Get started with Java
Run a worker with configuration and business stages, then submit and inspect a typed pipeline.
Build an orders worker and a separate producer with one SDK dependency. They are separate processes in the example and should remain separate services in a real system. The worker stays online and executes stages; the producer submits work without hosting handlers. The demonstration records recorded=true; it does not write to a database or charge a customer.
Download the runnable Java demo. It includes the files below plus independent-producer, retry and schedule recipes. The matching SDK source supplies the local packages used by every example on these pages.
Before you start
You need JDK 17 or 21, a running Pipelogiq API and an application API key. Use that application's key in both terminals. These instructions use macOS/Linux; Windows command equivalents are included below.
No Spring, broker URL or model provider is needed for the first run. HTTP is the default transport. Java package names start with io.pipelogiq.sdk; the Maven group is com.pipelogiq.
Install the current SDK from source
Extract the matching source archive, open its root directory containing mvnw and pom.xml, and run:
export PIPELOGIQ_SDK_DIR="$PWD"
chmod +x mvnw
./mvnw -B -pl sdk-runtime -am install -DskipTestsThis builds the recommended pipelogiq-sdk artifact and its dependencies into your local Maven repository. It does not publish anything. The wrapper downloads Maven automatically. This guide deliberately works without assuming version 0.5.0 has already been published to Maven Central.
Then extract the Java demo and open pipelogiq-java-demo. Alternatively, create the following files yourself. The SDK path variable must remain the absolute path to the SDK source root, not the demo directory.
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>pipelogiq-java-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.pipelogiq</groupId>
<artifactId>pipelogiq-sdk</artifactId>
<version>0.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.16.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>
</project>pipelogiq.yml in the demo's root directory:
pipelogiq:
api-url: ${PIPELOGIQ_API_URL:http://localhost:8081}
api-key: ${PIPELOGIQ_API_KEY}
worker-name: orders-java
environment: development
transport: ${PIPELOGIQ_TRANSPORT:http}
max-concurrency: 4Write the worker and client
Create src/main/java/example/ and put each public type in its own file. These five files are included in the download. The download also contains a separate inspection and testing CLI.
Order.java
package example;
import java.math.BigDecimal;
public record Order(String orderId, BigDecimal amount) {}ValidateOrder.java
package example;
import io.pipelogiq.sdk.core.execution.*;
@Stage("ValidateOrder")
public final class ValidateOrder implements StageHandler<Order> {
@Override
public StageResult execute(Order order, StageContext context) {
context.throwIfCancelled();
if (order.orderId() == null || order.orderId().isBlank()) {
return StageResult.validationError("Order ID is required");
}
if (order.amount() == null || order.amount().signum() <= 0) {
return StageResult.validationError("Amount must be positive");
}
context.put("validatedOrder", order);
context.logInfo("Order validated");
return StageResult.success();
}
}RecordOrder.java
package example;
import io.pipelogiq.sdk.core.execution.*;
@Stage("RecordOrder")
public final class RecordOrder implements NoInputStageHandler {
@Override
public StageResult execute(StageContext context) {
Order order = context.require("validatedOrder", Order.class);
context.put("recorded", true);
return StageResult.success("Recorded demo order " + order.orderId());
}
}@Stage supplies a stable wire name. The SDK infers the input type from StageHandler<Order>; NoInputStageHandler reads required context without a dummy input argument. context.require classifies missing or incompatible data for you.
OrdersExample.java
package example;
import io.pipelogiq.sdk.Pipelogiq;
/** Run from the examples directory; the SDK owns startup, readiness and SIGTERM shutdown. */
public final class OrdersExample {
public static void main(String[] args) {
Pipelogiq.worker().config("pipelogiq.yml").stages(ValidateOrder.class, RecordOrder.class).run();
}
}The SDK owns client creation, transport selection, registration, readiness, leases, input conversion, result delivery and shutdown. Deploy this entry point as its own continuously running service. Worker startup does not submit a pipeline.
CreateOrder.java
package example;
import io.pipelogiq.sdk.Pipelogiq;
import java.math.BigDecimal;
import java.time.Duration;
/** Run with OrdersExample (or SpringOrdersApplication) already listening. */
public final class CreateOrder {
public static void main(String[] args) {
try (var client = Pipelogiq.connect("pipelogiq.yml")) {
var created = client.pipeline("Process order")
.idempotencyKey("demo-order-intro-123")
.stage(ValidateOrder.class, new Order("intro-123", new BigDecimal("42.50")))
.stage(RecordOrder.class)
.send();
var completed = client.pipelines()
.waitForCompletion(created.id(), Duration.ofSeconds(60));
System.out.println("Pipeline " + completed.id() + ": " + completed.status());
System.out.println("Recorded: " + completed.context("recorded", Boolean.class));
}
}
}The producer owns one typed client for its operation. Pipeline drafts do not open separate connections and do not need their own close(). There is no application polling loop: waitForCompletion is bounded by the timeout supplied to it.
Build and start the worker
From pipelogiq-java-demo, build once:
"$PIPELOGIQ_SDK_DIR/mvnw" -q compile dependency:copy-dependencies
export PIPELOGIQ_API_URL='http://localhost:8081'
export PIPELOGIQ_API_KEY='your-application-api-key'
java -cp 'target/classes:target/dependency/*' example.OrdersExampleKeep this terminal running. It represents the independently deployed worker service. After successful bootstrap, the dashboard shows worker orders-java online in the application associated with your API key. The example does not promise a particular console readiness message.
For Windows PowerShell, install the SDK with .\mvnw.cmd -B -pl sdk-runtime -am install -DskipTests from its root, save that absolute path in $env:PIPELOGIQ_SDK_DIR, then use these commands from the demo root:
& "$env:PIPELOGIQ_SDK_DIR\mvnw.cmd" -q compile dependency:copy-dependencies
$env:PIPELOGIQ_API_URL = "http://localhost:8081"
$env:PIPELOGIQ_API_KEY = "your-application-api-key"
java -cp 'target/classes;target/dependency/*' example.OrdersExampleOther commands on these pages use the macOS/Linux : classpath separator. Use ; on Windows. In a new terminal, export the API settings again. Set PIPELOGIQ_SDK_DIR again only if you need another build.
Submit and observe
In a second terminal, open the same demo directory, set the same API variables, and run the small producer. In production this code normally lives in an API service, scheduled job or another application; it never starts the worker:
java -cp 'target/classes:target/dependency/*' example.CreateOrderIt submits the order and waits up to 60 seconds. Expect:
Pipeline <id>: COMPLETED
Recorded: trueOpen that pipeline in the dashboard to inspect both completed stages, logs and context. Running CreateOrder again reuses its fixed demo-order-intro-123 idempotency key and returns the existing pipeline. Change the business ID and key together for a deliberately new order.
Use the optional inspection CLI
The downloadable project also includes CreatePipelineExample, a utility for submitting different orders, inspecting status, and exercising failures and idempotency. It is not required by the five-file application above. If you created those files manually, obtain this optional utility from the demo download before running these commands:
java -cp 'target/classes:target/dependency/*' example.CreatePipelineExample submit order-001 42.50It prints Pipeline ID: <id>. Replace 123 below with that ID:
java -cp 'target/classes:target/dependency/*' example.CreatePipelineExample get 123
java -cp 'target/classes:target/dependency/*' example.CreatePipelineExample wait 123 60get reads a snapshot, which may still be pending or running. wait prints COMPLETED, Recorded: true and the statuses of ValidateOrder and RecordOrder. This utility uses demo-order-<orderId> as its idempotency key; choose a fresh order ID for a new request.
Try the two expected-behavior checks:
java -cp 'target/classes:target/dependency/*' example.CreatePipelineExample validate-failure rejected-001
java -cp 'target/classes:target/dependency/*' example.CreatePipelineExample idempotency repeated-001The first prints a FAILED pipeline with VALIDATION_ERROR and Recorded: false. The second prints equal IDs and Same pipeline: true, then observes completion. A local wait timeout does not cancel server work; inspect or wait again using the same ID.
Press Ctrl+C in the worker terminal to stop gracefully. To repeat the experiment over AMQP, set PIPELOGIQ_TRANSPORT=amqp before starting the worker and use a new order ID. Broker settings come from server bootstrap; see configuration.
If the first run does not complete
| Symptom | First check |
|---|---|
| Dependency cannot be resolved | Install the matching source into the same local Maven repository. |
| Missing API key | Export the key in each terminal or service environment. |
| Configuration file not found | Run from the demo root containing pipelogiq.yml. |
| Readiness failure | Verify API URL, authentication and transport reachability. |
| Pipeline stays pending | Keep a worker online with the same application key and matching stage names. |
| Previous result appears again | Reusing an order ID reuses its idempotency key. |
Continue with workflow recipes, schedules, Spring Boot or agent testing. The troubleshooting guide covers failure diagnosis in more detail.