I have a use case where I am looping through a list of ActivityInterface instances and asynchronously calling a common method they inherit from a parent interface but that can accept multiple types of input.
I notice that when I use the Async.function method and pass in an Object class object I get a compile time error as shown.
Why is the passing of generic Object type not allowed in the Async.function? In my use case I could cast this to the appropriate type inside each activity method for the different activity interfaces.
The example I was working with actually has multiple interfaces extending from a base interface but each of them were using their own class type instead of Object across all of their activity methods.
I now changed all of them to use Object and the IDE doesn’t show errors.
The issue was me using Object in some places and actual custom classes in other cases.
This only works for Strings and some other simple types that correspond to Json types. As soon as you use a class as an activity argument it is going to break.
For example this doesn’t work:
public class GreetingsArgs {
private final String greeting;
private final String name;
public GreetingsArgs(String greeting, String name) {
this.greeting = greeting;
this.name = name;
}
public GreetingsArgs() {
greeting = null;
name = null;
}
public String getGreeting() {
return greeting;
}
public String getName() {
return name;
}
}
@ActivityInterface
public interface GreetingActivities {
String composeGreeting(Object args);
}
public class GreetingActivitiesImpl implements GreetingActivities {
@Override
public String composeGreeting(Object argsO) {
GreetingsArgs args = (GreetingsArgs) argsO;
return args.getGreeting() + " " + args.getName() + "!";
}
}
public class GreetingWorkflowImpl implements GreetingWorkflow {
private final GreetingActivities activities =
Workflow.newActivityStub(
GreetingActivities.class,
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(2)).build());
@Override
public String getGreeting(String name) {
return activities.composeGreeting(new GreetingsArgs("Hello", name));
}
}
Here is the failure:
11:44:21.698 [Activity Executor taskQueue="HelloActivityTaskQueue", namespace="default": 1] WARN i.t.i.sync.POJOActivityTaskHandler - Activity failure. ActivityId=796d71ed-fb6b-33e0-94c2-46529b4ce0d0, activityType=greet, attempt=2
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to io.temporal.samples.hello.HelloActivity$GreetingsArgs
at io.temporal.samples.hello.HelloActivity$GreetingActivitiesImpl.composeGreeting(HelloActivity.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at io.temporal.internal.sync.POJOActivityTaskHandler$POJOActivityInboundCallsInterceptor.execute(POJOActivityTaskHandler.java:297)
at io.temporal.internal.sync.POJOActivityTaskHandler$POJOActivityImplementation.execute(POJOActivityTaskHandler.java:254)
at io.temporal.internal.sync.POJOActivityTaskHandler.handle(POJOActivityTaskHandler.java:212)
at io.temporal.internal.worker.ActivityWorker$TaskHandlerImpl.handle(ActivityWorker.java:192)
at io.temporal.internal.worker.ActivityWorker$TaskHandlerImpl.handle(ActivityWorker.java:151)
at io.temporal.internal.worker.PollTaskExecutor.lambda$process$0(PollTaskExecutor.java:73)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
@maxim I would like to know if there is any possible way to make this work?
My use case requires this flexibility to get a certain Class object from one Activity stub’s activity method and pass it to another using a generic piece of orchestration code inside the Workflow.
You mentioned that modifying the DataConverter is an option but of course that’s a framework/library file.