- Level: ⭐ Temporal beginner
- Time: ⏱️ ~20 minutes
- Goals: 🙌
- Learn how to set up, build, and test a Temporal application project from scratch using the Java SDK.
- Become more familiar with core concepts and the application structure.
This tutorial focuses on the practicalities of building an application from scratch. To better understand why you should use Temporal, we recommend that you follow the tutorial where you run a Temporal money transfer application to get a taste of its value propositions.
Before starting, make sure you have looked over the tutorial prerequisites.
All of the code in this tutorial is available in the Java "Hello World!" application template.
In a terminal, create a new project directory named "hello-world-project", or something similar and
cd into it.
We use Gradle to build and manage Java projects in these tutorials. You can scaffold a new Gradle project from the terminal or from within IntelliJ.
Change your working directory to the one created for the project and follow Gradle's Building Java Applications guide. When you get to the step where you define your source package, use "helloworldapp".
Open IntelliJ and create a new Gradle project by following Step 1 of the Getting started with Gradle guide. When you get to the step where you name the project, use "helloworldapp" and make sure you choose the "hello-world-tutorial" directory as the project location. It will take a few moments to complete.
Once Gradle has finished scaffolding you will need to customize the project dependencies. To do this, open the build.gradle file that is in the root of your project and add the following lines to the dependencies section. If you want to try using different versions of dependencies, you can find them on search.maven.org (Temporal SDK versions):
com.google.guava:guavaoffers a suit of core and expanded libraries that Gradle uses.
io.temporal:temporal-sdkenables communication with the Temporal server.
ch.qos.logback:logback-classicwill ensure that there is a logger to bind to within the SDK and prevent a default logger warning message.
To limit the logging output from the SDK, within src/main/resources/ create a logback.xml file and paste in the following XML:
If you are editing the files in IntelliJ, a "refresh" icon will appear on the screen. Click it to load the changes. Gradle will rebuild with the dependencies. Otherwise you can run
./gradlew build from the root of the project again.
All of the files for our application will be created in src/main/java/helloworldapp/. However, if you have selected Gradle through IntelliJ instead of scaffolding it from the terminal, you may have to create the directory helloworldapp by yourself. If you have scaffolded Gradle through the terminal, Gradle will have generated a default App.java class in that location. Remove it before proceeding.
Now we are ready to build our Temporal Workflow application. Our app will consist of four pieces:
- An Activity: An Activity is just a function that contains your business logic. Ours will simply format some text and return it.
- A Workflow: Workflows are functions that organize Activity method calls. Our Workflow will orchestrate the call of a single Activity function.
- A Worker: Workers host the Activity and Workflow code and execute the code piece by piece.
- An initiator: To start a Workflow, we must send a signal to the Temporal server to tell it to track the state of the Workflow. We'll write a separate function to do this.
First, let's define our Activity. Activities are meant to handle non-deterministic code that could result in unexpected results or errors. But for this tutorial all we are doing is taking a string, appending it to "Hello", and returning it back to the Workflow.
An Activity object is defined like any other object in Java. You need an interface and an implementation. The only difference is that the interface includes Temporal decorators. Let's create a
Format object with a
Create Format.java and add the following interface definition:
Create FormatImpl.java and define the implementation of the Format interface:
Next is our Workflow. Workflow functions are where you configure and organize the execution of Activity functions. Again, the Workflow object is defined like any other, except the interface includes Temporal decorators. Our Workflow has just a single entry method which calls the
composeGreeting() Activity method and returns the result.
Create HelloWorldWorkflow.java and define the Workflow interface:
Create HelloWorldWorkflowImpl.java and define the Workflow:
Task Queues are how the Temporal server supplies information to Workers. When you start a Workflow, you tell the server which Task Queue the Workflow and/or Activities use as an information queue. We will configure our Worker to listen to the same Task Queue that our Workflow and Activities use. Since the Task Queue name is used by multiple things, let's create Shared.java and define our Task Queue name there:
Our Worker hosts Workflow and Activity functions and executes them one at a time. The Worker is instructed to execute the specific functions via information it gets from the Task Queue, and after execution, it communicates results back to the server.
Create HelloWorldWorker.java and define the Worker:
There are two ways to start a Workflow, via the Temporal CLI or Temporal SDK. In this tutorial we will use the SDK to start the Workflow which is how most Workflows are started in live environments. Additionally, the call to the Temporal server can be made synchronously or asynchronously. Here we do it synchronously, so you will see the caller wait for the result of the Workflow.
Create InitiateHelloWorld.java and use the SDK to define the start of the Workflow:
Let's add a simple unit test to our application to make sure things are working as expected. Test code lives in src/test/java/helloworldapp. If you don't see the helloworldapp-directory, go ahead and create it yourself. Gradle might have generated a default AppTest.java in that location. If AppTest.java is there, remove that file. Create a new class HelloWorldWorkflowTest.java that contains the following code:
From the root of the project, run this command:
From within IntelliJ, right click on HelloWorldWorkflowTest and select Run.
Look for "BUILD SUCCESSFUL" in the output to confirm.
To run the app we need to start the Workflow and the Worker. You can start them in any order. Make sure you have the Temporal server running in a terminal and have the Temporal Web UI open in your browser
If you are using the terminal, add tasks to the build.gradle file so that you can run the main methods from there.
To start the Worker, run this command from the project root:
To start the Workflow, run this command from the project root:
To start the Worker from within IntelliJ, right click on HelloWorldWorker and select Run.
To start the Workflow fromw Within IntelliJ, right click on InitiateHelloWorld and select Run.
Congratulations you have successfully built a Temporal application from scratch!
Great work! You now know how to build a Temporal Workflow application using the Java SDK and Gradle. Let's do a quick review to make sure you remember some fo the more important pieces.
What are the minimum four pieces of a Temporal Workflow application?
- An Activity object and method.
- A Workflow object and method.
- A Worker to host the Activity and Workflow code.
- A function to start the Workflow.
How does the Temporal server get information to the Worker?
It puts information into a Task Queue.
What makes Temporal Activity and Workflow objects different from any other Java object?
The only difference is the interfaces have Temporal decorators.