Skip to main content
Temporal Java SDK

Run the application

~5 minutesTemporal beginnerHands-on tutorial
  1. Build the application
  2. Test and run a Worker
  3. Run the application

With your Workflow, Activity, and Worker in place, you'll now write a small client program to start the Workflow Execution, then run the Worker and client together to see Temporal orchestrate everything end to end.

Write code to start a Workflow Execution

You can start a Workflow Execution by using the Temporal CLI or by writing code using the Temporal SDK. In this tutorial, you'll use the Temporal SDK to start the Workflow, which is how most real-world applications work.

Starting a Workflow Execution using the Temporal SDK involves connecting to the Temporal Server, specifying the Task Queue the Workflow should use, and starting the Workflow with the input parameters it expects. In a real application, you may invoke this code when someone submits a form, presses a button, or visits a certain URL. In this tutorial, you'll create a separate Java class that starts the Workflow Execution.

Create InitiateHelloWorld.java in app/src/main/java/helloworldapp/ and add the following code to the file to connect to the server and start the Workflow:

app/src/main/java/helloworldapp/InitiateHelloWorld.java
package helloworldapp;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.client.WorkflowStub;
import io.temporal.serviceclient.WorkflowServiceStubs;

public class InitiateHelloWorld {

public static void main(String[] args) throws Exception {

// This gRPC stubs wrapper talks to the local docker instance of the Temporal service.
WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();

// WorkflowClient can be used to start, signal, query, cancel, and terminate Workflows.
WorkflowClient client = WorkflowClient.newInstance(service);

// Define our workflow unique id
final String WORKFLOW_ID = "HelloWorldWorkflowID";

/*
* Set Workflow options such as WorkflowId and Task Queue so the worker knows where to list and which workflows to execute.
*/
WorkflowOptions options = WorkflowOptions.newBuilder()
.setWorkflowId(WORKFLOW_ID)
.setTaskQueue(Shared.HELLO_WORLD_TASK_QUEUE)
.build();

// Create the workflow client stub. It is used to start our workflow execution.
HelloWorldWorkflow workflow = client.newWorkflowStub(HelloWorldWorkflow.class, options);

/*
* Execute our workflow and wait for it to complete. The call to our getGreeting method is
* synchronous.
*
* Replace the parameter "World" in the call to getGreeting() with your name.
*/
String greeting = workflow.getGreeting("World");

String workflowId = WorkflowStub.fromTyped(workflow).getExecution().getWorkflowId();
// Display workflow execution results
System.out.println(workflowId + " " + greeting);
System.exit(0);
}
}

Like the Worker you created, this program uses stubs and a client to connect to the Temporal server. It then specifies a Workflow ID for the Workflow, as well as the Task Queue. The Worker you configured is looking for tasks on that Task Queue.

Specify a Workflow ID

A Workflow Id is unique in a namespace and is used for deduplication. Using an identifier that reflects some business process or entity is a good practice. For example, you might use a customer identifier as part of the Workflow Id if you run one Workflow per customer. This would make it easier to find all of the Workflow Executions related to that customer later.

The program then creates a stubbed instance of your Workflow, workflow, taking the interface class of your workflow along with the options you have set as parameters. This stub looks like an implementation of the interface, but is used to communicate with the Temporal Server under the hood.

note

Notice that an interface of HelloWorldWorkflow is used to create the Workflow stub, not the Workflow implementation. The workflow communicates with a Workflow through its public interface and is not aware of its implementation.

You can get the results from your Workflow right away, or you can get the results at a later time. This implementation stores the results in the greeting variable after the getGreeting() method is called, which blocks the program's execution until the Workflow Execution completes.

You have a Workflow, an Activity, a Worker, and a way to start a Workflow Execution. It's time to run the Workflow.

Run the application

To run your Temporal Application, you need to start the Workflow and the Worker. You can start these in any order, but you'll need to run each command from a separate terminal window, as the Worker needs to be constantly running to look for tasks to execute.

First, ensure that your local Temporal Service is running.

To start the Worker, run this command from the project root:

mvn compile exec:java -Dexec.mainClass="helloworldapp.HelloWorldWorker"

You will see similar output from Maven:

[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< helloworldapp:app >--------------------------
[INFO] Building app 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec:3.1.0:java (default-cli) @ app ---
note

Based on the output above, it may appear that your application is stuck or non-responsive. This is not the case. Your Worker is running and ready to accept Workflows to be executed. Leave this program running and proceed to the next step.

To start the Workflow, open a new terminal window and switch to your project root:

cd hello-world-temporal

Run the following command to start the Workflow Execution:

mvn exec:java -Dexec.mainClass="helloworldapp.InitiateHelloWorld"

The program runs and returns the result:

[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< helloworldapp:app >--------------------------
[INFO] Building app 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec:3.1.0:java (default-cli) @ app ---
HelloWorldWorkflowID Hello World!

You can switch back to the terminal running the Worker and stop it with CTRL-C.

You have successfully built a Temporal application from scratch.

Conclusion

You now know how to build a Temporal Workflow application using the Java SDK. All of the code in this tutorial is available in the hello-world Java template repository.

Let's do a quick review to make sure you remember some of the more important pieces.

What are the minimum four pieces of a Temporal Workflow application?
  1. An Activity function.
  2. A Workflow function.
  3. A Worker to host the Activity and Workflow code.
  4. Some way to start the Workflow.
How does the Worker know which Activity to execute and when to do so?

Each Worker is configured to poll a specified Task Queue, whose name is specified when the Worker is created. The Temporal Server adds tasks to this queue, specifying the details about the Workflows and Activities that the Worker should execute.

True or false, with the Temporal Java SDK, you define Activities and Workflows by writing an Interface to create a definition and implementation of this interface that gets executed by the Workers?

True. Workflows and Activities are defined as interfaces and their implementations will implement the interface.

Get notified when we launch new educational content

New courses, tutorials, and learning resources - straight to your inbox.

Subscribe
Feedback