Documentation Index Fetch the complete documentation index at: https://mintlify.com/cadence-workflow/cadence/llms.txt
Use this file to discover all available pages before exploring further.
Introduction
The Cadence Java SDK is the official client library for building workflows and activities in Java and other JVM languages. It provides annotation-based workflow definitions, Spring Boot integration, and comprehensive tooling for enterprise applications.
GitHub Repository Official Cadence Java Client SDK - Star and contribute on GitHub
Installation
Prerequisites
Java 8 or higher (Java 11+ recommended)
Maven 3.6+ or Gradle 6.0+
Cadence server running (local or remote)
Maven Setup
Add the Cadence Java client dependency to your pom.xml:
< dependencies >
< dependency >
< groupId > com.uber.cadence </ groupId >
< artifactId > cadence-client </ artifactId >
< version > 3.11.2 </ version >
</ dependency >
</ dependencies >
Gradle Setup
Add the dependency to your build.gradle:
dependencies {
implementation 'com.uber.cadence:cadence-client:3.11.2'
}
Quick Start
1. Define a Workflow Interface
Workflow interfaces define the contract for workflow execution:
import com.uber.cadence.workflow.WorkflowMethod;
import com.uber.cadence.workflow.SignalMethod;
import com.uber.cadence.workflow.QueryMethod;
public interface HelloWorkflow {
@ WorkflowMethod ( executionStartToCloseTimeoutSeconds = 600 )
String sayHello ( String name );
@ SignalMethod
void updateGreeting ( String greeting );
@ QueryMethod
int getCallCount ();
}
2. Implement the Workflow
Workflow implementations must be deterministic:
import com.uber.cadence.workflow.Workflow;
import com.uber.cadence.activity.ActivityOptions;
import java.time.Duration;
public class HelloWorkflowImpl implements HelloWorkflow {
private String greeting = "Hello" ;
private int callCount = 0 ;
// Configure activity options
private final ActivityOptions activityOptions = new ActivityOptions. Builder ()
. setScheduleToStartTimeout ( Duration . ofMinutes ( 1 ))
. setStartToCloseTimeout ( Duration . ofMinutes ( 5 ))
. setHeartbeatTimeout ( Duration . ofSeconds ( 20 ))
. build ();
// Create activity stub
private final GreetingActivities activities =
Workflow . newActivityStub ( GreetingActivities . class , activityOptions);
@ Override
public String sayHello ( String name ) {
callCount ++ ;
// Execute activity
String result = activities . greet (greeting, name);
// Workflow can also use timers
Workflow . sleep ( Duration . ofSeconds ( 1 ));
return result;
}
@ Override
public void updateGreeting ( String greeting ) {
this . greeting = greeting;
}
@ Override
public int getCallCount () {
return callCount;
}
}
3. Define Activity Interface
Activities perform non-deterministic operations:
import com.uber.cadence.activity.ActivityMethod;
public interface GreetingActivities {
@ ActivityMethod ( scheduleToCloseTimeoutSeconds = 300 )
String greet ( String greeting , String name );
@ ActivityMethod
void sendEmail ( String to , String message );
}
4. Implement Activities
Activity implementations can call external services:
import com.uber.cadence.activity.Activity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GreetingActivitiesImpl implements GreetingActivities {
private static final Logger logger =
LoggerFactory . getLogger ( GreetingActivitiesImpl . class );
@ Override
public String greet ( String greeting , String name ) {
// Activities can call external services
logger . info ( "Greeting {} with {}" , name, greeting);
// Record heartbeat for long-running activities
Activity . getExecutionContext (). heartbeat ( null );
return String . format ( "%s, %s!" , greeting, name);
}
@ Override
public void sendEmail ( String to , String message ) {
// Call email service
logger . info ( "Sending email to {} with message: {}" , to, message);
}
}
Workers poll for and execute workflows and activities:
import com.uber.cadence.client.WorkflowClient;
import com.uber.cadence.serviceclient.ClientOptions;
import com.uber.cadence.serviceclient.WorkflowServiceTChannel;
import com.uber.cadence.worker.Worker;
import com.uber.cadence.worker.WorkerFactory;
import com.uber.cadence.worker.WorkerOptions;
public class WorkerMain {
private static final String DOMAIN = "my-domain" ;
private static final String TASK_LIST = "my-task-list" ;
public static void main ( String [] args ) {
// Create Cadence service client
WorkflowServiceTChannel service = new WorkflowServiceTChannel (
ClientOptions . newBuilder ()
. setHost ( "localhost" )
. setPort ( 7933 )
. build ()
);
// Create workflow client
WorkflowClient workflowClient = WorkflowClient . newInstance (
service,
WorkflowClient . Options . newBuilder ()
. setDomain (DOMAIN)
. build ()
);
// Create worker factory
WorkerFactory factory = WorkerFactory . newInstance (workflowClient);
// Configure worker
WorkerOptions workerOptions = WorkerOptions . newBuilder ()
. setMaxConcurrentActivityExecutionSize ( 100 )
. setMaxConcurrentWorkflowExecutionSize ( 50 )
. build ();
Worker worker = factory . newWorker (TASK_LIST, workerOptions);
// Register workflow implementation
worker . registerWorkflowImplementationTypes ( HelloWorkflowImpl . class );
// Register activity implementation
worker . registerActivitiesImplementations ( new GreetingActivitiesImpl ());
// Start worker
factory . start ();
System . out . println ( "Worker started for task list: " + TASK_LIST);
}
}
6. Execute Workflow
Start workflow execution from your application:
import com.uber.cadence.client.WorkflowClient;
import com.uber.cadence.client.WorkflowOptions;
import com.uber.cadence.serviceclient.ClientOptions;
import com.uber.cadence.serviceclient.WorkflowServiceTChannel;
import java.time.Duration;
public class WorkflowStarter {
public static void main ( String [] args ) {
// Create service client
WorkflowServiceTChannel service = new WorkflowServiceTChannel (
ClientOptions . newBuilder ()
. setHost ( "localhost" )
. setPort ( 7933 )
. build ()
);
// Create workflow client
WorkflowClient workflowClient = WorkflowClient . newInstance (
service,
WorkflowClient . Options . newBuilder ()
. setDomain ( "my-domain" )
. build ()
);
// Configure workflow options
WorkflowOptions workflowOptions = new WorkflowOptions. Builder ()
. setWorkflowId ( "hello-workflow-1" )
. setTaskList ( "my-task-list" )
. setExecutionStartToCloseTimeout ( Duration . ofMinutes ( 10 ))
. build ();
// Create workflow stub
HelloWorkflow workflow = workflowClient . newWorkflowStub (
HelloWorkflow . class ,
workflowOptions
);
// Start workflow execution
String result = workflow . sayHello ( "World" );
System . out . println ( "Workflow result: " + result);
}
}
Advanced Patterns
Child Workflows
Compose complex workflows from simpler ones:
import com.uber.cadence.workflow.Workflow;
import com.uber.cadence.workflow.ChildWorkflowOptions;
import java.time.Duration;
public class ParentWorkflowImpl implements ParentWorkflow {
@ Override
public String orchestrate ( String input ) {
// Configure child workflow options
ChildWorkflowOptions childOptions = new ChildWorkflowOptions. Builder ()
. setExecutionStartToCloseTimeout ( Duration . ofHours ( 1 ))
. setTaskList ( "child-task-list" )
. build ();
// Create child workflow stub
ChildWorkflow child = Workflow . newChildWorkflowStub (
ChildWorkflow . class ,
childOptions
);
// Execute child workflow
String childResult = child . processData (input);
return "Parent processed: " + childResult;
}
}
Saga Pattern
Implement distributed transactions with compensation:
import com.uber.cadence.workflow.Workflow;
import com.uber.cadence.workflow.Saga;
import io.temporal.common.CancellationScope;
public class SagaWorkflowImpl implements SagaWorkflow {
private final BookingActivities activities =
Workflow . newActivityStub ( BookingActivities . class );
@ Override
public void bookTrip ( String userId , String flightId , String hotelId ) {
Saga saga = new Saga ( new Saga. Options . Builder ()
. setParallelCompensation ( false )
. build ());
try {
// Book flight
String flightBookingId = activities . bookFlight (flightId, userId);
saga . addCompensation (() ->
activities . cancelFlight (flightBookingId)
);
// Book hotel
String hotelBookingId = activities . bookHotel (hotelId, userId);
saga . addCompensation (() ->
activities . cancelHotel (hotelBookingId)
);
// Charge payment
activities . chargePayment (userId, calculateTotal ());
saga . addCompensation (() ->
activities . refundPayment (userId)
);
} catch ( Exception e ) {
// Compensate on failure
saga . compensate ();
throw e;
}
}
private double calculateTotal () {
return 1000.0 ; // Simplified
}
}
Signals and Queries
Signal Handler
Query Handler
public class OrderWorkflowImpl implements OrderWorkflow {
private String status = "PENDING" ;
private boolean approved = false ;
@ Override
public void processOrder ( String orderId ) {
// Wait for approval signal
Workflow . await (() -> approved);
status = "APPROVED" ;
// Continue processing...
}
@ Override
public void approveOrder () {
this . approved = true ;
}
@ Override
public String getStatus () {
return status;
}
}
// Send signal from client
OrderWorkflow workflow = workflowClient . newWorkflowStub (
OrderWorkflow . class ,
"order-workflow-id"
);
workflow . approveOrder ();
// Query workflow state
OrderWorkflow workflow = workflowClient . newWorkflowStub (
OrderWorkflow . class ,
"order-workflow-id"
);
String status = workflow . getStatus ();
System . out . println ( "Order status: " + status);
Retry Policies
Configure automatic retries for activities:
import com.uber.cadence.common.RetryOptions;
import java.time.Duration;
public class RobustWorkflowImpl implements RobustWorkflow {
private final RetryOptions retryOptions = new RetryOptions. Builder ()
. setInitialInterval ( Duration . ofSeconds ( 1 ))
. setMaximumInterval ( Duration . ofMinutes ( 1 ))
. setBackoffCoefficient ( 2.0 )
. setMaximumAttempts ( 5 )
. setDoNotRetry ( IllegalArgumentException . class )
. build ();
private final ActivityOptions activityOptions = new ActivityOptions. Builder ()
. setStartToCloseTimeout ( Duration . ofMinutes ( 5 ))
. setRetryOptions (retryOptions)
. build ();
private final RiskyActivities activities =
Workflow . newActivityStub ( RiskyActivities . class , activityOptions);
@ Override
public void executeRiskyOperation () {
// Activity will be automatically retried on failure
activities . riskyCall ();
}
}
Spring Boot Integration
Spring Configuration
import com.uber.cadence.client.WorkflowClient;
import com.uber.cadence.serviceclient.ClientOptions;
import com.uber.cadence.serviceclient.WorkflowServiceTChannel;
import com.uber.cadence.worker.WorkerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ Configuration
public class CadenceConfiguration {
@ Value ( "${cadence.service.host:localhost}" )
private String cadenceHost ;
@ Value ( "${cadence.service.port:7933}" )
private int cadencePort ;
@ Value ( "${cadence.domain}" )
private String domain ;
@ Bean
public WorkflowServiceTChannel workflowService () {
return new WorkflowServiceTChannel (
ClientOptions . newBuilder ()
. setHost (cadenceHost)
. setPort (cadencePort)
. build ()
);
}
@ Bean
public WorkflowClient workflowClient ( WorkflowServiceTChannel service ) {
return WorkflowClient . newInstance (
service,
WorkflowClient . Options . newBuilder ()
. setDomain (domain)
. build ()
);
}
@ Bean
public WorkerFactory workerFactory ( WorkflowClient workflowClient ) {
return WorkerFactory . newInstance (workflowClient);
}
}
Spring Worker Component
import com.uber.cadence.worker.Worker;
import com.uber.cadence.worker.WorkerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@ Component
public class CadenceWorker implements CommandLineRunner {
@ Autowired
private WorkerFactory workerFactory ;
@ Autowired
private GreetingActivitiesImpl activities ;
@ Override
public void run ( String ... args ) {
Worker worker = workerFactory . newWorker ( "my-task-list" );
worker . registerWorkflowImplementationTypes ( HelloWorkflowImpl . class );
worker . registerActivitiesImplementations (activities);
workerFactory . start ();
}
}
Testing
Unit Testing Workflows
import com.uber.cadence.testing.TestWorkflowEnvironment;
import com.uber.cadence.worker.Worker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito. * ;
public class HelloWorkflowTest {
private TestWorkflowEnvironment testEnv ;
private Worker worker ;
@ Before
public void setUp () {
testEnv = TestWorkflowEnvironment . newInstance ();
worker = testEnv . newWorker ( "test-task-list" );
// Register workflow
worker . registerWorkflowImplementationTypes ( HelloWorkflowImpl . class );
}
@ After
public void tearDown () {
testEnv . close ();
}
@ Test
public void testWorkflow () {
// Mock activities
GreetingActivities activities = mock ( GreetingActivities . class );
when ( activities . greet ( "Hello" , "World" ))
. thenReturn ( "Hello, World!" );
worker . registerActivitiesImplementations (activities);
// Start test environment
testEnv . start ();
// Create workflow stub
HelloWorkflow workflow = testEnv . newWorkflowStub ( HelloWorkflow . class );
// Execute workflow
String result = workflow . sayHello ( "World" );
// Verify result
assertEquals ( "Hello, World!" , result);
verify (activities). greet ( "Hello" , "World" );
}
}
Sample Repository
Cadence Java Samples Enterprise examples including:
Spring Boot integration
Saga pattern implementation
Complex orchestration scenarios
Testing strategies
Production configurations
Best Practices
Keep workflow code deterministic
Use Workflow.getVersion() for versioning
Avoid direct instantiation of random or time
Use workflow methods for all non-deterministic operations
Make activities idempotent when possible
Implement heartbeats for long-running activities
Use dependency injection for testability
Handle exceptions appropriately
Use Spring’s dependency injection for activities
Configure workers as Spring components
Externalize configuration to application.properties
Implement health checks for workers
Next Steps
Core Concepts Understand workflows, activities, and task lists
Go Client Explore the Go SDK for cloud-native apps
CLI Reference Manage workflows with the Cadence CLI
Operations Monitor and operate Cadence in production