This module provides full bindings for the AMQP RabbitMQ Java library. It is based on Inline::Java and it exposes all of the classes and interfaces of the original library. You should refer to the original documentation in order to understand how to do the various AMQP tasks and to check the exact method signatures:

This distribution ships the RabbitMQ client library, so you don't need to download it yourself. The module version number represents the library version. If a newer library is available from the RabbitMQ team and this distribution wasn't updated, you can use it (see the CLASSPATH option below).

Don't be scared by the "Java" thing. Using this module is quite easy: if you have Inline::Java installed, it just works. To install Inline::Java you only need to have Java SDK installed in your system (no more difficult than a quick apt-get install openjdk-6-jdk, probably).

Yes. At the time of writing, CPAN offers incomplete or unmaintained modules. Some do not support recent AMQP specs such as 0-9-1, others do not support features like returned messages. This is not criticism, though. Writing and maintaining an AMQP module is probably not easy, given the complexity of the protocol, the variety of broker implementations and different spec versions, so I understand that it's difficult to develop and maintain a robust Perl implementation. I believe that an optimal solution would be a module with XS bindings to an AMQP C/C++ library. However, there seem to be no stable or widely-adopted C/C++ libraries, so I decided to build an interface to the Java client library developed by the RabbitMQ team, which appears to be the most actively maintained library.

This will load the Java code, start the background JVM and populate the Net::RabbitMQ::Java:: namespace with the loaded classes. If you want fine-grained configuration over Inline::Java behaviour, you can pass arguments to init:

Net::RabbitMQ::Java->init(JNI => 1);

So, if you want to use a custom client library JAR (instead of the one shipped with this module), just populate the CLASSPATH option:

See the client library original documentation to learn about method signatures. This module will take care of casting data types. You only need to take care of the number of arguments which must match what the library is expecting, even if you want to pass null values:

$channel->queueDeclare($name, 1, 0, 0, undef);

In Perl you could omit the last argument, but since we're talking to Java you must provide the exact number of arguments described in docs as it's needed to identify which signature are you calling the method with (for the non-Java-savvy people out there: this is why many methods are listed multiple times with different argument lists).

In order to provide you with a better interface to the underlying library, some methods are overloaded and augmented. Thus, for these methods you should combine the RabbitMQ client library docs with the following instructions:

This module provides some glue to use Perl code as callbacks for reacting to events thrown by the RabbitMQ client library. The library itself is multi-threading; however there's currently no way to share Java objects between multiple Perl threads, so your application will need to have one connection per Perl thread. Thus, your callbacks will be executed in a single-threaded environment as soon as you want. The Java library will catch the events in the background and will put them in a queue so that you can poll from Perl using the following command:

Net::RabbitMQ::Java->processCallbacks();

Note that this is a non-blocking call! It will execute any callbacks available in the internal queue. If there are no callbacks to execute, it will return immediately.

Each callback setter method returns a reference to the callback too, so you can process callbacks for individual listeners too:

If a message is published with the "mandatory" or "immediate" flags set, but cannot be delivered, the broker will return it to the sending client (via a AMQP.Basic.Return command). To be notified of such returns, clients can set up a callback using the following syntax:

Warning: if you call $cb->process() right after publishing a message with $channel->basicPublish(), you likely won't catch an eventual return as the server may take some time to send it (milliseconds or even seconds). So it's up to you to poll frequently for callbacks. You could use an event-driven environment such as POE or Reflex to schedule regular calls to $cb->process() or processCallbacks().

If you don't need a transaction, note that calling txSelect and txCommit add a significant server overhead due to disk processing and so on, but this lets you ensure that by calling $cb->process() immediately you will catch an eventual return. The reason for this relies in the wire traffic order enforced by the transaction commit: the server sends the tx.commit-ok response after having sent any basic.return frame, so when the txCommit() methods returns, the AMQP library has already processed the return frame and enqueued the callback. (I actually haven't checked whether this ordering is enforced by the AMQP specs or is just RabbitMQ's implementation.)

The first argument passed to the callback is ack or nack depending on the kind of event notified by the server (consult RabbitMQ docs for the semantics of these). Note that you will get a confirm for every single message published, so you should poll (i.e. call $cb->process() or processCallbacks) until you've got enough confirms:

The client library will fire a shutdown event whenever a connection or a channel is closed by the server or due to a communication failure (see the Core API Guide on RabbitMQ website linked above). To handle such events you can register a callback using the following syntax:

(Hint: use a module like Try::Tiny or TryCatch to catch your exceptions without surprises.)

Note that you should the isa() method instead of doing ref $@, because the resulting package name might have a different namespace than Net::RabbitMQ::Java::Client::. Otherwise you could use a regexp and omit the namespace:

An async mode would be useful to allow implementation with event-based frameworks such as POE and others. This requires a non-blocking behaviour of AMQP sync commands. It could be achieved by extending the current callback system: a method call like txCommit() should accept a coderef as last argument and return immediately; the Java client library should receive the tx.commit-ok response in a separate Java thread and enqueue the callback call.

This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

This distribution includes the RabbitMQ Java client library which is dual-licensed under the MPL and the GPL v2. It also includes the commons-io library which is licensed under the Apache Licence v2. If you have any questions or concerns regarding licensing, contact the distribution maintainer.