Skip to main content

How to spawn a Workflow Execution in Java

Use WorkflowStub to start a Workflow Execution from within a Client, and ExternalWorkflowStub to start a different Workflow Execution from within a Workflow.

See SignalwithStart to start a Workflow Execution to receive a Signal from within another Workflow.

Using WorkflowStub

WorkflowStub is a proxy generated by the WorkflowClient. Each time a new Workflow Execution is started, an instance of the Workflow implementation object is created. Then, one of the methods (depending on the Workflow Type of the instance) annotated with @WorkflowMethod can be invoked. As soon as this method returns, the Workflow Execution is considered to be complete.

You can use a typed or untyped WorkflowStub in the client code.

  • Typed WorkflowStub are useful because they are type safe and allow you to invoke your Workflow methods such as @WorkflowMethod, @QueryMethod, and @SignalMethod directly.
  • An untyped WorkflowStub does not use the Workflow interface, and is not type safe. It is more flexible because it has methods from the WorkflowStub interface, such as start, signalWithStart, getResults (sync and async), query, signal, cancel and terminate. Note that the Temporal Java SDK also provides typed WorkflowStub versions for these methods. When using untyped WorkflowStub, we rely on the Workflow Type, Activity Type, Child Workflow Type, as well as Query and Signal names. For details, see Temporal Client.

A Workflow Execution can be started either synchronously or asynchronously.

  • Synchronous invocation starts a Workflow and then waits for its completion. If the process that started the Workflow crashes or stops waiting, the Workflow continues executing. Because Workflows are potentially long-running, and Client crashes happen, it is not very commonly found in production use. The following example is a type-safe approach for starting a Workflow Execution synchronously.

      NotifyUserAccounts workflow = client.newWorkflowStub(
    NotifyUserAccounts.class,
    WorkflowOptions.newBuilder()
    .setWorkflowId("notifyAccounts")
    .setTaskQueue(taskQueue)
    .build()
    );

    // start the Workflow and wait for a result.
    workflow.notify(new String[] { "Account1", "Account2", "Account3", "Account4", "Account5",
    "Account6", "Account7", "Account8", "Account9", "Account10"});
    }
    // notify(String[] accountIds) is a Workflow method defined in the Workflow Definition.
  • Asynchronous start initiates a Workflow Execution and immediately returns to the caller. This is the most common way to start Workflows in production code. The WorkflowClienthttps://github.com/temporalio/sdk-java/blob/master/temporal-sdk/src/main/java/io/temporal/client/WorkflowClient.java) provides some static methods, such as start, execute, signalWithStart etc., that help with starting your Workflows asynchronously.

    The following examples show how to start Workflow Executions asynchronously, with either typed or untyped WorkflowStub.

    • Typed WorkflowStub Example

      // create typed Workflow stub
      FileProcessingWorkflow workflow = client.newWorkflowStub(FileProcessingWorkflow.class,
      WorkflowOptions.newBuilder()
      .setTaskQueue(taskQueue)
      .setWorkflowId(workflowId)
      .build());
      // use WorkflowClient.execute to return future that contains Workflow result or failure, or
      // use WorkflowClient.start to return WorkflowId and RunId of the started Workflow).
      WorkflowClient.start(workflow::greetCustomer);
    • Untyped WorkflowStub Example

      WorkflowStub untyped = client.newUntypedWorkflowStub("FileProcessingWorkflow",
      WorkflowOptions.newBuilder()
      .setWorkflowId(workflowId)
      .setTaskQueue(taskQueue)
      .build());

      // blocks until Workflow Execution has been started (not until it completes)
      untyped.start(argument);

You can call a Dynamic Workflow implementation using an untyped WorkflowStub. The following example shows how to call the Dynamic Workflow implementation in the Client code.

    WorkflowClient client = WorkflowClient.newInstance(service);
/**
* Note that for this part of the client code, the dynamic Workflow implementation must
* be known to the Worker at runtime in order to dispatch Workflow tasks, and may be defined
* in the Worker definition as:*/
// worker.registerWorkflowImplementationTypes(DynamicGreetingWorkflowImpl.class);

/* Create the Workflow stub to call the dynamic Workflow.
* Note that the Workflow Type is not explicitly registered with the Worker.*/
WorkflowOptions workflowOptions =
WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).setWorkflowId(WORKFLOW_ID).build();
WorkflowStub workflow = client.newUntypedWorkflowStub("DynamicWF", workflowOptions);

DynamicWorkflow can be used to invoke different Workflow Types. To check what type is running when your Dynamic Workflow execute method runs, use getWorkflowType() in the implementation code.

String type = Workflow.getInfo().getWorkflowType();

See Workflow Execution Result for details on how to get the results of the Workflow Execution.

Using ExternalWorkflowStub

Use ExternalWorkflowStub within a Workflow to invoke, and send Signals to, other Workflows by type.

This helps particularly for executing Workflows written in other language SDKs, as shown in the following example.

@Override
public String yourWFMethod(String name) {
ExternalWorkflowStub callOtherWorkflow = Workflow.newUntypedExternalWorkflowStub("OtherWFId");
}

See the Temporal Polyglot code for examples of executing Workflows written in other language SDKs.

Recurring start

You can start a Workflow Execution on a regular schedule by using setCronSchedule Workflow option in the Client code.