Skip to main content

How to develop an Activity in Java

An Activity Definition is a combination of the Temporal Java SDK Activity Class implementing a specially annotated interface.

An Activity interface is annotated with @ActivityInterface and an Activity implementation implements this Activity interface. To handle Activity types that do not have an explicitly registered handler, you can directly implement a dynamic Activity.

@ActivityInterface
public interface GreetingActivities {
String composeGreeting(String greeting, String language);
}

Each method defined in the Activity interface defines a separate Activity method. You can annotate each method in the Activity interface with the @ActivityMethod annotation, but this is completely optional. The following example uses the @ActivityMethod annotation for the method defined in the previous example.

@ActivityInterface
public interface GreetingActivities {
@ActivityMethod
String composeGreeting(String greeting, String language);
}

An Activity implementation is a Java class that implements an Activity annotated interface.

// Implementation for the GreetingActivities interface example from in the previous section
static class GreetingActivitiesImpl implements GreetingActivities {
@Override
public String composeGreeting(String greeting, String name) {
return greeting + " " + name + "!";
}
}

Use DynamicActivity to implement any number of Activity types dynamically. When an Activity implementation that extends DynamicActivity is registered, it is called for any Activity type invocation that doesn't have an explicitly registered handler.

The dynamic Activity interface is implemented with the execute method, as shown in the following example.

 // Dynamic Activity implementation
public static class DynamicGreetingActivityImpl implements DynamicActivity {
@Override
public Object execute(EncodedValues args) {
String activityType = Activity.getExecutionContext().getInfo().getActivityType();
return activityType
+ ": "
+ args.get(0, String.class)
+ " "
+ args.get(1, String.class)
+ " from: "
+ args.get(2, String.class);
}
}

Use Activity.getExecutionContext() to get information about the Activity type that should be implemented dynamically.

Customize Activity Type

The Activity Type defaults to method name, with the first letter of the method name capitalized, and can be customized using namePrefix() or {ActivityMethod.name()} to ensure they are distinct.

In the following example, the Activity Type defaults to ComposeGreeting.

@ActivityInterface
public interface GreetingActivities {
@ActivityMethod
String composeGreeting(String greeting, String language);
}

To overwrite this default naming and assign a custom Activity Type, use the @ActivityMethod annotation with the name parameter. In the following example, the Activity Type is set to "greet".

@ActivityInterface
public interface GreetingActivities {
@ActivityMethod(name = "greet")
String composeGreeting(String greeting, String language);
}

You can also define a prefix for all of your Activity Types using the namePrefix parameter with the @ActivityInterface annotation. The following example shows a namePrefix parameter applied to the @ActivityInterface, and two Activity methods, of which one is defined using the @ActivityMethod annotation.

@ActivityInterface(namePrefix = "A_")
Public interface GreetingActivities {
String sendGreeting(String input);

@ActivityMethod(name = "abc")
String composeGreeting(String greeting, String language);
}

In this example, the Activity type for the first method is set to A_SendGreeting. The Activity type for the method annotated with @ActivityMethod is set to A_abc.

Parameters

An Activity interface can have any number of parameters. All inputs should be serializable by the default Jackson JSON Payload Converter.

When implementing Activities, be mindful of the amount of data that you transfer using the Activity invocation parameters or return values as these are recorded in the Workflow Execution Events History. Large Events Histories can adversely impact performance.

You can create a custom object, and pass it to the Activity interface, as shown in the following example.

@ActivityInterface
public interface YourActivities {
String getCustomObject(CustomObj customobj);
void sendCustomObject(CustomObj customobj, String abc);
}

The execute method in the dynamic Activity interface implementation takes in EncodedValues that are inputs to the Activity Execution, as shown in the following example.

 // Dynamic Activity implementation
public static class DynamicActivityImpl implements DynamicActivity {
@Override
public Object execute(EncodedValues args) {
String activityType = Activity.getExecutionContext().getInfo().getActivityType();
return activityType
+ ": "
+ args.get(0, String.class)
+ " "
+ args.get(1, String.class)
+ " from: "
+ args.get(2, String.class);
}
}

For more details, see Dynamic Activity Reference.

Return values

Activity return values must be serializable and deserializable by the provided DataConverter.

The execute method for DynamicActivity can return type Object. Ensure that your Workflow or Client can handle an Object type return or is able to convert the Object type response.