Strange behaviour when adding activity to worker

Hi all, I have noticed something strange when registrating activity with a worker. If I have a class structure with the following structure:

  • CommonActivity interface with method getName
  • ActivityInterface1 extends CommonActivity. This interface is annotated with @ActivityInterface and has method doWork1() that is annotated with @ActivityMethod
  • ActivityInterface2 extends CommonActivity. This interface is annotated with @ActivityInterface and has method doWork2() that is annotated with @ActivityMethod

When I register those activities with a worker
yourWorker.registerActivitiesImplementations(new ActivityInterface1Imp(), new ActivityInterface2Impl() );

I get error

Exception in thread "main" io.temporal.worker.TypeAlreadyRegisteredException: "GetName" activity type is already registered with the worker
	at io.temporal.internal.activity.ActivityTaskHandlerImpl.registerActivityImplementation(ActivityTaskHandlerImpl.java:168)
	at io.temporal.internal.activity.ActivityTaskHandlerImpl.registerActivityImplementations(ActivityTaskHandlerImpl.java:107)
	at io.temporal.internal.worker.SyncActivityWorker.registerActivityImplementations(SyncActivityWorker.java:90)
	at io.temporal.worker.Worker.registerActivitiesImplementations(Worker.java:364)
	at

The reason for this is that in class ActivityTaskHandlerImpl when the activities are registered the code gets ALL of the activities methods, not just the ones annotated with @ActivityMethod and since for both activities I have a common interface with a method the CommonActivity method is tried to be added as an activity.

The code doing this is

   Class<?> cls = activity.getClass();
      POJOActivityImplMetadata activityImplMetadata = POJOActivityImplMetadata.newInstance(cls);
      for (POJOActivityMethodMetadata activityMetadata :
          activityImplMetadata.getActivityMethods()) {
        String typeName = activityMetadata.getActivityTypeName();
        if (activities.containsKey(typeName)) {
          throw new TypeAlreadyRegisteredException(
              typeName, "\"" + typeName + "\" activity type is already registered with the worker");
        }

Is there a reason why ALL of the activity methods are considered as if they are annotated with @ActivityMethod? Do you think this is a bug?

Is there a place where I can report this ti the temporal team for investigation?

Thanks you,
Svet

An activity interface is used to expose activities to remote clients. Do you want to expose getName to remote clients? If so how are you going to differentiate between “GetName” activities implemented by both interfaces?

Would you explain what you are trying to achieve from the business point of view?

Hi, we want to be able to dynamically build workflows and order execution of activities based on a config that is provided to us at runtime. In order to do that my intention is to have a DynamicWorkflow class that is annotated as @WorkflowInterface that will at runtime decide which activity it needs to call.
In order to achieve the runtime activity ordering I’m planing to have a common interface that all my activities inherit with a method execute, and in the activity implementation each of the activities will in term call their @ActivityMethod from that execute method. That way I will be able to work in my code only with the CommonActivity and I will not have to know what method each of the activity will have and how to call it, as that will be kept in the activity iteself. The outside code will interact only with the common method. Attaching some code examples for clarity

You can have a common interface, but don’t annotate it with @ActivityInterface. Only annotate the subinterfaces. To differentiate the activity type, use a different ActivityInterface.namePrefix value for each submiterface.

See samples-java/core/src/main/java/io/temporal/samples/hello/HelloPolymorphicActivity.java at main · temporalio/samples-java · GitHub