River’s Java client inserts and works jobs using Postgres or SQLite. It shares the River schema with Go, Ruby, Rust, and TypeScript, so applications can enqueue jobs for workers in any of those languages.
Use Java 21 or newer. The client is available without credentials from https://riverqueue.com/maven; see the getting-started guide for Maven and Gradle setup. Source is in river/java, with a Java API guide. The shared feature pages include Java examples.
Basic usage
Wrap your application’s JDBC DataSource, create an insert-only client, and give the job a stable kind with record arguments:
import com.riverqueue.Client;import com.riverqueue.Database;import com.riverqueue.JobType;import java.util.List;
var database = new Database(dataSource, Database.Dialect.POSTGRES);var producer = new Client(database);
record SortArgs(List<String> strings) {}
var sort = JobType.of("sort", SortArgs.class);var result = producer.insert(sort, new SortArgs(List.of("whale", "tiger", "bear")));Record properties use snake_case in JSON by default. Keep kinds and serialized field names consistent when another language inserts or works the same jobs.
Working jobs
Register a lambda or method reference on the client builder, configure queue concurrency, and start the client:
var client = Client.builder(database) .queue("default", 10) .worker(sort, context -> { System.out.println(context.args().strings().stream().sorted().toList()); }) .build();var run = client.start();
// Later, during application shutdown:run.stop();Run migrations first. Each active job runs on a virtual thread; keep the returned RunHandle open while the application is running and stop it before closing the connection pool. RunHandle implements AutoCloseable. See graceful shutdown.
Inserting in a transaction
Pass an open JDBC transaction as the first argument to insert, or let River manage the transaction:
client.transaction(connection -> { // Make related application changes through connection. client.insert(connection, sort, new SortArgs(List.of("whale", "tiger", "bear"))); return null;});The helper commits on return and rolls back on failure. When you pass your own transaction, River does not commit or close it.