10 Replies Latest reply on Oct 19, 2012 8:17 AM by ataylor

    JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat

    gazal_ka

      Hi,

       

      I am embedding an in-vm hornetq instance in my web application using spring. My in-vm spring context file is as follows:

       

       

      {code:xml}

                <bean name="namingServer" class="org.jnp.server.Main" init-method="start"

                          destroy-method="stop">

                          <property name="namingInfo" ref="namingServerImpl" />

                          <property name="port" value="#{namingServerMap['port']}" />

                          <property name="bindAddress"

                                    value="#{T(java.net.InetAddress).getLocalHost().getHostName()}" />

                          <property name="rmiPort" value="#{namingServerMap['rmiPort']}" />

                          <property name="rmiBindAddress"

                                    value="#{T(java.net.InetAddress).getLocalHost().getHostName()}" />

                </bean>

       

       

                <bean name="namingServerImpl" class="org.jnp.server.NamingBeanImpl"

                          init-method="start" destroy-method="stop">

                          <property name="useGlobalService" value="false" />

                </bean>

       

       

                <bean name="connectionFactory" class="org.hornetq.jms.client.HornetQJMSConnectionFactory">

                          <constructor-arg value="false" />

                          <constructor-arg>

                                    <bean class="org.hornetq.api.core.TransportConfiguration">

                                              <constructor-arg

                                                        value="org.hornetq.core.remoting.impl.invm.InVMConnectorFactory" />

                                    </bean>

                          </constructor-arg>

                          <property name="connectionTTL" value="-1" />

                          <qualifier value="inVMConnectionFactory" />

                </bean>

       

       

                <bean name="jmsServerManagerImpl" class="org.hornetq.jms.server.impl.JMSServerManagerImpl"

                          init-method="start" destroy-method="stop" depends-on="namingServer">

                          <constructor-arg ref="hornetQServerImpl" />

                </bean>

       

       

                <bean name="hornetQSecurityManagerImpl"

                          class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl" />

       

       

                <bean name="remoteConnector" class="java.util.ArrayList">

                          <constructor-arg>

                                    <list>

                                              <value>remote-connector</value>

                                    </list>

                          </constructor-arg>

                </bean>

       

       

                <bean id="nettyConnector" class="org.hornetq.api.core.TransportConfiguration">

                          <constructor-arg

                                    value="org.hornetq.core.remoting.impl.netty.NettyConnectorFactory" />

                          <constructor-arg>

                                    <map key-type="java.lang.String" value-type="java.lang.Object">

                                              <entry key="host" value="${JMS_HOST}"></entry>

                                              <entry key="port" value="${JMS_CONNECTOR_PORT}"></entry>

                                    </map>

                          </constructor-arg>

                          <constructor-arg value="remote-connector" />

                </bean>

       

       

                <bean name="fileConfiguration" class="org.hornetq.core.config.impl.FileConfiguration"

                          init-method="start" destroy-method="stop">

                          <property name="connectorConfigurations">

                                    <map key-type="java.lang.String" value-type="org.hornetq.api.core.TransportConfiguration">

                                              <entry key="remote-connector" value-ref="nettyConnector" />

                                    </map>

                          </property>

                          <property name="bridgeConfigurations" ref="bridgeConfigurations" />

                </bean>

       

       

                <bean id="bridgeConfigurations" class="java.util.ArrayList" />

       

       

                <bean name="mbeanServer" class="java.lang.management.ManagementFactory"

                          factory-method="getPlatformMBeanServer" />

       

       

                <bean name="hornetQServerImpl" class="org.hornetq.core.server.impl.HornetQServerImpl">

                          <constructor-arg ref="fileConfiguration" />

                          <constructor-arg ref="mbeanServer" />

                          <constructor-arg ref="hornetQSecurityManagerImpl" />

                </bean>


      {code}

       

       

       

       

      From my application's main context file I'm supplying the map 'namingServerMap' so that port and rmiPort are different for application A & B.

       

      For A:

       

       

      {code:xml}

                <bean id="namingServerMap" class="java.util.HashMap">

                          <constructor-arg>

                                    <map>

                                              <entry key="port" value="1099" />

                                              <entry key="rmiPort" value="1098" />

                                    </map>

                          </constructor-arg>

                </bean>

      {code}

       

       

       

      For B:

       

       

      {code:xml}

                <bean id="namingServerMap" class="java.util.HashMap">

                          <constructor-arg>

                                    <map>

                                              <entry key="port" value="2001" />

                                              <entry key="rmiPort" value="2000" />

                                    </map>

                          </constructor-arg>

                </bean>

      {code}

       

       

       

      jndi.properties file for A:

       

      java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

      java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

      java.naming.provider.url=jnp://localhost:1099

       

      jndi.properties file for B:

       

      java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

      java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

      java.naming.provider.url=jnp://localhost:2001

       

      I have separate hornetq-configuraiton.xml & hornetq-jms.xml files for both applications (A & B).

      And the applications used to work perfectly on hornetq 2.0.0 GA. Now we're trying to migrate to 2.2.19.Final.

      (I've made the required changes in the spring context file such as using 'HornetQJMSConnectionFactory' instead of 'HornetQConnectionFactory')

       

      When deployed in tomcat separately, both A & B works as expected.

      But when deployed together, first A deployes and all goes well.

      But for B I get the following exception:

       

       

      -----

      SEVERE: Unable to deploy node {noformat}[queue: null]{noformat} DLQ

      javax.naming.NamingException: /queue/DLQ already has an object bound

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.checkJNDI(JMSServerManagerImpl.java:1491)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.access$100(JMSServerManagerImpl.java:104)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl$1.runException(JMSServerManagerImpl.java:436)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.runAfterActive(JMSServerManagerImpl.java:1719)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.createQueue(JMSServerManagerImpl.java:427)

              at org.hornetq.jms.server.impl.JMSServerDeployer.deployQueue(JMSServerDeployer.java:176)

              at org.hornetq.jms.server.impl.JMSServerDeployer.createAndBindObject(JMSServerDeployer.java:116)

              at org.hornetq.jms.server.impl.JMSServerDeployer.deploy(JMSServerDeployer.java:99)

              at org.hornetq.core.deployers.impl.XmlDeployer.deploy(XmlDeployer.java:189)

              at org.hornetq.core.deployers.impl.FileDeploymentManager.registerDeployer(FileDeploymentManager.java:131)

              at org.hornetq.core.deployers.impl.XmlDeployer.start(XmlDeployer.java:218)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.activated(JMSServerManagerImpl.java:234)

              at org.hornetq.core.server.impl.HornetQServerImpl.callActivateCallbacks(HornetQServerImpl.java:1267)

              at org.hornetq.core.server.impl.HornetQServerImpl.initialisePart2(HornetQServerImpl.java:1492)

              at org.hornetq.core.server.impl.HornetQServerImpl.access$1200(HornetQServerImpl.java:138)

              at org.hornetq.core.server.impl.HornetQServerImpl$SharedStoreLiveActivation.run(HornetQServerImpl.java:1944)

              at org.hornetq.core.server.impl.HornetQServerImpl.start(HornetQServerImpl.java:366)

              at org.hornetq.jms.server.impl.JMSServerManagerImpl.start(JMSServerManagerImpl.java:282)

              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.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1581)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1522)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)

              at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)

              at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)

              at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)

              at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)

              at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)

              at org.springframework.beans.factory.support.AbstractBeanFactory.getTypeForFactoryBean(AbstractBeanFactory.java:1356)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:710)

              at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:519)

              at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:343)

              at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:320)

              at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:307)

              at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:144)

              at org.springframework.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:97)

              at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findNamedEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:511)

              at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:493)

              at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:657)

              at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:630)

              at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)

              at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)

              at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:339)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)

              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)

              at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)

              at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)

              at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)

              at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)

              at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609)

              at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)

              at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469)

              at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)

              at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)

              at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)

              at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4205)

              at org.apache.catalina.core.StandardContext.start(StandardContext.java:4704)

              at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)

              at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)

              at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)

              at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:675)

              at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:601)

              at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502)

              at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1315)

              at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)

              at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)

              at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1061)

              at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)

              at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)

              at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)

              at org.apache.catalina.core.StandardService.start(StandardService.java:525)

              at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)

              at org.apache.catalina.startup.Catalina.start(Catalina.java:595)

              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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)

              at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

      -----

       

       

       

      Similar exception traces for all queues in application B with same JNDI name as in application A.

      Am I missing something?

      My intention is to have 2 separate hornetq instances for the 2 applications with their own separate NamingServers.

       

      Please Help.

        • 1. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
          ataylor

          As far as I am aware the naming server will be shared In the same JVM, thats why you only specify the class. Im not a JNDI expert but I'm assuming you will have to isolate the classpath of your 2 servers or change one config not to use jndi.

          • 2. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
            gazal_ka

            I think this part of the config is supposed to mean otherwise:

             

             

            {code:xml}          <bean name="namingServerImpl" class="org.jnp.server.NamingBeanImpl"

                                init-method="start" destroy-method="stop">

                                <property name="useGlobalService" value="false" />

                      </bean>{code}

             

            The useGlobalService = false setting in my understanding is supposed to create separate namingService for both applications.

            Correct me if I'm wrong.

            • 3. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
              ataylor

              The naming server is just a component we use, it actually has nothing to do with HornetQ, one question i have tho is how do you specify the 2 different jndi properties for each application, the reason i ask is that i though if have a jndiURL then when we bind objects to jndi it should fail as you cant do this remotely.

               

              fyi in the code we just do

               

              ic = new InitialContext()

              ic.bind(...)

              • 4. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                ataylor

                btw you can ask on the jboss naming forums for specific questions on JNDI

                • 5. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                  gazal_ka

                  Each application has a jndi.properties file in its classpath:

                   

                  A

                  - WEB-INF

                      - classes

                         - jndi.properties

                  B

                  - WEB-INF

                      - classes

                         - jndi.properties

                   

                  And within the application's context we are getting destinations like this:

                   

                  {code:xml}  <bean id="exampleQueue" class="org.springframework.jndi.JndiObjectFactoryBean"

                                      depends-on="jmsServerManagerImpl">

                                      <property name="jndiName" value="/queue/exampleQueue" />

                            </bean>{code}

                   

                  Is there a better approach?

                  • 6. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                    ataylor

                    to be honest i cant see that the jndi url is actually being used and to be honest the url is just for clients, it looks like its not, you could debug JMSServerManagerImpl and see what naming server is being used.

                     

                    If its not then Tomcat/Spring isnt using classloaders correctly, i.e. application server a shoul dnot see classes loaded by application b (assuming that the hornetq jars are shipped with the application and not in a common lib)

                    • 7. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                      gazal_ka

                      When debugging JMSServerManagerImpl

                       

                      for application A

                      (JMSServerManagerImpl instance).registry.context.myProps={java.naming.provider.url=jnp://localhost:1099, java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory, java.naming.factory.url.pkgs=org.apache.naming:org.jboss.naming:org.jnp.interfaces}

                      (The url is the one that I have specified in A's jndi.properties, but the other properties seem changed.

                       

                      for application B

                      (JMSServerManagerImpl instance).registry.context.myProps={java.naming.provider.url=jnp://localhost:2001, java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory, java.naming.factory.url.pkgs=org.apache.naming:org.jboss.naming:org.jnp.interfaces}

                       

                      But interestingly

                      (JMSServerManagerImpl instance).registry.context.gotDefault = true

                      That I'm guessing should be a problem.

                      Could you suggest what can be done to get around this?

                       

                       

                      Another important point to consider is that all of this was working fine for us using hornetq 2.0.0.GA.

                      (and correspoding maven dependency for jnpserver and client -

                      <groupId>org.jboss</groupId>

                                                    <artifactId>jnpserver</artifactId>

                                                    <version>${hornetq.version}</version>)

                       

                      Currently trying to run with hornetq 2.2.19.FINAL with

                      <dependency>

                                                    <groupId>jboss</groupId>

                                                    <artifactId>jnpserver</artifactId>

                                                    <version>${jnp.version}</version>

                                                    <scope>runtime</scope>

                                          </dependency>

                      • 8. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                        ataylor

                        no it isnt the problem, you can't use a jndiURL for server side jndi contexts, this is because you can only bind lo local jndi, you should only have this set on the client side.

                         

                        This means I(Im assuming) that both servers are using the same invm InitialContext for binding. The issue is that Tomcat or spring is nit isolating the classloaders.

                         

                        I would suggest

                         

                        1) removing the jndiURL property

                        2) only configure your jndi names on one server.

                        • 9. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                          gazal_ka

                          Any idea as to why this was working properly when using hornetq 2.0.0GA ?

                          • 10. Re: JNDI Issue 2 web applications with in-vm hornetq deployed in 1 tomcat
                            ataylor

                            probably because then we ignored duplicate entries which was wrong