Skip to content

Commit 2e24a37

Browse files
committed
Fix UnsupportedOperationException when merging ActivityOptions with immutable context propagators
The mergeActivityOptions method was calling addAll() directly on the existing contextPropagators list, which fails when the list is immutable (e.g., created with List.of() or Collections.emptyList()). This fix creates a new ArrayList that combines both lists instead of modifying the existing one. Fixes #2482
1 parent a39d10c commit 2e24a37

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

temporal-sdk/src/main/java/io/temporal/activity/ActivityOptions.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.temporal.common.context.ContextPropagator;
77
import io.temporal.failure.CanceledFailure;
88
import java.time.Duration;
9+
import java.util.ArrayList;
910
import java.util.List;
1011

1112
/** Options used to configure how an activity is invoked. */
@@ -282,7 +283,9 @@ public Builder mergeActivityOptions(ActivityOptions override) {
282283
if (this.contextPropagators == null) {
283284
this.contextPropagators = override.contextPropagators;
284285
} else if (override.contextPropagators != null) {
285-
this.contextPropagators.addAll(override.contextPropagators);
286+
List<ContextPropagator> merged = new ArrayList<>(this.contextPropagators);
287+
merged.addAll(override.contextPropagators);
288+
this.contextPropagators = merged;
286289
}
287290
if (override.versioningIntent != VersioningIntent.VERSIONING_INTENT_UNSPECIFIED) {
288291
this.versioningIntent = override.versioningIntent;

temporal-sdk/src/test/java/io/temporal/activity/ActivityOptionsTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.temporal.workflow.shared.TestActivities.TestActivityImpl;
1010
import java.lang.reflect.Method;
1111
import java.time.Duration;
12+
import java.util.Collections;
1213
import java.util.Map;
1314
import org.junit.*;
1415
import org.junit.rules.Timeout;
@@ -62,6 +63,31 @@ public void testActivityOptionsMerge() {
6263
Assert.assertEquals(methodOps1, merged);
6364
}
6465

66+
@Test
67+
public void testActivityOptionsMergeWithImmutableContextPropagators() {
68+
// Create options with immutable lists using Collections.emptyList()
69+
// This tests the fix for https://github.com/temporalio/sdk-java/issues/2482
70+
ActivityOptions options1 =
71+
ActivityOptions.newBuilder()
72+
.setStartToCloseTimeout(Duration.ofSeconds(1))
73+
.setContextPropagators(Collections.emptyList())
74+
.build();
75+
76+
ActivityOptions options2 =
77+
ActivityOptions.newBuilder()
78+
.setStartToCloseTimeout(Duration.ofSeconds(2))
79+
.setContextPropagators(Collections.emptyList())
80+
.build();
81+
82+
// This should NOT throw UnsupportedOperationException
83+
ActivityOptions merged =
84+
ActivityOptions.newBuilder(options1).mergeActivityOptions(options2).build();
85+
86+
assertNotNull(merged);
87+
assertNotNull(merged.getContextPropagators());
88+
assertEquals(Duration.ofSeconds(2), merged.getStartToCloseTimeout());
89+
}
90+
6591
@Test
6692
public void testActivityOptionsDefaultInstance() {
6793
testEnv.registerActivitiesImplementations(new TestActivityImpl());

0 commit comments

Comments
 (0)