diff --git a/temporal-sdk/src/main/java/io/temporal/activity/ActivityOptions.java b/temporal-sdk/src/main/java/io/temporal/activity/ActivityOptions.java index 69032d1f7..f67a4beed 100644 --- a/temporal-sdk/src/main/java/io/temporal/activity/ActivityOptions.java +++ b/temporal-sdk/src/main/java/io/temporal/activity/ActivityOptions.java @@ -6,6 +6,7 @@ import io.temporal.common.context.ContextPropagator; import io.temporal.failure.CanceledFailure; import java.time.Duration; +import java.util.ArrayList; import java.util.List; /** Options used to configure how an activity is invoked. */ @@ -282,7 +283,9 @@ public Builder mergeActivityOptions(ActivityOptions override) { if (this.contextPropagators == null) { this.contextPropagators = override.contextPropagators; } else if (override.contextPropagators != null) { - this.contextPropagators.addAll(override.contextPropagators); + List merged = new ArrayList<>(this.contextPropagators); + merged.addAll(override.contextPropagators); + this.contextPropagators = merged; } if (override.versioningIntent != VersioningIntent.VERSIONING_INTENT_UNSPECIFIED) { this.versioningIntent = override.versioningIntent; diff --git a/temporal-sdk/src/test/java/io/temporal/activity/ActivityOptionsTest.java b/temporal-sdk/src/test/java/io/temporal/activity/ActivityOptionsTest.java index 26f8cc910..3a96c685f 100644 --- a/temporal-sdk/src/test/java/io/temporal/activity/ActivityOptionsTest.java +++ b/temporal-sdk/src/test/java/io/temporal/activity/ActivityOptionsTest.java @@ -9,6 +9,7 @@ import io.temporal.workflow.shared.TestActivities.TestActivityImpl; import java.lang.reflect.Method; import java.time.Duration; +import java.util.Collections; import java.util.Map; import org.junit.*; import org.junit.rules.Timeout; @@ -62,6 +63,31 @@ public void testActivityOptionsMerge() { Assert.assertEquals(methodOps1, merged); } + @Test + public void testActivityOptionsMergeWithImmutableContextPropagators() { + // Create options with immutable lists using Collections.emptyList() + // This tests the fix for https://github.com/temporalio/sdk-java/issues/2482 + ActivityOptions options1 = + ActivityOptions.newBuilder() + .setStartToCloseTimeout(Duration.ofSeconds(1)) + .setContextPropagators(Collections.emptyList()) + .build(); + + ActivityOptions options2 = + ActivityOptions.newBuilder() + .setStartToCloseTimeout(Duration.ofSeconds(2)) + .setContextPropagators(Collections.emptyList()) + .build(); + + // This should NOT throw UnsupportedOperationException + ActivityOptions merged = + ActivityOptions.newBuilder(options1).mergeActivityOptions(options2).build(); + + assertNotNull(merged); + assertNotNull(merged.getContextPropagators()); + assertEquals(Duration.ofSeconds(2), merged.getStartToCloseTimeout()); + } + @Test public void testActivityOptionsDefaultInstance() { testEnv.registerActivitiesImplementations(new TestActivityImpl());