diff --git a/temporal-sdk/src/main/java/io/temporal/common/metadata/POJOWorkflowImplMetadata.java b/temporal-sdk/src/main/java/io/temporal/common/metadata/POJOWorkflowImplMetadata.java index ee302b6af..1ad2ee6ff 100644 --- a/temporal-sdk/src/main/java/io/temporal/common/metadata/POJOWorkflowImplMetadata.java +++ b/temporal-sdk/src/main/java/io/temporal/common/metadata/POJOWorkflowImplMetadata.java @@ -77,10 +77,18 @@ public int hashCode() { /** * Create POJOWorkflowImplMetadata for a workflow implementation class. The object must implement - * at least one workflow method. + * at least one workflow method. Validates the implementation can be registered. */ public static POJOWorkflowImplMetadata newInstance(Class implClass) { - return new POJOWorkflowImplMetadata(implClass, false); + return new POJOWorkflowImplMetadata(implClass, false, true); + } + + /** + * Create POJOWorkflowImplMetadata for a workflow implementation class. The object must implement + * at least one workflow method. Does not validate the implementation can be registered. + */ + public static POJOWorkflowImplMetadata newInstanceForWorkflowFactory(Class implClass) { + return new POJOWorkflowImplMetadata(implClass, false, false); } /** @@ -89,10 +97,11 @@ public static POJOWorkflowImplMetadata newInstance(Class implClass) { * signal methods. */ public static POJOWorkflowImplMetadata newListenerInstance(Class implClass) { - return new POJOWorkflowImplMetadata(implClass, true); + return new POJOWorkflowImplMetadata(implClass, true, false); } - private POJOWorkflowImplMetadata(Class implClass, boolean listener) { + private POJOWorkflowImplMetadata( + Class implClass, boolean listener, boolean validateConstructor) { if (implClass.isInterface() || implClass.isPrimitive() || implClass.isAnnotation() @@ -166,7 +175,7 @@ private POJOWorkflowImplMetadata(Class implClass, boolean listener) { this.queryMethods = ImmutableList.copyOf(queryMethods.values()); this.updateMethods = ImmutableList.copyOf(updateMethods.values()); this.updateValidatorMethods = ImmutableList.copyOf(updateValidatorMethods.values()); - if (!listener) { + if (!listener && validateConstructor) { this.workflowInit = ReflectionUtils.getConstructor( implClass, diff --git a/temporal-sdk/src/test/java/io/temporal/common/metadata/POJOWorkflowImplMetadataTest.java b/temporal-sdk/src/test/java/io/temporal/common/metadata/POJOWorkflowImplMetadataTest.java index 7df236e6b..5efd4bc61 100644 --- a/temporal-sdk/src/test/java/io/temporal/common/metadata/POJOWorkflowImplMetadataTest.java +++ b/temporal-sdk/src/test/java/io/temporal/common/metadata/POJOWorkflowImplMetadataTest.java @@ -229,6 +229,23 @@ public void testWorkflowWithConstructor() { Assert.assertNull(meta.getWorkflowInit()); } + @Test + public void testWorkflowWithConstructorArgsNoInit() { + try { + POJOWorkflowImplMetadata.newInstance(WorkflowWithConstructorParameters.class); + Assert.fail(); + } catch (IllegalArgumentException e) { + assertTrue( + e.getMessage() + .contains( + "No default constructor or constructor annotated with @WorkflowInit found:")); + } + POJOWorkflowImplMetadata meta = + POJOWorkflowImplMetadata.newInstanceForWorkflowFactory( + WorkflowWithConstructorParameters.class); + Assert.assertEquals(1, meta.getWorkflowMethods().size()); + } + public static class GImpl implements POJOWorkflowInterfaceMetadataTest.G { @Override public void g() {} @@ -377,4 +394,13 @@ public WorkflowWithConstructor() {} @Override public void i() {} } + + public static class WorkflowWithConstructorParameters + implements POJOWorkflowInterfaceMetadataTest.I { + + public WorkflowWithConstructorParameters(Integer i) {} + + @Override + public void i() {} + } } diff --git a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkersTemplate.java b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkersTemplate.java index 210506bb8..e21d42ab6 100644 --- a/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkersTemplate.java +++ b/temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/WorkersTemplate.java @@ -504,7 +504,8 @@ private void configureWorkflowImplementationAutoDiscovery( @SuppressWarnings("unchecked") private void configureWorkflowImplementation(Worker worker, Class clazz) { - POJOWorkflowImplMetadata workflowMetadata = POJOWorkflowImplMetadata.newInstance(clazz); + POJOWorkflowImplMetadata workflowMetadata = + POJOWorkflowImplMetadata.newInstanceForWorkflowFactory(clazz); List workflowMethods = workflowMetadata.getWorkflowMethods(); if (workflowMethods.isEmpty()) { throw new BeanDefinitionValidationException( diff --git a/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestWorkflowImpl.java b/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestWorkflowImpl.java index eae95af3f..7e1aa3581 100644 --- a/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestWorkflowImpl.java +++ b/temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestWorkflowImpl.java @@ -26,9 +26,15 @@ import io.temporal.workflow.NexusServiceOptions; import io.temporal.workflow.Workflow; import java.time.Duration; +import org.springframework.context.ConfigurableApplicationContext; @WorkflowImpl(workers = "mainWorker") public class TestWorkflowImpl implements TestWorkflow { + + // Test auto-wiring of the application context works, this is not indicative of a real-world use + // case as the workflow implementation should be stateless. + public TestWorkflowImpl(ConfigurableApplicationContext applicationContext) {} + @Override public String execute(String input) { if (input.equals("nexus")) {