Runtime setup
This page starts after Ratchet is on your classpath and its database schema is available. For Maven coordinates, module selection, and released-version guidance, use the canonical Installation guide. Keeping dependency setup in one place prevents the two deployment paths from drifting apart.
Prerequisites
- Java 17 or later
- A Jakarta EE 10 or 11 runtime with CDI, Persistence, Interceptors, and Jakarta Concurrency
- One supported store: MySQL 8+, PostgreSQL 14+, Oracle 23ai+, SQL Server 2022+, or MongoDB 6+
- The selected store's resources and schema, as described in Database setup
1. Enable CDI discovery
Ratchet's beans use annotated discovery. CDI 4 normally discovers them without a descriptor. If your deployment uses beans.xml, keep discovery mode at annotated or all:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0"
bean-discovery-mode="annotated">
</beans>Place the descriptor in WEB-INF/beans.xml for a WAR or META-INF/beans.xml for a bean archive.
2. Produce RatchetOptions
Every running Ratchet deployment must produce exactly one unqualified, application-scoped RatchetOptions bean. Without it, CDI fails deployment with UnsatisfiedResolutionException; Ratchet does not silently start with ambient defaults.
The smallest environment-driven producer is:
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import run.ratchet.api.RatchetOptions;
import run.ratchet.api.RatchetOptionsFactory;
@ApplicationScoped
public class RatchetConfiguration {
@Produces
@ApplicationScoped
RatchetOptions ratchetOptions() {
return RatchetOptionsFactory.fromEnvironment();
}
}Use the Configuration guide for a programmatic producer and the Configuration reference for every property, environment variable, and default.
3. Provide a ClassPolicy
Ratchet also refuses to start while the default ClassPolicy allowlist is empty. Jobs execute application methods reconstructed from durable payloads, so the allowlist is a required security boundary rather than optional hardening.
Install a CDI alternative that admits only your job-target packages:
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Alternative;
import jakarta.interceptor.Interceptor;
import run.ratchet.spi.ClassPolicy;
@Alternative
@Priority(Interceptor.Priority.APPLICATION)
@ApplicationScoped
public class ApplicationClassPolicy implements ClassPolicy {
@Override
public boolean isAllowed(String className) {
return className.startsWith("com.example.jobs.");
}
}Do not allow broad namespaces such as java., jakarta., or an entire organization's root package. Include each package that contains a scheduled target. Typed workflow-result deserialization uses the separate, narrower isAllowedForResultType check, which defaults to deny.
For demos and tests only, RatchetOptions.builder().security(s -> s.allowEmptyClassPolicy(true)).build() bypasses the startup guard. It does not make the default policy permissive: jobs remain rejected until a real allowlist is installed.
4. Configure store and concurrency resources
SQL stores need the selected Jakarta Persistence unit and datasource; MongoDB needs a MongoDatabase using UuidRepresentation.STANDARD. The database-specific pages cover provider and isolation requirements.
By default, Ratchet looks up the Jakarta Concurrency resources below:
| Purpose | Default JNDI name | Configuration key |
|---|---|---|
| Job execution | java:comp/DefaultManagedExecutorService | ratchet.worker.job-executor-jndi |
| Scheduled maintenance | java:comp/DefaultManagedScheduledExecutorService | ratchet.worker.scheduled-executor-jndi |
| Coordinator threads | java:comp/DefaultManagedThreadFactory | ratchet.coordinator.thread-factory-jndi |
Override these only when the application server binds managed resources under different names. Ratchet never creates unmanaged worker threads as a fallback.
5. Verify startup
Deploy the application and confirm all four stages appear without a ClassPolicy or CDI error:
INFO Ratchet starting
INFO Scheduler nodeId=...
INFO Poller initialized (batch=50)
INFO Ratchet startedThen submit one job and verify that its cold row exists:
scheduler.enqueueNow(() -> workService.runOnce());SELECT job_id, terminal_status, created_at
FROM scheduler_job
ORDER BY created_at DESC;Troubleshooting
RatchetOptionsis unsatisfied: add the producer above and ensure its method is@ApplicationScoped.ClassPolicy allowedPackages is empty: install the application alternative; do not use the demo escape hatch in production.JobSchedulerServiceis unsatisfied: verify CDI discovery and thatratchetis packaged with exactly one store implementation.- Managed executor lookup fails: compare the server's JNDI bindings with the three keys above.
- Store startup fails: follow the selected database page and verify schema, datasource, transaction isolation, and UUID mapping.