Files
temporalio__skill-temporal-…/references/java/standalone-activities.md
skill-temporal-developer-updater[bot] 5f32b62499 Implement planned topic: 0001-standalone-activities (#224)
* Add Python standalone activities reference

* Add TypeScript standalone activities reference

* Add .NET standalone activities reference

* Add Java standalone activities reference

* Finalize draft for 0001-standalone-activities

* remove incomplete sections

* Add core page which abstracts out all shared stuff

* Standardize connection logic

* Unify worker setup section across SDK standalone-activity refs

Rename the worker section to "Worker setup & activity registration" in
all four SDK files and lead with a single sentence noting the Activity
is defined and registered exactly as normal. Drop the .NET "Define the
Activity" section so no file repeats how to define an activity, matching
the Python structure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* re-organize to a LOGICAL structure, not just a flat list of H2 headings.

* finish cleaning up parts other than calling activities

* Get client connection in order

* cleanup of operations content

* Add links

---------

Co-authored-by: skill-sync[bot] <skill-sync[bot]@users.noreply.github.com>
Co-authored-by: Donald Pinckney <donald.pinckney@temporal.io>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 15:29:04 -04:00

5.3 KiB

Note

This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.

Overview

Standalone Activities are Activities run independently of any Workflow, started directly from a Temporal Client — useful when you need a single durable, retryable task (job-queue style) and not multi-step orchestration. The same Activity method can be executed both as a Standalone Activity and as a Workflow Activity with no code changes.

Standalone Activities are conceptually the same across all SDKs. Read the cross-SDK concept file if you have not already, and then see below for the Java SDK specific APIs for calling Standalone Activities.

Prerequisites

  • Temporal Java SDK v1.35.0 or higher.
  • Temporal CLI v1.7.0 or higher — see Temporal CLI install instructions if needed. Dev server includes Standalone Activities support.
  • For production, Temporal Server v1.31.0 or higher (or Temporal Cloud).

Hosting Activities on a Worker

The Activity is defined just as activities normally are in Temporal. Worker registration is also the same.

ClientConfigProfile profile = ClientConfigProfile.load();
WorkflowServiceStubs service =
    WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions());

WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions());
WorkerFactory factory = WorkerFactory.newInstance(client);
Worker worker = factory.newWorker(TASK_QUEUE);
worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); // register whatever your activity(ies) is/are
factory.start();

Calling and managing Standalone Activities

Start and manage Standalone Activities from your application code using the Temporal Client.

Do not call from inside a Workflow

Don't call ActivityClient.execute / ActivityClient.start or any other Standalone Activity APIs from inside a Workflow Definition — use Workflow-side activity invocation (Workflow.newActivityStub(...)) instead.

Connect a Client

The Standalone Activity operations are methods on a connected ActivityClient. The examples below assume this client.

ActivityClient client =
    ActivityClient.newInstance(
        service,
        ActivityClientOptions.newBuilder().setNamespace(profile.getNamespace()).build());

Execute (wait for result)

Use client.execute(...) to durably enqueue the Activity, wait for it to run on a Worker, and return the result. StartActivityOptions must set id, taskQueue, and at least one of startToCloseTimeout or scheduleToCloseTimeout.

With type checking

Use when activity definitions are available in this language. The typed form takes the Activity interface class and an unbound method reference; the SDK infers the Activity type name and result type at runtime.

// In practice, use a meaningful business identifier, like customer or transaction identifier
String activityId = UUID.randomUUID().toString();

StartActivityOptions options =
    StartActivityOptions.newBuilder()
        .setId(activityId)
        .setTaskQueue(TASK_QUEUE)
        .setStartToCloseTimeout(Duration.ofSeconds(10))
        .build();

String result =
    client.execute(
        GreetingActivities.class,
        GreetingActivities::composeGreeting,
        options,
        "Hello",
        "World");

Without type checking

Use when activity definitions are unavailable in this language (i.e. you can't import them). Call the Activity by its string type name and pass the result class.

String result = client.execute("ComposeGreeting", String.class, options, "Hello", "World");

Start (do not wait for result)

Use client.start(...) to durably enqueue the Activity and get back an ActivityHandle without waiting for completion. This takes the exact same arguments as execute.

ActivityHandle<String> handle = client.start(...);

Get a handle to an existing Activity execution

Use client.getHandle(...) to attach a typed handle to a previously started Standalone Activity. Passing null as the run ID targets the latest run of that Activity ID.

ActivityHandle<String> handle = client.getHandle("standalone-activity-id", null, String.class);

Wait for the result of a handle

String result = handle.getResult();
// or, for a non-blocking wait...
CompletableFuture<String> future = handle.getResultAsync();

Calling execute is equivalent to start followed by getResult().

List Standalone Activities

client
    .listExecutions("TaskQueue = '" + TASK_QUEUE + "'") // returns a Stream<ActivityExecutionMetadata>
    .forEach(
        info ->
            System.out.printf(
                "ActivityID: %s, Type: %s, Status: %s%n",
                info.getActivityId(), info.getActivityType(), info.getStatus()));

Only Standalone Activity Executions are returned; Activities running inside Workflows are not included.

Count Standalone Activities

Use client.countExecutions(query) to count matching executions; this takes the exact same arguments as listExecutions.

ActivityExecutionCount resp = client.countExecutions("TaskQueue = '" + TASK_QUEUE + "'");
System.out.println("Total activities: " + resp.getCount());