temporalio / spring-boot-demo

Sample application demonstrating Temporal JavaSDK Spring Boot integration
https://github.com/temporalio/sdk-java/blob/master/temporal-spring-boot-autoconfigure-alpha/README.md
26 stars 12 forks source link

[Bug] Calling Temporal's ActivityStub from Spring-Boot Service throwing error. #26

Open mainaksethi opened 4 months ago

mainaksethi commented 4 months ago

What are you really trying to do?

  1. We have multiple activities written in Python code.
  2. We are writing workflows in Java leveraging those activities through Spring Boot.
  3. I created an abstraction PythonClient in Java exposing all Python activities to Java Workflows.
  4. On spawning the spring boot services it is throwing ActivityStub cannot be spawned from a non-workflow class.

Describe the bug

Minimal Reproduction

` @WorkflowInterface public interface CallPythonActivityWorkflow {

@WorkflowMethod
public GreetingActvityResponse greetInSpanish(GreetingActvityRequest greetingActvityRequest);

}

@WorkflowImpl(taskQueues = "python-greeting-tasks") public class CallPythonActivityWorkflowImpl implements CallPythonActivityWorkflow {

@Autowired
private static final Logger logger = LoggerFactory.getLogger(CallPythonActivityWorkflowImpl.class);

// This is not getting instantiated private final PythonClient pythonClient;

@Autowired
public CallPythonActivityWorkflowImpl(PythonClient pythonClient) {
    this.pythonClient = pythonClient;
}

@Override
public GreetingActvityResponse greetInSpanish(GreetingActvityRequest greetingActvityRequest) {
    return pythonClient.greetInSpanish(greetingActvityRequest);
}

}

@Service public class PythonClient {

private final ActivityOptions spanishGreetingActivityOptions
        = ActivityOptions.newBuilder()
        .setStartToCloseTimeout(Duration.ofSeconds(10))
        // todo move to an enum in proto
        .setTaskQueue("python-greeting-tasks")
        .build();

private final ActivityStub spanishGreetingActivityStub;

public PythonClient() {
    this.spanishGreetingActivityStub =  Workflow.newUntypedActivityStub(spanishGreetingActivityOptions);
}

public GreetingActvityResponse greetInSpanish(GreetingActvityRequest greetingActvityRequest) {
    return spanishGreetingActivityStub.execute("JavaSpanishGreetingActivity", GreetingActvityResponse.class, greetingActvityRequest);
}

}

``

logs: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pythonClient' defined in file [/PythonClient.class]: Failed to instantiate [com.job_framework.client.PythonClient]: Constructor threw exception at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1317) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1202) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.5.jar:6.1.5] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) [spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) [spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) [spring-boot-3.2.4.jar:3.2.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) [spring-boot-3.2.4.jar:3.2.4] at com..job_framework.JobFrameworkApplication.main(JobFrameworkApplication.java:10) [classes/:?] Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com..job_framework.client.PythonClient]: Constructor threw exception at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:221) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:88) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1311) ~[spring-beans-6.1.5.jar:6.1.5] ... 17 more Caused by: java.lang.Error: Called from non workflow or workflow callback thread at io.temporal.internal.sync.DeterministicRunnerImpl.currentThreadInternal(DeterministicRunnerImpl.java:130) ~[temporal-sdk-1.23.2.jar:?] at io.temporal.internal.sync.WorkflowInternal.getRootWorkflowContext(WorkflowInternal.java:738) ~[temporal-sdk-1.23.2.jar:?] at io.temporal.internal.sync.WorkflowInternal.getWorkflowOutboundInterceptor(WorkflowInternal.java:734) ~[temporal-sdk-1.23.2.jar:?] at io.temporal.internal.sync.WorkflowInternal.newUntypedActivityStub(WorkflowInternal.java:378) ~[temporal-sdk-1.23.2.jar:?] at io.temporal.workflow.Workflow.newUntypedActivityStub(Workflow.java:118) ~[temporal-sdk-1.23.2.jar:?] at com.job_framework.client.PythonClient.(PythonClient.java:25) ~[classes/:?] at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) ~[?:?] at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502) ~[?:?] at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) ~[?:?] at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:195) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:88) ~[spring-beans-6.1.5.jar:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1311) ~[spring-beans-6.1.5.jar:6.1.5]

0001-Added-reproduction-scenarios.patch

Environment/Versions

Additional context

mainaksethi commented 3 months ago

@tsurdilo @Spikhalskiy @antmendoza