Chapter 43. Embedding HornetQ

HornetQ is designed as set of simple Plain Old Java Objects (POJOs). This means HornetQ can be instantiated and run in any dependency injection framework such as JBoss Microcontainer, Spring or Google Guice. It also means that if you have an application that could use messaging functionality internally, then it can directly instantiate HornetQ clients and servers in its own application code to perform that functionality. We call this embedding HornetQ.

Examples of applications that might want to do this include any application that needs very high performance, transactional, persistent messaging but doesn't want the hassle of writing it all from scratch.

Embedding HornetQ can be done in very few easy steps. Instantiate the configuration object, instantiate the server, start it, and you have a HornetQ running in your virtual machine. It's as simple and easy as that.

43.1. POJO instantiation

You can follow this step-by-step guide:

Create the configuration object - this contains configuration information for a HornetQ. If you want to configure it from a file on the classpath, use FileConfigurationImpl

import org.hornetq.core.config.Configuration;
import org.hornetq.core.config.impl.FileConfiguration;

...


Configuration config = new FileConfiguration();
config.setConfigurationUrl(urlToYourconfigfile);
config.start();

If you don't need to support a configuration file, just use ConfigurationImpl and change the config parameters accordingly, such as adding acceptors.

The acceptors are configured through ConfigurationImpl. Just add the NettyAcceptorFactory on the transports the same way you would through the main configuration file.

import org.hornetq.core.config.Configuration;
import org.hornetq.core.config.impl.ConfigurationImpl;

...

Configuration config = new ConfigurationImpl();
HashSet<TransportConfiguration> transports = new HashSet<TransportConfiguration>();
      
transports.add(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
transports.add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));

config.setAcceptorConfigurations(transports);

You need to instantiate and start HornetQ server. The class org.hornetq.api.core.server.HornetQ has a few static methods for creating servers with common configurations.

import org.hornetq.api.core.server.HornetQ;
import org.hornetq.core.server.HornetQServer;

...

HornetQServer server = HornetQ.newHornetQServer(config);

server.start();

You also have the option of instantiating HornetQServerImpl directly:

HornetQServer server = 
        new HornetQServerImpl(config);
server.start();

43.2. Dependency Frameworks

You may also choose to use a dependency injection framework such as JBoss Micro Container™ or Spring Framework™.

HornetQ standalone uses JBoss Micro Container as the injection framework. HornetQBootstrapServer and hornetq-beans.xml which are part of the HornetQ distribution provide a very complete implementation of what's needed to bootstrap the server using JBoss Micro Container.

When using JBoss Micro Container, you need to provide an XML file declaring the HornetQServer and Configuration object, you can also inject a security manager and a MBean server if you want, but those are optional.

A very basic XML Bean declaration for the JBoss Micro Container would be:

<?xml version="1.0" encoding="UTF-8"?>

<deployment xmlns="urn:jboss:bean-deployer:2.0">
   
   <!-- The core configuration -->
   <bean name="Configuration" 
         class="org.hornetq.core.config.impl.FileConfiguration">
   </bean>

   	<!-- The core server -->
   <bean name="HornetQServer" 
         class="org.hornetq.core.server.impl.HornetQServerImpl">      
      <constructor>
         <parameter>
            <inject bean="Configuration"/>
         </parameter>            
      </constructor>         
   </bean>
   </deployment>

HornetQBootstrapServer provides an easy encapsulation of JBoss Micro Container.

HornetQBootstrapServer bootStrap = 
        new HornetQBootstrapServer(new String[] {"hornetq-beans.xml"});
        bootStrap.run();

43.3. Connecting to the Embedded HornetQ

To connect clients to HornetQ you just create the factories as normal:

43.3.1. Core API

If using the core API, just create the ClientSessionFactory and use the regular core API.

ClientSessionFactory nettyFactory =  HornetQClient.createClientSessionFactory(
                                        new TransportConfiguration(
                                           InVMConnectorFactory.class.getName()));

ClientSession session = factory.createSession();

session.createQueue("example", "example", true);

ClientProducer producer = session.createProducer("example");

ClientMessage message = session.createMessage(true);

message.getBody().writeString("Hello");

producer.send(message);

session.start();

ClientConsumer consumer = session.createConsumer("example");

ClientMessage msgReceived = consumer.receive();

System.out.println("message = " + msgReceived.getBody().readString());

session.close();

43.3.2. JMS API

Connection on an Embedded HornetQ through JMS is also simple. Just instantiate ConnectionFactory directly. The following example illustrates that.

ConnectionFactory cf =
    HornetQJMSClient.createConnectionFactory(
       new TransportConfiguration(InVMConnectorFactory.class.getName()));

Connection conn = cf.createConnection();

conn.start();

Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);

MessageProducer prod = sess.createProducer(queue);

TextMessage msg = sess.createTextMessage("Hello!");

prod.send(msg);

sess.commit();

MessageConsumer consumer = sess.createConsumer(queue);

TextMessage txtmsg = (TextMessage)consumer.receive();

System.out.println("Msg = " + txtmsg.getText());

sess.commit();

conn.close();

43.4. JMS Embedding Example

Please see Section 11.2.1, “Embedded” for an example which shows how to setup and run HornetQ embedded with JMS.