Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/cloud/get-started/api-keys.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ To use your API key with a Temporal SDK, see the instructions in each SDK sectio

[How to connect to Temporal Cloud using an API Key with the Go SDK](/develop/go/temporal-client#connect-to-temporal-cloud)

[How to connect to Temporal Cloud using an API Key with the Java SDK](/develop/java/temporal-client#connect-to-temporal-cloud)
[How to connect to Temporal Cloud using an API Key with the Java SDK](/develop/java/client/temporal-client#connect-to-temporal-cloud)

[How to connect to Temporal Cloud using an API Key with the Python SDK](/develop/python/temporal-client#connect-to-temporal-cloud)

Expand Down
2 changes: 1 addition & 1 deletion docs/cloud/get-started/certificates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ To view the current certificate filters, use the
## Configure clients to use client certificates {#configure-clients-to-use-client-certificates}

- [Go SDK](/develop/go/temporal-client#connect-to-temporal-cloud)
- [Java SDK](/develop/java/temporal-client#connect-to-temporal-cloud)
- [Java SDK](/develop/java/client/temporal-client#connect-to-temporal-cloud)
- [PHP SDK](/develop/php/temporal-client#connect-to-a-dev-cluster)
- [Python SDK](/develop/python/temporal-client#connect-to-temporal-cloud)
- [TypeScript SDK](/develop/typescript/temporal-client#connect-to-temporal-cloud)
Expand Down
4 changes: 2 additions & 2 deletions docs/cloud/get-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ cert management, then [mTLS](/cloud/certificates) is an excellent choice.
See our guides for connecting each SDK to your Temporal Cloud Namespace:

- [Connect to Temporal Cloud in Go](/develop/go/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in Java](/develop/java/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in Java](/develop/java/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in Python](/develop/python/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in TypeScript](/develop/typescript/core-application#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in .NET](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
Expand All @@ -65,7 +65,7 @@ See our guides for connecting each SDK to your Temporal Cloud Namespace:
See our guides for starting a workflow using each SDK:

- [Start a workflow in Go](/develop/go/temporal-client#start-workflow-execution)
- [Start a workflow in Java](/develop/java/temporal-client#start-workflow-execution)
- [Start a workflow in Java](/develop/java/client/temporal-client#start-workflow-execution)
- [Start a workflow in Python](/develop/python/temporal-client#start-workflow-execution)
- [Start a workflow in TypeScript](/develop/typescript/core-application#start-workflow-execution)
- [Start a workflow in .NET](/develop/dotnet/temporal-client#start-workflow)
Expand Down
4 changes: 2 additions & 2 deletions docs/cloud/metrics/prometheus-grafana.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ If you're following through with the examples provided here, ensure that you hav
- Set up your connections to Temporal Cloud using an SDK of your choice and have some Workflows running on Temporal Cloud. See Connect to a Temporal Service for details.

- [Go](/develop/go/temporal-client#connect-to-temporal-cloud)
- [Java](/develop/java/temporal-client#connect-to-temporal-cloud)
- [Java](/develop/java/client/temporal-client#connect-to-temporal-cloud)
- [PHP](/develop/php/temporal-client#connect-to-a-dev-cluster)
- [Python](/develop/python/temporal-client#connect-to-temporal-cloud)
- [TypeScript](/develop/typescript/core-application#connect-to-temporal-cloud)
Expand Down Expand Up @@ -93,7 +93,7 @@ You must configure a Prometheus scrape endpoint for Prometheus to collect and ag
Each language development guide has details on how to set this up.

- [Go SDK](/develop/go/observability#metrics)
- [Java SDK](/develop/java/observability#metrics)
- [Java SDK](/develop/java/workers/observability#metrics)
- [TypeScript SDK](/develop/typescript/observability#metrics)
- [Python](/develop/python/observability#metrics)
- [.NET](/develop/dotnet/observability#metrics)
Expand Down
205 changes: 205 additions & 0 deletions docs/develop/java/activities/basic-activity.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
id: basic-activity
title: Basic Activity - Java SDK
sidebar_label: Basic Activity
description: This section explains how to implement Activities with the Java SDK
toc_max_heading_level: 4
keywords:
- Java SDK
tags:
- Java SDK
- Temporal SDKs
---

## Develop a basic Activity

One of the primary things that Workflows do is orchestrate the execution of Activities.
An Activity is a normal function or method execution that's intended to execute a single, well-defined action (either short or long-running), such as querying a database, calling a third-party API, or transcoding a media file.
An Activity can interact with world outside the Temporal Platform or use a Temporal Client to interact with a Temporal Service.
For the Workflow to be able to execute the Activity, we must define the [Activity Definition](/activity-definition).

An [Activity Definition](/activities) is a combination of the Temporal Java SDK [Activity](https://www.javadoc.io/static/io.temporal/temporal-sdk/0.19.0/io/temporal/activity/Activity.html) 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.

```java
@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.

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

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

```java
// 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 + "!";
}
}
```

## Define Activity parameters {#activity-parameters}

There is no explicit limit to the total number of parameters that an [Activity Definition](/activity-definition) may support.
However, there is a limit to the total size of the data that ends up encoded into a gRPC message Payload.

A single argument is limited to a maximum size of 2 MB.
And the total size of a gRPC message, which includes all the arguments, is limited to a maximum of 4 MB.

Also, keep in mind that all Payload data is recorded in the [Workflow Execution Event History](/workflow-execution/event#event-history) and large Event Histories can affect Worker performance.
This is because the entire Event History could be transferred to a Worker Process with a [Workflow Task](/tasks#workflow-task).

{/* TODO link to gRPC limit section when available */}

Some SDKs require that you pass context objects, others do not.
When it comes to your application data—that is, data that is serialized and encoded into a Payload—we recommend that you use a single object as an argument that wraps the application data passed to Activities.
This is so that you can change what data is passed to the Activity without breaking a function or method signature.

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.

```java
@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.

```java
// 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](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/activity/DynamicActivity.html).

## Define Activity return values {#activity-return-values}

All data returned from an Activity must be serializable.

Activity return values are subject to payload size limits in Temporal. The default payload size limit is 2MB, and there is a hard limit of 4MB for any gRPC message size in the Event History transaction ([see Cloud limits here](https://docs.temporal.io/cloud/limits#per-message-grpc-limit)). Keep in mind that all return values are recorded in a [Workflow Execution Event History](/workflow-execution/event#event-history).

Activity return values must be serializable and deserializable by the provided [`DataConverter`](https://www.javadoc.io/static/io.temporal/temporal-sdk/1.17.0/io/temporal/common/converter/DataConverter.html).

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.

- [Data Converter](/dataconversion)
- Java DataConverter reference: [https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/common/converter/DataConverter.html](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/common/converter/DataConverter.html)

## Customize your Activity Type {#activity-type}

Each Activity has a Type, which may also be referred to as the Activity 'name'.
This name appears in the Workflow Execution Event History in the Summary tab for each Activity Task.
The name lets you identify Activity Types called during the Execution.

Custom Activity Type names prevent name collisions across interfaces and Workflows.
They offer descriptive Activity method names without concerns about re-using those names elsewhere in your project.
They also support code management, especially in larger projects with many Activities.
For example, you might use a prefix to group related activities together.
Custom names also distinguish keys for gathering metrics without name conflicts.

The following examples show how to set custom names for your Activity Type.

### Default behavior

By default, an Activity Type is the method name with the first letter capitalized:

```java
@ActivityInterface
public interface GreetingActivities {
String sendMessage(String input);

@ActivityMethod
String composeGreeting(String greeting, String language);
}
```

- Method Name: `sendMessage`
- Activity Type: `SendMessage`
- Method Name: `composeGreeting`
- Activity Type: `ComposeGreeting`

### Custom Prefix

Using the `namePrefix` parameter in the `@ActivityInterface` annotation adds a prefix to each Activity Type name mentioned in the interface, unless the prefix is specifically overridden:

```java
@ActivityInterface(namePrefix = "Messaging_")
public interface GreetingActivities {
String sendMessage(String input);

@ActivityMethod
String composeGreeting(String greeting, String language);
}
```

- Method Name: `sendMessage`
- Activity Type: `Messaging_SendMessage`
- Method Name: `composeGreeting`
- Activity Type: `Messaging_ComposeGreeting`

The Activity Type is capitalized, even when using a prefix.

### Custom Name

To override the default name and any inherited prefixes, use the `name` parameter in the `@ActivityMethod` annotation:

```java
@ActivityInterface(namePrefix = "Messaging_")
public interface GreetingActivities {
String sendMessage(String input);

@ActivityMethod
String composeGreeting(String greeting, String language);
@ActivityMethod(name = "farewell")
String composeFarewell(String farewell, String language);
}
```

Using the `name` parameter won't automatically capitalize the result:

- Method Name: `sendMessage`
- Activity Type: `Messaging_SendMessage`
- Method Name: `composeGreeting`
- Activity Type: `Messaging_ComposeGreeting`
- Method Name: `composeFarewell`
- Activity Type: `farewell`

Be cautious with names that contain special characters, as these can be used as metric tags.
Systems such as Prometheus may ignore metrics with tags using unsupported characters.
Loading