AceMQ for Java

A messaging library for RabbitMQ built on one idea: a message should never disappear quietly.

Every default here is the safe one. Publishes wait for the broker to confirm them. A message nothing is bound to receive is an error, not a shrug. A handler that fails gets retried on a schedule the broker enforces, and if it never succeeds the message ends up somewhere you can find it and put it back. None of that is opt-in.

try (AceMq mq = AceMq.connect("amqp://localhost")) {
    mq.declareExchange("orders", "topic");
    mq.declareQueue("orders.new");
    mq.bind("orders.new", "orders", "order.*");

    mq.publisher("orders", "order.placed", Order.class)
      .send(new Order("o-1", 42.00));

    mq.consume("orders.new", Order.class, message -> process(message.payload()));
}

That is the whole thing: connect, declare, publish, consume. JSON serialization, publisher confirms, acknowledgement after the handler returns, and connection recovery are already on.

Start here

Getting started Install it and send your first message
Publishing Confirms, unroutable messages, delivery options
Consuming Prefetch, acknowledgement, concurrency
The envelope What travels with every message, the header contract, and the reserved namespace
Reliability Retries, dead letters, replay, idempotency
Topology Planning exchanges and queues, and catching drift before a deployment does
Patterns Idempotency, the transactional outbox, the schema registry
Serialization JSON, XML, YAML, TOML, Avro, Protobuf
Streams Append-only logs, offsets, replay
Request and reply Asking a question over a broker, and when not to
Security TLS, credentials, and what is not built yet
Observability Traces that cross the broker, metrics, and what to alert on
Testing An in-memory broker, no Docker needed
Compatibility What runs on RabbitMQ 3.13 as well as 4.x, and where the two brokers differ
Native image GraalVM ahead-of-time: what works, and the one thing you must configure
API reference Javadoc for every module
Licence and warranty Apache-2.0, what it disclaims, and where support comes from

What it is not

It is not a framework. There is no container, no annotations, no lifecycle to learn — the entry point is a class you construct and close.

It is not a broker abstraction that pretends every broker is the same. When a transport cannot do something, it says so and fails, rather than silently doing something close enough. A stream is not a queue with different settings, and this library will not let you treat it as one.

It is not finished. See what is missing below before you depend on it.

Status

Pre-1.0, and honest about it. What works today is tested against real RabbitMQ in CI on every commit: publishing with confirms, asynchronous publishing (sendAsync) and batch publishing (sendAll), consuming, the retry ladder, dead-letter and parking queues, replay, streams, pipelines, ordered consumption, the transactional outbox, idempotency (in-process and shared), request and reply, sagas, claim check, scheduling, payload encryption, topology drift detection, interceptors, GraalVM native image, and six serialization formats.

A Spring Boot starter ships separately, at acemq-java-amqp-spring-boot-starter, on its own version line because it tracks Spring Boot's release train as much as this one.

RabbitMQ 3.13 is supported as well as 4.x. The whole integration suite passes on both, a CI job re-runs it against 3.13 on every pull request, and compatibility records what was run and where the two brokers differ. Nothing here needs 4.x.

Coordinates and API shape may still move before 1.0, which is why artifacts are not yet on Maven Central.