4 Replies Latest reply on Oct 15, 2015 12:46 AM by shabin8780

    Remote JMS with JTS in wildfly

    shabin8780

      Hi,

       

      I am trying to implement remote JMS in wildfly for multiple instances using JTS.

      I combined these two quickstarts: [quickstart/jts at 9.x · wildfly/quickstart · GitHub] and [quickstart/helloworld-jms at 9.x · wildfly/quickstart · GitHub].

      This is my changed code in CustomerManagerEJB class at the application-component-1.

       

      @TransactionAttribute(TransactionAttributeType.REQUIRED)
        public void createCustomer(String name) throws RemoteException {
        Customer c1 = new Customer();
        c1.setName(name);
        entityManager.persist(c1);
        final InvoiceManagerEJB invoiceManager = invoiceManagerHome.create();
        Context namingContext = null;
        try {
        final Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8081"));
        env.put(Context.SECURITY_PRINCIPAL, "username");
        env.put(Context.SECURITY_CREDENTIALS, "password");
        namingContext = new InitialContext(env);
        ConnectionFactory connectionFactory = (ConnectionFactory) namingContext
        .lookup("/jms/RemoteConnectionFactory");
        Destination destination = (Destination) namingContext.lookup("java:/queue/InvoiceManagerQueue");
        try (JMSContext context = connectionFactory.createContext("username", "password")) {
        log.info("Sending  messages with content: message from client");
        context.createProducer().send(destination, "message from client");
        }
        } catch (NamingException e) {
        log.log(Level.SEVERE, e.getMessage(), e);
        }
        invoiceManager.createInvoice(name);
        throw new RuntimeException("test");
        }
      

       

      Connection factory config in server side

      <connection-factory name="RemoteConnectionFactory">
      <factory-type>XA_GENERIC</factory-type>
       <connectors>
          <connector-ref connector-name="http-connector"/>
        </connectors>
      <entries>
         <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
      </entries>
      </connection-factory>
      

       

      Eventhough I am throwing a runtime exception at the end, the message "message from client" is coming to the server. Do I need to add some extra configs to make remote jms work with JTS?

       

      Regards,
      Shabin

        • 1. Re: Remote JMS with JTS in wildfly
          jbertram

          From what I can tell this is basic JTA rather than JTS, but I digress.

           

          You need to lookup and use a local pooled-connection-factory when sending your messages to the remote server.  A pooled-connection-factory is JCA based and will be automatically enlisted in the EJB's JTA transaction.  A plain JMS connection factory will not be automatically enlisted into the JTA transaction whether or not it's looked up locally or remotely.

          • 2. Re: Remote JMS with JTS in wildfly
            shabin8780

            Thanks Justin, I was actually trying the same thing as you suggested. But I am facing some issues.

             

            I looked up a local pooled-connection-factory(java:/JmsXA) using @Resource.

            <http-connector name="http-connector" socket-binding="my-http">
                <param key="http-upgrade-endpoint" value="http-acceptor"/>
            </http-connector>
            
            
            

             

             

            <pooled-connection-factory name="hornetq-ra">
              <transaction mode="xa"/>
                  <connectors>
                      <connector-ref connector-name="http-connector"/>
                  </connectors>
                    <entries>
                        <entry name="java:/JmsXA"/>
                        <!-- Global JNDI entry used to provide a default JMS Connection factory to EE application -->
                        <entry name="java:jboss/DefaultJMSConnectionFactory"/>
                    </entries>
            </pooled-connection-factory>
            
            
            

             

            <outbound-socket-binding name="my-http">
                        <remote-destination host="localhost" port="8081"/>
                    </outbound-socket-binding>
            
            
            

             

            But on lookup of the queue as same in the previous code, I am getting the following exception in the send() method even though queue obtained from the remote lookup is of type HornetQQueue.

            javax.jms.InvalidDestinationException: Not a HornetQ Destination:HornetQQueue[InvoiceManagerQueue]

             

            Thinking it as a class loader issue, I made my client side hornetq maven dependencies as provided. But then I am getting classnotfound for org.hornetq.jms.client.HornetQQueue

             

            So I don't know what to try next. Am I correct in the configuration part(using local-pooled-connection with http-connector and looking up a remote queue)? If yes, why I am getting the InvalidDestinationException. I am fully confused.

            • 3. Re: Remote JMS with JTS in wildfly
              jbertram

              I would recommend creating a new pooled-connection-factory which references a new connector rather than changing the existing ones.  Changing the existing pooled-connection-factory isn't a huge deal if no other applications use it, but changing the default connector will impact any client attempting to connect to the server using JNDI/JMS.

               

              As for your InvalidDestinationException, I'm not sure why that's being thrown.  Like you, I suspect it is a classloading issue.  Are you packaging HornetQ libraries with your application?  If so, don't.  You should be using the HornetQ libraries provided by the application server at runtime.

              • 4. Re: Remote JMS with JTS in wildfly
                shabin8780

                Hi Justin,

                 

                I finally made it work.

                InvalidDestinationException was indeed a class loading issue.

                I got around it by the following steps:

                As mentioned in my previous post, if I made the hornetq maven dependency in my client side as provided or removed that dependency entirely, it started to give classnotfound.

                So after removing the dependecy I added jboss-deployment-structure.xml inside the WEB-INF with the following config:

                <dependencies>       

                     <module name="org.hornetq"/>

                </dependencies>

                Then everything started working as expected.

                 

                Thanks a lot for helping me out.

                 

                Regards,
                Shabin