spring-boot-demo icon indicating copy to clipboard operation
spring-boot-demo copied to clipboard

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

Open mainaksethi opened this issue 1 year ago • 1 comments

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]

  • Reproduction: Added patch to reproduce on below example repo. Repo: https://github.com/temporalio/spring-boot-demo/tree/main

0001-Added-reproduction-scenarios.patch

Environment/Versions

  • OS and processor: [e.g. M1 Mac, x86 Windows, Linux]
  • Temporal Version: [e.g. 1.14.0?] and/or SDK version
  • Are you using Docker or Kubernetes or building Temporal from source?

Additional context

mainaksethi avatar Aug 04 '24 15:08 mainaksethi

@tsurdilo @Spikhalskiy @antmendoza

mainaksethi avatar Aug 08 '24 15:08 mainaksethi