HornetQ 2.2.14 to JBoss AS 7 Bridge
renevanwijk Nov 27, 2012 9:05 AMWe are trying to set-up a JMS bridge between a stand-alone HornetQ Server and JBoss AS7.
Just following an example that is present in the ${HORNETQ_HOME}/examples directory. The following hornetq-beans.xml is used
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<bean name="Naming" class="org.jnp.server.NamingBeanImpl"/>
<!-- JNDI server. Disable this if you don't want JNDI -->
<bean name="JNDIServer" class="org.jnp.server.Main">
<property name="namingInfo">
<inject bean="Naming"/>
</property>
<property name="port">${jnp.port:1099}</property>
<property name="bindAddress">${jnp.host:middleware-magic.com}</property>
<property name="rmiPort">${jnp.rmiPort:1098}</property>
<property name="rmiBindAddress">${jnp.host:middleware-magic.com}</property>
</bean>
<!-- MBean server -->
<bean name="MBeanServer" class="javax.management.MBeanServer">
<constructor factoryClass="java.lang.management.ManagementFactory"
factoryMethod="getPlatformMBeanServer"/>
</bean>
<!-- The core configuration -->
<bean name="Configuration" class="org.hornetq.core.config.impl.FileConfiguration">
</bean>
<!-- The security manager -->
<bean name="HornetQSecurityManager" class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl">
<start ignored="true"/>
<stop ignored="true"/>
</bean>
<!-- The core server -->
<bean name="HornetQServer" class="org.hornetq.core.server.impl.HornetQServerImpl">
<constructor>
<parameter>
<inject bean="Configuration"/>
</parameter>
<parameter>
<inject bean="MBeanServer"/>
</parameter>
<parameter>
<inject bean="HornetQSecurityManager"/>
</parameter>
</constructor>
<start ignored="true"/>
<stop ignored="true"/>
</bean>
<!-- The JMS server -->
<bean name="JMSServerManager" class="org.hornetq.jms.server.impl.JMSServerManagerImpl">
<constructor>
<parameter>
<inject bean="HornetQServer"/>
</parameter>
</constructor>
</bean>
<!-- The JMS Bridge -->
<bean name="JMSBridge" class="org.hornetq.jms.bridge.impl.JMSBridgeImpl">
<constructor>
<!-- Source ConnectionFactory -->
<parameter>
<inject bean="SourceConnectionFactory"/>
</parameter>
<!-- Target ConnectionFactory -->
<parameter>
<inject bean="TargetConnectionFactory"/>
</parameter>
<!-- Source Destination -->
<parameter>
<inject bean="SourceDestination"/>
</parameter>
<!-- Target Destination -->
<parameter>
<inject bean="TargetDestination"/>
</parameter>
<!-- Source username -->
<parameter>guest</parameter>
<!-- Source password -->
<parameter>guest</parameter>
<!-- Target username -->
<parameter>employee</parameter>
<!-- Target password -->
<parameter>welcome1</parameter>
<!-- Selector -->
<parameter><null /></parameter>
<!-- Interval to retry in case of failure (in ms) -->
<parameter>5000</parameter>
<!-- Maximum number of retries to connect to the source and target -->
<parameter>10</parameter>
<!-- Quality of service -->
<parameter>ONCE_AND_ONLY_ONCE</parameter>
<!-- Maximum batch size -->
<parameter>1</parameter>
<!-- Maximum batch time (-1 means infinite) -->
<parameter>-1</parameter>
<!-- Subscription name (no subscription name here)-->
<parameter><null /></parameter>
<!-- client ID (no client ID here)-->
<parameter><null /></parameter>
<!-- concatenate JMS messageID to the target's message header -->
<parameter>true</parameter>
<!-- register the JMS Bridge in the JMX MBeanServer -->
<parameter>
<inject bean="MBeanServer"/>
</parameter>
<parameter>org.hornetq:service=JMSBridge</parameter>
</constructor>
<property name="transactionManager">
<inject bean="TransactionManager"/>
</property>
<!-- HornetQ JMS Server must be started before the bridge -->
<depends>JMSServerManager</depends>
</bean>
<bean name="TransactionManager" class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"></bean>
<!-- The ConnectionFactory used to connect to the source destination -->
<bean name="SourceConnectionFactory" class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">
<constructor>
<parameter>
<inject bean="SourceJNDI" />
</parameter>
<parameter>jms/SomeConnectionFactory</parameter>
</constructor>
</bean>
<!-- The ConnectionFactory used to connect to the target destination -->
<bean name="TargetConnectionFactory" class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">
<constructor>
<parameter>
<inject bean="TargetJNDI" />
</parameter>
<parameter>jms/RemoteConnectionFactory</parameter>
</constructor>
</bean>
<!-- The Destination used as the source -->
<bean name="SourceDestination" class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">
<constructor>
<parameter>
<inject bean="SourceJNDI" />
</parameter>
<parameter>jms/queue/SomeQueue</parameter>
</constructor>
</bean>
<!-- The Destination used as the target -->
<bean name="TargetDestination" class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">
<constructor>
<parameter>
<inject bean="TargetJNDI" />
</parameter>
<parameter>jms/queue/test</parameter>
</constructor>
</bean>
<!-- JNDI is a Hashtable containing the JNDI properties required to connect to the *source* JMS resources -->
<bean name="SourceJNDI" class="java.util.Hashtable">
<constructor class="java.util.Map">
<map class="java.util.Hashtable" keyClass="java.lang.String" valueClass="java.lang.String">
<entry>
<key>java.naming.factory.initial</key>
<value>org.jnp.interfaces.NamingContextFactory</value>
</entry>
<entry>
<key>java.naming.provider.url</key>
<value>jnp://192.168.1.150:1099</value>
</entry>
<entry>
<key>java.naming.factory.url.pkgs</key>
<value>org.jboss.naming:org.jnp.interfaces"</value>
</entry>
<entry>
<key>jnp.timeout</key>
<value>5000</value>
</entry>
<entry>
<key>jnp.sotimeout</key>
<value>5000</value>
</entry>
</map>
</constructor>
</bean>
<!-- JNDI is a Hashtable containing the JNDI properties required to connect to the *target* JMS resources -->
<bean name="TargetJNDI" class="java.util.Hashtable">
<constructor class="java.util.Map">
<map class="java.util.Hashtable" keyClass="java.lang.String" valueClass="java.lang.String">
<entry>
<key>java.naming.factory.initial</key>
<value>org.jboss.naming.remote.client.InitialContextFactory</value>
</entry>
<entry>
<key>java.naming.provider.url</key>
<value>remote://192.168.1.150:4447</value>
</entry>
<entry>
<key>java.naming.security.principal</key>
<value>employee</value>
</entry>
<entry>
<key>java.naming.security.credentials</key>
<value>welcome1</value>
</entry>
</map>
</constructor>
</bean>
</deployment>
The problem here is to set-up the right JNDI connection to JBoss AS7. Programmatically one would proceed as
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.put(Context.PROVIDER_URL, "remote://192.168.1.150:4447");
properties.put(Context.SECURITY_PRINCIPAL, "employee");
properties.put(Context.SECURITY_CREDENTIALS, "welcome1");
ConnectionFactory connectionFactory = null;
Destination destination = null;
try {
Context context = new InitialContext(properties);
connectionFactory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
destination = (Destination) context.lookup("jms/queue/test");
System.out.println(connectionFactory);
System.out.println(destination);
sendMessage(connectionFactory, destination);
} catch (NamingException e) {
e.printStackTrace();
}
With the jboss-client*.jar in the classpath, this is working fine (a connection factory and destination are looked-up and messages can be send).
When using the HornetQ bean configuration, the following error is observed:
[jboss@middleware-magic bin]$ ./run.sh
***********************************************************************************
java -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M -Dhornetq.config.dir=../config/stand-alone/non-clustered -Djava.util.logging.config.file=../config/stand-alone/non-clustered/logging.properties -Djava.library.path=. -classpath ../lib/twitter4j-core.jar:../lib/netty.jar:../lib/log4j.jar:../lib/jnpserver.jar:../lib/jnp-client.jar:../lib/jbossts-common.jar:../lib/jboss-mc.jar:../lib/jbossjta.jar:../lib/jboss-jms-api.jar:../lib/jboss-javaee.jar:../lib/jboss-client-7.1.0.Final.jar:../lib/hornetq-twitter-integration.jar:../lib/hornetq-spring-integration.jar:../lib/hornetq-logging.jar:../lib/hornetq-jms.jar:../lib/hornetq-jms-client-java5.jar:../lib/hornetq-jms-client.jar:../lib/hornetq-jboss-as-integration.jar:../lib/hornetq-core.jar:../lib/hornetq-core-client-java5.jar:../lib/hornetq-core-client.jar:../lib/hornetq-bootstrap.jar:../lib/commons-logging.jar:../config/stand-alone/non-clustered:../schemas/ org.hornetq.integration.bootstrap.HornetQBootstrapServer hornetq-beans.xml
***********************************************************************************
* [main] 27-Nov 14:46:52,395 INFO [HornetQBootstrapServer] Starting HornetQ Server
* [main] 27-Nov 14:46:53,216 INFO [HornetQServerImpl] live server is starting with configuration HornetQ Configuration (clustered=false,backup=false,sharedStore=true,journalDirectory=../data/journal,bindingsDirectory=../data/bindings,largeMessagesDirectory=../data/large-messages,pagingDirectory=../data/paging)
* [main] 27-Nov 14:46:53,217 INFO [HornetQServerImpl] Waiting to obtain live lock
* [main] 27-Nov 14:46:53,238 INFO [JournalStorageManager] Using AIO Journal
* [main] 27-Nov 14:46:53,250 WARNING [HornetQServerImpl] Security risk! It has been detected that the cluster admin user and password have not been changed from the installation default. Please see the HornetQ user guide, cluster chapter, for instructions on how to do this.
* [main] 27-Nov 14:46:53,447 INFO [AIOFileLockNodeManager] Waiting to obtain live lock
* [main] 27-Nov 14:46:53,447 INFO [AIOFileLockNodeManager] Live Server Obtained live lock
* [main] 27-Nov 14:46:55,840 INFO [HornetQServerImpl] trying to deploy queue jms.queue.DLQ
* [main] 27-Nov 14:46:55,859 INFO [HornetQServerImpl] trying to deploy queue jms.queue.ExpiryQueue
* [main] 27-Nov 14:46:55,865 INFO [HornetQServerImpl] trying to deploy queue jms.queue.SomeQueue
* [main] 27-Nov 14:46:55,976 INFO [NettyAcceptor] Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4455 for CORE protocol
* [main] 27-Nov 14:46:55,977 INFO [NettyAcceptor] Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4445 for CORE protocol
* [main] 27-Nov 14:46:55,979 INFO [HornetQServerImpl] Server is now live
* [main] 27-Nov 14:46:55,979 INFO [HornetQServerImpl] HornetQ Server version 2.2.11.Final (HQ_2_2_11_FINAL_AS7, 122) [0ba4fa8d-3895-11e2-a23c-01d224a63402]) started
log4j:WARN No appenders could be found for logger (com.arjuna.ats.jta.logging.logger).
log4j:WARN Please initialize the log4j system properly.
* [main] 27-Nov 14:46:56,128 WARNING [JMSBridgeImpl] Failed to connect bridge
javax.naming.NamingException: Failed to create remoting connection [Root exception is java.util.ServiceConfigurationError: org.xnio.XnioProvider: Provider org.xnio.nio.NioXnioProvider could not be instantiated: java.lang.NoSuchMethodError: org.jboss.logging.Logger.tracef(Ljava/lang/String;Ljava/lang/Object;)V]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:117)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at org.hornetq.jms.bridge.impl.JNDIFactorySupport.createObject(JNDIFactorySupport.java:55)
at org.hornetq.jms.bridge.impl.JNDIDestinationFactory.createDestination(JNDIDestinationFactory.java:40)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl.setupJMSObjects(JMSBridgeImpl.java:1085)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl.start(JMSBridgeImpl.java:348)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:59)
at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:150)
at org.jboss.joinpoint.plugins.BasicMethodJoinPoint.dispatch(BasicMethodJoinPoint.java:66)
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction$JoinpointDispatchWrapper.execute(KernelControllerContextAction.java:241)
at org.jboss.kernel.plugins.dependency.ExecutionWrapper.execute(ExecutionWrapper.java:47)
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerContextAction.java:109)
at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchJoinPoint(KernelControllerContextAction.java:70)
at org.jboss.kernel.plugins.dependency.LifecycleAction.installActionInternal(LifecycleAction.java:221)
at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:54)
at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:42)
at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:774)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:540)
at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deployBean(AbstractKernelDeployer.java:319)
at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deployBeans(AbstractKernelDeployer.java:297)
at org.jboss.kernel.plugins.deployment.AbstractKernelDeployer.deploy(AbstractKernelDeployer.java:130)
at org.jboss.kernel.plugins.deployment.xml.BeanXMLDeployer.deploy(BeanXMLDeployer.java:96)
at org.hornetq.integration.bootstrap.HornetQBootstrapServer.deploy(HornetQBootstrapServer.java:236)
at org.hornetq.integration.bootstrap.HornetQBootstrapServer.deploy(HornetQBootstrapServer.java:206)
at org.hornetq.integration.bootstrap.HornetQBootstrapServer.bootstrap(HornetQBootstrapServer.java:155)
at org.jboss.kernel.plugins.bootstrap.AbstractBootstrap.run(AbstractBootstrap.java:83)
at org.hornetq.integration.bootstrap.HornetQBootstrapServer.run(HornetQBootstrapServer.java:116)
at org.hornetq.integration.bootstrap.HornetQBootstrapServer.main(HornetQBootstrapServer.java:73)
* [main] 27-Nov 14:46:56,129 WARNING [JMSBridgeImpl] Failed to start bridge
* [pool-3-thread-1] 27-Nov 14:46:56,130 WARNING [JMSBridgeImpl] Will retry after a pause of 5000 ms
* [pool-3-thread-1] 27-Nov 14:47:1,149 WARNING [JMSBridgeImpl] Failed to connect bridge
javax.naming.NamingException: Failed to create remoting connection [Root exception is java.util.ServiceConfigurationError: org.xnio.XnioProvider: Provider org.xnio.nio.NioXnioProvider could not be instantiated: java.lang.NoClassDefFoundError: Could not initialize class org.xnio.nio.NioXnioProvider]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:117)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at org.hornetq.jms.bridge.impl.JNDIFactorySupport.createObject(JNDIFactorySupport.java:55)
at org.hornetq.jms.bridge.impl.JNDIDestinationFactory.createDestination(JNDIDestinationFactory.java:40)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl.setupJMSObjects(JMSBridgeImpl.java:1085)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl.setupJMSObjectsWithRetry(JMSBridgeImpl.java:1341)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl.access$2100(JMSBridgeImpl.java:71)
at org.hornetq.jms.bridge.impl.JMSBridgeImpl$FailureHandler.run(JMSBridgeImpl.java:1864)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
* [pool-3-thread-1] 27-Nov 14:47:1,150 INFO [JMSBridgeImpl] Failed to set up JMS bridge connections. Most probably the source or target servers are unavailable. Will retry after a pause of 5000 ms
^C* [hornetq-shutdown-thread] 27-Nov 14:47:5,843 INFO [HornetQBootstrapServer] Stopping HornetQ Server...
Probably some classloading issue (java.lang.NoSuchMethodError: org.jboss.logging.Logger.tracef(Ljava/lang/String;Ljava/lang/Object;)V]), but which class is interfering with which
-classpath ../lib/twitter4j-core.jar:../lib/netty.jar:../lib/log4j.jar:../lib/jnpserver.jar:../lib/jnp-client.jar:../lib/jbossts-common.jar:../lib/jboss-mc.jar:../lib/jbossjta.jar:../lib/jboss-jms-api.jar:../lib/jboss-javaee.jar:../lib/jboss-client-7.1.0.Final.jar:../lib/hornetq-twitter-integration.jar:../lib/hornetq-spring-integration.jar:../lib/hornetq-logging.jar:../lib/hornetq-jms.jar:../lib/hornetq-jms-client-java5.jar:../lib/hornetq-jms-client.jar:../lib/hornetq-jboss-as-integration.jar:../lib/hornetq-core.jar:../lib/hornetq-core-client-java5.jar:../lib/hornetq-core-client.jar:../lib/hornetq-bootstrap.jar:../lib/commons-logging.jar:
Another thing; I presume it is not possible to use jnp with JBoss AS7 (that is why remoting is used above).
Maybe it is easier to use hornetq core bridge (instead of a jms bridge):
<bridges>
<bridge name="my-bridge">
<queue-name>jms.queue.sausage-factory</queue-name>
<forwarding-address>jms.queue.mincing-machine</forwarding-address>
<filter string="name='aardvark'"/>
<transformer-class-name>org.hornetq.jms.example.HatColourChangeTransformer</transformer-class-name>
<reconnect-attempts>-1</reconnect-attempts>
<static-connectors>
<connector-ref>remote-connector</connector-ref>
</static-connectors>
</bridge>
</bridges>
but my problem here is, how does the forward-address work. Also how do you provide a connection factory and queue (or topic) or does hornetq retrieve this kind of information automatically?