--- description: "Build Conductor workers in Java with automated polling, thread management, and Spring Boot integration." --- # Java SDK !!! info "Source" GitHub: [conductor-oss/java-sdk](https://github.com/conductor-oss/java-sdk) | Report issues and contribute on GitHub. ## Start Conductor server If you don't already have a Conductor server running, pick one: **Docker (recommended, includes UI):** ```shell docker run -p 8080:8080 conductoross/conductor:latest ``` The UI will be available at `http://localhost:8080` and the API at `http://localhost:8080/api` **MacOS / Linux (one-liner):** (If you don't want to use docker, you can install and run the binary directly) ```shell curl -sSL https://raw.githubusercontent.com/conductor-oss/conductor/main/conductor_server.sh | sh ``` **Conductor CLI** ```shell # Installs conductor cli npm install -g @conductor-oss/conductor-cli # Start the open source conductor server conductor server start # see conductor server --help for all the available commands ``` ## Install the SDK The SDK requires Java 17+. Add the following dependency to your project: **For Gradle:** ```gradle dependencies { implementation 'org.conductoross:conductor-client:5.0.1' // Optionally, you can also add spring module for auto configuration // implementation 'org.conductoross:conductor-client-spring:5.0.1' } ``` **For Maven:** ```xml org.conductoross conductor-client 5.0.1 ``` *Optionally, you can also add spring module for auto configuration* ```xml org.conductoross conductor-client-spring 5.0.1 ``` ## 60-Second Quickstart **Step 1: Write a worker** Workers are Java classes that implement the `Worker` interface and poll Conductor for tasks to execute. ```java public class GreetWorker implements Worker { @Override public String getTaskDefName() { return "greet"; } @Override public TaskResult execute(Task task) { String name = (String) task.getInputData().get("name"); TaskResult result = new TaskResult(task); result.setStatus(TaskResult.Status.COMPLETED); result.addOutputData("greeting", "Hello, " + name + "!"); return result; } } ``` **Step 2: Run your first workflow app** Create a `Main.java` with the following: ```java import io.orkes.conductor.client.ApiClient; import io.orkes.conductor.client.OrkesClients; import com.netflix.conductor.client.automator.TaskRunnerConfigurer; import com.netflix.conductor.common.metadata.workflow.StartWorkflowRequest; import com.netflix.conductor.sdk.workflow.def.ConductorWorkflow; import com.netflix.conductor.sdk.workflow.def.tasks.SimpleTask; import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { // Configure the SDK via ApiClient (enterprise-compatible path) ApiClient apiClient = ApiClient.builder().build(); OrkesClients clients = new OrkesClients(apiClient); // Create workflow executor WorkflowExecutor executor = new WorkflowExecutor(apiClient, 100); // Build and register the workflow ConductorWorkflow workflow = new ConductorWorkflow<>(executor); workflow.setName("greetings"); workflow.setVersion(1); SimpleTask greetTask = new SimpleTask("greet", "greet_ref"); greetTask.input("name", "${workflow.input.name}"); workflow.add(greetTask); workflow.registerWorkflow(true, true); // Start polling for tasks using OrkesTaskClient TaskRunnerConfigurer configurer = new TaskRunnerConfigurer.Builder( clients.getTaskClient(), List.of(new GreetWorker()) ).withThreadCount(10).build(); configurer.init(); // Run the workflow using OrkesWorkflowClient StartWorkflowRequest request = new StartWorkflowRequest(); request.setName("greetings"); request.setVersion(1); request.setInput(Map.of("name", "Conductor")); String workflowId = clients.getWorkflowClient().startWorkflow(request); System.out.println("Started workflow: " + workflowId); System.out.println("View execution at: " + apiClient.getBasePath().replace("/api", "") + "/execution/" + workflowId); } } ``` Run it: ```shell ./gradlew run ``` > ### Using Orkes Conductor / Remote Server? > Export your authentication credentials as well: > > ```shell > export CONDUCTOR_SERVER_URL="https://your-cluster.orkesconductor.io/api" > > # If using Orkes Conductor that requires auth key/secret > export CONDUCTOR_AUTH_KEY="your-key" > export CONDUCTOR_AUTH_SECRET="your-secret" > ``` That's it -- you just defined a worker, built a workflow, and executed it. Open the Conductor UI (default: [http://localhost:8080](http://localhost:8080)) to see the execution. ## Comprehensive worker example See [examples/basics/hello-world/](https://github.com/conductor-oss/java-sdk/tree/main/examples/basics/hello-world) for a complete working example with: - Workflow definition using the SDK - Worker implementation with annotations - Workflow execution and monitoring --- ## Workers Workers are Java classes that execute Conductor tasks. Implement the `Worker` interface or use the `@WorkerTask` annotation: **Using Worker interface:** ```java public class MyWorker implements Worker { @Override public String getTaskDefName() { return "my_task"; } @Override public TaskResult execute(Task task) { // Your business logic here TaskResult result = new TaskResult(task); result.setStatus(TaskResult.Status.COMPLETED); result.addOutputData("result", "Task completed successfully"); return result; } } ``` **Using @WorkerTask annotation:** ```java public class Workers { @WorkerTask("greet") public String greet(@InputParam("name") String name) { return "Hello, " + name + "!"; } @WorkerTask("process_data") public Map processData(@InputParam("data") Map data) { // Process and return data return Map.of("processed", true, "result", data); } } ``` **Start workers** with `TaskRunnerConfigurer` or `WorkflowExecutor`: ```java // Option 1: Using TaskRunnerConfigurer ApiClient apiClient = ApiClient.builder().build(); OrkesClients clients = new OrkesClients(apiClient); TaskRunnerConfigurer configurer = new TaskRunnerConfigurer.Builder( clients.getTaskClient(), List.of(new MyWorker(), new AnotherWorker()) ) .withThreadCount(10) .build(); configurer.init(); // Option 2: Using WorkflowExecutor (auto-discovers @WorkerTask annotations) WorkflowExecutor executor = new WorkflowExecutor(apiClient, 10); executor.initWorkers("com.mycompany.workers"); // Package to scan for @WorkerTask ``` **Worker Design Principles:** - Workers should be stateless and idempotent - Handle failure scenarios gracefully - Report status back to Conductor - Complete execution quickly (or use polling for long-running tasks) **Worker vs. HTTP Endpoints:** | Feature | Worker | HTTP Endpoint | |---------|--------|---------------| | Deployment | Embedded in application | Separate service | | Scalability | Horizontal (add more instances) | Horizontal (add more instances) | | Latency | Lower (direct polling) | Higher (network overhead) | | Complexity | Simple | Complex (service mesh, load balancer) | **Learn more:** - [Worker SDK Guide](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/worker_sdk.md) — Complete worker framework documentation - [Worker Examples](https://github.com/conductor-oss/java-sdk/blob/main/examples/) — Sample worker implementations ## Monitoring Workers Enable metrics collection for monitoring workers: ```java // Using conductor-client-metrics module dependencies { implementation 'org.conductoross:conductor-client-metrics:5.0.1' } ``` ```java // Configure metrics with Prometheus TaskRunnerConfigurer configurer = new TaskRunnerConfigurer.Builder(taskClient, workers) .withThreadCount(10) .withMetricsCollector(new PrometheusMetricsCollector()) .build(); ``` See [conductor-client-metrics/README.md](https://github.com/conductor-oss/java-sdk/blob/main/conductor-client-metrics/README.md) for full metrics documentation. ## Workflows Define workflows in Java using the `ConductorWorkflow` builder: ```java ConductorWorkflow workflow = new ConductorWorkflow<>(executor); workflow.setName("my_workflow"); workflow.setVersion(1); workflow.setOwnerEmail("team@example.com"); // Add tasks SimpleTask task1 = new SimpleTask("task1", "task1_ref"); SimpleTask task2 = new SimpleTask("task2", "task2_ref"); workflow.add(task1); workflow.add(task2); // Register the workflow workflow.registerWorkflow(true, true); ``` **Execute workflows:** ```java ApiClient apiClient = ApiClient.builder().build(); OrkesClients clients = new OrkesClients(apiClient); WorkflowClient workflowClient = clients.getWorkflowClient(); // Synchronous (start and poll for completion) CompletableFuture future = workflow.execute(input); Workflow result = future.get(30, TimeUnit.SECONDS); System.out.println("Output: " + result.getOutput()); // Asynchronous (returns workflow ID immediately) StartWorkflowRequest request = new StartWorkflowRequest(); request.setName("my_workflow"); request.setVersion(1); request.setInput(Map.of("key", "value")); String workflowId = workflowClient.startWorkflow(request); // Dynamic execution (sends workflow definition with request) CompletableFuture dynamicRun = workflow.executeDynamic(input); ``` **Manage running workflows:** ```java // Get workflow status Workflow wf = workflowClient.getWorkflow(workflowId, true); System.out.println("Status: " + wf.getStatus()); // Pause, resume, terminate workflowClient.pauseWorkflow(workflowId); workflowClient.resumeWorkflow(workflowId); workflowClient.terminateWorkflow(workflowId, "No longer needed"); // Retry and restart failed workflows workflowClient.retryWorkflow(workflowId); workflowClient.restartWorkflow(workflowId, false); ``` **Learn more:** - [Workflow SDK Guide](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/workflow_sdk.md) — Workflow-as-code documentation - [Workflow Testing](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/testing_framework.md) — Unit testing workflows ## Troubleshooting **Worker stops polling or crashes:** - Check network connectivity to Conductor server - Verify `CONDUCTOR_SERVER_URL` is set correctly - Ensure sufficient thread pool size for your workload - Monitor JVM memory and GC pauses **Connection refused errors:** - Verify Conductor server is running: `curl http://localhost:8080/health` - Check firewall rules if connecting to remote server - For Orkes Conductor, verify auth credentials are correct **Tasks stuck in SCHEDULED state:** - Ensure workers are polling for the correct task type - Check that `getTaskDefName()` matches the task name in workflow - Verify worker thread count is sufficient **Workflow execution timeout:** - Increase workflow timeout in definition - Check if tasks are completing within expected time - Monitor Conductor server logs for errors **Authentication errors with Orkes Conductor:** - Verify `CONDUCTOR_AUTH_KEY` and `CONDUCTOR_AUTH_SECRET` are set - Ensure the application has required permissions - Check that credentials haven't expired --- ## File handling For workflows that move binary file payloads, the SDK exposes `FileHandler` — a worker-facing reference to a file in the configured backend. Pass it as a worker input/output and the runtime handles upload, download, and the metadata roundtrip transparently. See [File Storage](../advanced/file-storage.md) for the operator-side configuration and [File API](../api/files.md) for the underlying REST surface. The relevant types in `org.conductoross.conductor.sdk.file`: | Type | Use | |---|---| | `FileHandler` | Worker parameter type for files. Static `fromLocalFile(Path)` / `fromLocalFile(Path, contentType)` create a handle for a local file the worker is producing. | | `FileUploader` | Explicit upload API; obtained from `task.getFileUploader()` inside a `Worker` impl, or from `WorkflowFileClient` outside one. | | `FileUploadOptions` | Optional metadata: `contentType`, `fileName`, `taskId`, `multipart`. | **Worker that consumes a file:** ```java public class TranscodeInput { public FileHandler primary_video; public String resolution; } @WorkerTask("transcode_video") public @OutputParam("output_file") FileHandler transcode(TranscodeInput input) throws IOException { Path transcoded = Files.createTempFile("transcoded-", ".mp4"); try (InputStream in = input.primary_video.getInputStream()) { Files.write(transcoded, in.readAllBytes()); } return FileHandler.fromLocalFile(transcoded, "video/mp4"); } ``` `primary_video` is auto-resolved from the task input — the runtime downloads the file lazily on first read of `getInputStream()`. The returned `FileHandler` is auto-uploaded by the task runner before the task output is published, and the resulting `fileHandleId` is substituted into the output map so downstream tasks can consume it. **Explicit upload inside a `Worker` implementation:** ```java @Override public TaskResult execute(Task task) { Path output = renderReport(task); FileHandler handle = task.getFileUploader().upload( output, new FileUploadOptions().setContentType("application/pdf").setMultipart(true)); TaskResult result = new TaskResult(task); result.getOutputData().put("report", handle); return result; } ``` Use this form when you want to control upload timing (e.g., upload before the task's main work completes, or upload an `InputStream` that's not backed by a file). When `multipart=true` the SDK uses the multipart upload flow on backends that support it, falling back to single-shot otherwise. --- ## AI & LLM Workflows Conductor supports AI-native workflows including agentic tool calling, RAG pipelines, and multi-agent orchestration. **Agentic Workflows** Build AI agents where LLMs dynamically select and call Java workers as tools. All agentic examples live in [`AgenticExamplesRunner.java`](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/agentic/AgenticExamplesRunner.java) — a single unified runner. | Workflow | Description | |----------|-------------| | `llm_chat_workflow` | Automated multi-turn Q&A using `LLM_CHAT_COMPLETE` system task | | `llm_chat_human_in_loop` | Interactive chat with WAIT task pauses for user input | | `multiagent_chat_demo` | Multi-agent debate with moderator routing between two LLM panelists | | `function_calling_workflow` | LLM picks which Java worker to call, returns JSON, dispatch worker executes it | | `mcp_ai_agent` | AI agent using MCP tools (ListMcpTools → LLM plans → CallMcpTool → summarize) | **LLM and RAG Workflows** | Example | Description | |---------|-------------| | [RagWorkflowExample.java](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/agentic/RagWorkflowExample.java) | End-to-end RAG: document indexing, semantic search, answer generation | | [VectorDbExample.java](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/agentic/VectorDbExample.java) | Vector database operations: text indexing, embedding generation, and semantic search | **Using LLM Tasks in Workflows:** ```java // Chat completion task (LLM_CHAT_COMPLETE system task) LlmChatComplete chatTask = new LlmChatComplete("chat_assistant", "chat_ref") .llmProvider("openai") .model("gpt-4o-mini") .messages(List.of( Map.of("role", "system", "message", "You are a helpful assistant."), Map.of("role", "user", "message", "${workflow.input.question}") )) .temperature(0.7) .maxTokens(500); // Text completion task (LLM_TEXT_COMPLETE system task) LlmTextComplete textTask = new LlmTextComplete("generate_text", "text_ref") .llmProvider("openai") .model("gpt-4o-mini") .promptName("my-prompt-template") .temperature(0.7); // Document indexing for RAG (LLM_INDEX_DOCUMENT system task) LlmIndexDocument indexTask = new LlmIndexDocument("index_doc", "index_ref") .vectorDb("pinecone") .namespace("my-docs") .index("knowledge-base") .embeddingModel("text-embedding-ada-002") .text("${workflow.input.document}"); // Semantic search (LLM_SEARCH_INDEX system task) LlmSearchIndex searchTask = new LlmSearchIndex("search_docs", "search_ref") .vectorDb("pinecone") .namespace("my-docs") .index("knowledge-base") .query("${workflow.input.question}") .topK(5); // MCP tool discovery (MCP_LIST_TOOLS system task — Orkes Conductor) ListMcpTools listTools = new ListMcpTools("discover_tools", "tools_ref") .mcpServer("http://localhost:3001/mcp"); // MCP tool execution (MCP_CALL_TOOL system task — Orkes Conductor) CallMcpTool callTool = new CallMcpTool("execute_tool", "tool_ref") .mcpServer("http://localhost:3001/mcp") .method("${tools_ref.output.result.method}") .arguments("${tools_ref.output.result.arguments}"); workflow.add(chatTask); workflow.add(textTask); workflow.add(indexTask); ``` Run all agentic examples: ```shell export CONDUCTOR_SERVER_URL=http://localhost:8080/api export OPENAI_API_KEY=your-key # or ANTHROPIC_API_KEY # Run all examples end-to-end ./gradlew :examples:run --args="--all" # Run specific workflow ./gradlew :examples:run --args="--menu" ``` ## Examples See the [Examples Guide](https://github.com/conductor-oss/java-sdk/blob/main/examples/README.md) for the full catalog. Key examples: | Example | Description | Run | |---------|-------------|-----| | [Hello World](https://github.com/conductor-oss/java-sdk/tree/main/examples/basics/hello-world) | Minimal workflow with worker | `./gradlew :examples:run -PmainClass=com.netflix.conductor.sdk.examples.helloworld.Main` | | [Workflow Operations](https://github.com/conductor-oss/java-sdk/tree/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/workflowops) | Pause, resume, terminate workflows | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.workflowops.Main` | | [Shipment Workflow](https://github.com/conductor-oss/java-sdk/tree/main/examples/old/src/main/java/com/netflix/conductor/sdk/examples/shipment) | Real-world order processing | `./gradlew :examples:run -PmainClass=com.netflix.conductor.sdk.examples.shipment.Main` | | [Events](https://github.com/conductor-oss/java-sdk/tree/main/examples/old/src/main/java/com/netflix/conductor/sdk/examples/events) | Event-driven workflows | `./gradlew :examples:run -PmainClass=com.netflix.conductor.sdk.examples.events.EventHandlerExample` | | [All AI examples](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/agentic/AgenticExamplesRunner.java) | All agentic/LLM workflows | `./gradlew :examples:run --args="--all"` | | [RAG Workflow](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/agentic/RagWorkflowExample.java) | RAG pipeline (index → search → answer) | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.agentic.RagWorkflowExample` | | [Media Transcoder](https://github.com/conductor-oss/file-storage-java-sdk/tree/main/examples/file-storage/media-transcoder) | File-handling pipeline: upload video → transcode → thumbnail → manifest | `mvn -f examples/file-storage/media-transcoder/pom.xml exec:java` | ## API Journey Examples End-to-end examples covering all APIs for each domain: | Example | APIs | Run | |---------|------|-----| | [Metadata Management](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/MetadataManagement.java) | Task & workflow definitions | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.MetadataManagement` | | [Workflow Management](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/WorkflowManagement.java) | Start, monitor, control workflows | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.WorkflowManagement` | | [Authorization Management](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/AuthorizationManagement.java) | Users, groups, permissions | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.AuthorizationManagement` | | [Scheduler Management](https://github.com/conductor-oss/java-sdk/blob/main/examples/old/src/main/java/io/orkes/conductor/sdk/examples/SchedulerManagement.java) | Workflow scheduling | `./gradlew :examples:run -PmainClass=io.orkes.conductor.sdk.examples.SchedulerManagement` | ## Documentation | Document | Description | |----------|-------------| | [Worker SDK](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/worker_sdk.md) | Complete worker framework guide | | [Workflow SDK](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/workflow_sdk.md) | Workflow-as-code documentation | | [Testing Framework](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/testing_framework.md) | Unit testing workflows and workers | | [Conductor Client](https://github.com/conductor-oss/java-sdk/blob/main/conductor-client/README.md) | HTTP client library documentation | | [Client Metrics](https://github.com/conductor-oss/java-sdk/blob/main/conductor-client-metrics/README.md) | Prometheus metrics collection | | [Spring Integration](https://github.com/conductor-oss/java-sdk/blob/main/conductor-client-spring/README.md) | Spring Boot auto-configuration | | [Examples](https://github.com/conductor-oss/java-sdk/blob/main/examples/README.md) | Complete examples catalog | ## Support - [Open an issue (SDK)](https://github.com/conductor-oss/conductor-java-sdk/issues) for SDK bugs, questions, and feature requests - [Open an issue (Conductor server)](https://github.com/conductor-oss/conductor/issues) for Conductor OSS server issues - [Join the Conductor Slack](https://join.slack.com/t/orkes-conductor/shared_invite/zt-2vdbx239s-Eacdyqya9giNLHfrCavfaA) for community discussion and help - [Orkes Community Forum](https://community.orkes.io/) for Q&A ## Frequently Asked Questions **Is this the same as Netflix Conductor?** Yes. Conductor OSS is the continuation of the original [Netflix Conductor](https://github.com/Netflix/conductor) repository after Netflix contributed the project to the open-source foundation. **Is this project actively maintained?** Yes. [Orkes](https://orkes.io) is the primary maintainer and offers an enterprise SaaS platform for Conductor across all major cloud providers. **Can Conductor scale to handle my workload?** Conductor was built at Netflix to handle massive scale and has been battle-tested in production environments processing millions of workflows. It scales horizontally to meet virtually any demand. **Does Conductor support durable code execution?** Yes. Conductor ensures workflows complete reliably even in the face of infrastructure failures, process crashes, or network issues. **Are workflows always asynchronous?** No. While Conductor excels at asynchronous orchestration, it also supports synchronous workflow execution when immediate results are required. **Do I need to use a Conductor-specific framework?** No. Conductor is language and framework agnostic. Use your preferred language and framework -- the [SDKs](https://github.com/conductor-oss/conductor#conductor-sdks) provide native integration for Python, Java, JavaScript, Go, C#, and more. **Can I mix workers written in different languages?** Yes. A single workflow can have workers written in Python, Java, Go, or any other supported language. Workers communicate through the Conductor server, not directly with each other. **What Java versions are supported?** Java 17 and above. **Should I use Worker interface or @WorkerTask annotation?** Use `@WorkerTask` annotation for simpler, cleaner code -- input parameters are automatically mapped and return values become task output. Use the `Worker` interface when you need full control over task execution, access to task metadata, or custom error handling. **How do I run workers in production?** Workers are standard Java applications. Deploy them as you would any Java application -- in containers, VMs, or bare metal. Workers poll the Conductor server for tasks, so no inbound ports need to be opened. **How do I test workflows without running a full Conductor server?** The SDK provides a test framework that uses Conductor's `POST /api/workflow/test` endpoint to evaluate workflows with mock task outputs. See [Testing Framework](https://github.com/conductor-oss/java-sdk/blob/main/java-sdk/testing_framework.md) for details. ## License Apache 2.0 ## Examples Browse all examples on GitHub: [conductor-oss/java-sdk/examples](https://github.com/conductor-oss/java-sdk/tree/main/examples) | Example | Type | |---|---| | [Readme](https://github.com/conductor-oss/java-sdk/blob/main/examples/README.md) | file | | [Examples](https://github.com/conductor-oss/java-sdk/tree/main/examples) | directory |