7 Replies Latest reply on Aug 26, 2017 8:40 PM by gberish

    Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10

    gberish

      Thanks to Vincent (solution below) this now should work for anyone.

       

      Code should be cut an pastable.

      Only 4 jars required to make it work with WF-10

       

      Dumb. But the only problem was I picked up too many jars wadding through earlier problems on the way to the last step: createConsumer ().

      My embarassing starting list, and final list of 4 jars are below.

      It seems the order in which they were searched resulted in some out of date/inconsistent version jars read first.

       

      Solution was to remove all jars.

      Add jboss-client.jar as suggested.

      Three jars later it all wrorked.

      xnio-api-3.4.6.Final.jar was the only one it took me forever to find.

       

      Seems an awfully good reason to learn Mavin.

       

      Thanks to all.

       

      Awf

       

      Many similar questions exist.

      But none with answers of any general value to anyone staring out with Wildfly-0.

      All are unanswered, or so specific to the questioner's application they don't help

       

      So I'd like to leave behind one simple complete free standing Cut & Past Example of a remote Java Client able to exchange JMS Messages with a Wild Fly / 10 Artemis messaging subsystem.

       

      Here's of list of the things I pasted below.

      Right now code terminates with a NullPointerException is Session createConsumer () -- documentation says it doesn't throw.

      I'd really appreciate help getting past that.

       

      Class Code

      Eclipse Console Output

      Wildfly CLI command to configure a Queue

      Windfly standalone-full.xml messaging subsystem

      A list of all the jars I've accumulated

         (from many unhelpful answers ... so I can't guarantee all are needed)

       

      ANY HELP?

       

      *** CLASS CODE ***

          Only main () is relevant. all other methods are just Println helpers

          main () has only seven relevant lines ... marked in bold.  Again all other lines format Console output

          import java.util.Properties;

          import javax.naming.Context;

          import javax.naming.InitialContext;

          import javax.jms.Connection;

          import javax.jms.ConnectionFactory;

          import javax.jms.MessageConsumer;

          import javax.jms.Queue;

          import javax.jms.Session;

         

          public class TestArtemisJmsWF10 {

         

            static final Properties ENV = new Properties() {

              private static final long serialVersionUID = 1L;

              {

                put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");

                put(Context.PROVIDER_URL, "http-remoting://localhost:8080");

                put(Context.SECURITY_PRINCIPAL, "jmsUser");

                 put(Context.SECURITY_CREDENTIALS, "jmsUser123!");

              }

            };

            static final String JMS_SELECTOR = "selector=\'AAAAA\'";

           

            public static void main (String args[]) {

              boolean p = true; String iAmM = null; String s = " "; String errAt = "";

              if (p) iAmM = TestArtemisJmsWF10.getIAm(Thread.currentThread().getStackTrace());

              if (p) P(iAmM + "beg\n");

              if (p) P(s + iAmM + "Requesting InitialContext with:");

              if (p) P(printInitialContextProperties(8, ENV));

              try {

                errAt = "Requesting InitialContext";

                Context ctx = new InitialContext(ENV);

                if (p) P("\n" + s + iAmM + "InitialContext ok: " + ctx);

               

                errAt = "LookingUp  ConnectionFactory";

                if (p) P("\n" + s + iAmM + "Lookup ConnectionFactory");

                if (p) P(s + iAmM + "JNDI lookUp name: \"jms/RemoteConnectionFactory\"");

                ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");

                if (p) P(s + iAmM + "ConnectionFactory: Ok: " );

                if (p) P(s + makeMargin(iAmM.length()) + "[" + factory.getClass().getName() +"]");

         

                errAt = "Requesting Connection";

                Connection jmsConnection = factory.createConnection(

                   ENV.getProperty(Context.SECURITY_PRINCIPAL),

                   ENV.getProperty(Context.SECURITY_CREDENTIALS));

                if (p) P("\n" + s + iAmM + "JMS Connection: Ok:");

                if (p) P(s + makeMargin(iAmM.length()) + "[" + jmsConnection + "]");

               

                errAt = "Starting Connection";

               jmsConnection.start();

                if (p) P("\n" + s + iAmM + "Starting jmsConnection & initiating Session");

               jmsConnection.start();

       

                errAt = "Creating Session";

                Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                if (p) P(s + iAmM + "Session ok - " + jmsSession);

       

                          errAt = "Looking Up JNDI Name sendToClientQueue2";

              if (p) P("\n" + s + iAmM + errAt);

              String jndiName = "jms/queue/sendToClientQueue2";

              if (p) P(s + iAmM + "JNDI lookUp name: " + jndiName);

              Queue jmsSendToClientQueue = (Queue) ctx.lookup(jndiName);

              if(p) P(s + iAmM + "Queue secured. Queue name: " + jmsSendToClientQueue.getQueueName());

       

          

                errAt = "Creating JMS Message Consumer";

                if(p) P("\n" + s + iAmM + "Calling createConsumer() with selector: " + JMS_SELECTOR);

               // This Line Throws Exception        

               MessageConsumer jmsMsgConsumer = jmsSession.createConsumer(jmsSendToClientQueue, JMS_SELECTOR);

                if(p) P(s + iAmM + "Consumer secured: " + jmsMsgConsumer);

                if (p) P(iAmM + "end");

              } catch (Exception e) {

                if(p) P("\n" + s + iAmM + "Caught: "+ e.getClass().getName()

                    + "\n" + s + makeMargin(iAmM.length()) + "when " + errAt);

                if(p) P(s + makeMargin(iAmM.length()) + "Msg   : " + e.getMessage());

                if(p) P(iAmM + "end - error");

                if (p) e.printStackTrace();

              }

            }

           // All methods are just Print Helpers. May be ignored

            static public String printInitialContextProperties (int leader, Properties env) {

              int maxLength = 0;

              String s = padRight("", leader, ' ');

              for (Object keyO: env.keySet()) {

                String key = (String) keyO;

                maxLength = 1+Math.max(maxLength, key.length());

              }

              StringBuffer sb = new StringBuffer ();

              sb.append(s + "CONNECTION VARIABLES");

              for (Object keyO: env.keySet()) {

                String key = padRight((String)keyO, maxLength, ' ');

                sb.append("\n" + s + "key: " + key + "value: " + env.get(keyO));

              }

              return sb.toString();

            }

           

            static public void P (String s) {

              System.out.println(s); 

            }

           

            static private String getIAm (StackTraceElement[] elements) {

              StringBuffer sb = new StringBuffer ();

              sb.append(getClassMethodName(elements));

              sb.append(" ()");

              return padRight (sb.toString(), 45, ' ') ;

            }

           

            static public String getClassMethodName (StackTraceElement[] elements) {

              /*

               * This method finds the 1st org.america3 element from the top

               * of the stack

               */

              String className = null;

              for (int i = 0; i < elements.length; i++) {

                className = elements[i].getClassName ();

                if (className.startsWith ("org.america3")) {

                  int end = className.lastIndexOf ('.');

                  return className.substring (end + 1) + "." + elements[i].getMethodName ();

                } else {

                 continue;

                }

              }

              return "no project method found in elements beginning with org.america3" ;

            }

           

            static public String padRight(String s, int width, char c){

              if (s == null) return "Null String";

              if(s.length() >= width){

                return s;

              } else {

                StringBuffer sb = new StringBuffer();

                sb.append (s);

                for(int i = 0; i < (width - s.length()); i++){

                  sb.append(c);

                }

                return sb.toString();

              }

            }

         

            static public String makeMargin (int padWidth) {

              StringBuffer sb = new StringBuffer ();

              for (int i = 0; i < padWidth; i ++) {

                sb.append(' ');

              }

              return sb.toString();

            }     

          }

       

      ECLIPSE CONSOLE OUTPUT w/ STACK TRACE

      TestArtemisJmsWF10.main ()                   beg

       

        TestArtemisJmsWF10.main ()                   Requesting InitialContext with:

              CONNECTION VARIABLES

              key: java.naming.provider.url         value: http-remoting://localhost:8080

              key: java.naming.factory.initial      value: org.jboss.naming.remote.client.InitialContextFactory

              key: java.naming.security.principal   value: jmsUser

              key: java.naming.security.credentials value: jmsUser123!

       

        TestArtemisJmsWF10.main ()                   InitialContext ok: javax.naming.InitialContext@210366b4

       

        TestArtemisJmsWF10.main ()                   Lookup ConnectionFactory

        TestArtemisJmsWF10.main ()                   JNDI lookUp name: "jms/RemoteConnectionFactory"

        TestArtemisJmsWF10.main ()                   ConnectionFactory: Ok:

      [org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory]

       

        TestArtemisJmsWF10.main ()                   JMS Connection: Ok:

      [org.apache.activemq.artemis.jms.client.ActiveMQConnection@43195e57]

       

        TestArtemisJmsWF10.main ()                   Starting jmsConnection & initiating Session

        TestArtemisJmsWF10.main ()                   Session ok - ActiveMQSession->ClientSessionImpl [name=99a38536-8aba-11e7-a8d2-bbbb165a7f4a, username=jmsUser, closed=false, factory = org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl@6e2c9341, metaData=(jms-session=,)]@333291e3

       

        TestArtemisJmsWF10.main ()                   Looking Up JNDI Name sendToClientQueue2

        TestArtemisJmsWF10.main ()                   JNDI lookUp name: jms/queue/sendToClientQueue2

        TestArtemisJmsWF10.main ()                   Queue secured. Queue name: SendToClientQueue2

       

        TestArtemisJmsWF10.main ()                   Calling createConsumer() with selector: selector='AAAAA'

        TestArtemisJmsWF10.main ()                   Consumer secured: ActiveMQMessageConsumer[org.apache.activemq.artemis.core.client.impl.ClientConsumerImpl@8f4ea7c{consumerContext=ActiveMQConsumerContext{id=0}, queueName=jms.queue.SendToClientQueue2}]

      TestArtemisJmsWF10.main ()                   end

       

       

      CLI COMMAND USED TO CONFIGURE SERVER SIDE QUEUE

       

      [standalone@localhost:9990 /] /subsystem=messaging-activemq/server=default/jms-queue=SendToClientQueue2:add(entries=[java:jboss/exported/jms/queue/sendToClientQueue2])

      {"outcome" => "success"}

      [standalone@localhost:9990 /]

       

      STANDALONE-FULL.XML JMS MESSAGING SUBSYSTEM

       

      <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">

        <server name="default">

          <security enabled="false"/>

          <security-setting name="#">

            <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>

          </security-setting>

                  ...

          <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>

          <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>

          <jms-queue name="SendToServerQueue" entries="java:jboss/exported/jms/queue/sendToServerQueue"/>

          <jms-queue name="SendToClientQueue2" entries="java:jboss/exported/jms/queue/sendToClientQueue2"/>

         

          <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>

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

          <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>

        </server>

      </subsystem>

       

      JARS ACCUMULATED SO FAR IN THE BUILD PATH

            jboss-client.jar

           xnio-api-3.4.6.Final.jar   

          slf4j-log4j12-1.8.0-alpha2.jar   

          apache-logging-log4j.jar

       

         xnio-nio-3.4.3.Final.jar

          artemis-commons-2.2.0.jar   

         artemis-commons-2.2.0.jar   

          artemis-core-client-2.2.0.jar   

          artemis-jms-client-2.2.0.jar   

          artemis-selector-2.2.0.jar

          commons-beanutils-1.9.2.jar   

          commons-logging-1.1.1.jar   

          commons-collections-3.2.1.jar

         netty-all-4.1.9.Final.jar

          javax.json-1.0.2.jar   

          javax.jms-3.1.2.2.jar   

          javax.mail-1.5.0.jar   

          javax.jms-api-2.0.jar

         jboss-logging-3.1.4.GA.jar  

          jboss-ejb-client-1.0.19.final.jar

          jboss-marshalling-1.3.15.GA.jar

         jboss-remoting-4.0.7.Final.jar   

         jboss-remote-naming-2.0.1.Final.jar

          jboss-remoting-3.2.7.ga.jar   

         jboss-marshalling-river-1.3.14.GA.jar

          hornetq-jms-client.jar (left over from WF 8

        • 1. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
          vincent.sourin

          Hello George,

           

          It seems you have a curly brace at the end of the entries definition of SendToClientQueue queue.

           

          <jms-queue name="SendToClientQueue" entries="java:jboss/exported/jms/queue/sendToClientQueue }"/>

           

          In your cli command, it should be a parenthesis at the end of the command not a curly brace.

          • 2. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
            gberish

            Hi Vincent,

             

            Thanks, but correcting that made no difference.

             

            Note: To keep things clean I've decided to make the suggestions I try to the original question in Bold Blue font. So when done it will still be a cut and pasteable example.

             

            Otherwise ... here's how I implemented your correction:

            I used WF console to remove old Queue.

            Used the new CLI Command above to add a new Queue with a new name, NAME = SendToClientQueue2. NEW JNDI NAME=java:jboss/exported/jms/queue/sendToClient2.

            Checked standalone-full.xml:  <jms-queue name="SendToClientQueue2" entries="java:jboss/exported/jms/queue/sendToClientQueue2"/>

            And changed Code for the Queue lookup to verify the object really was the new Queue.  Note it confirms the queue's name (not jndi name) is SendToClientQueue2.

             

            And it still threw the exact same NullPointerException from ActiveMQDestination.java: 397

             

            Neither the WF Console, nor the C:\ProgramFilesGeo\Wildfly\wildfly-10.1.0.Final\standalone\log\server.log show anything. last entry in both is the start up successfully line.

            I'm lost. This seems Nutz.

            • 3. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
              vincent.sourin

              Hi,

               

              Here is a maven project that works for me on Wildfly 10.1.0.Final

              I did not pay attention the first time but I don't think you use the correct libraries. WF 10 is shipped with Artemis 1.1.0

              The easiest way is to use Wildfly jms client bom :

               

              <dependency>
                   <groupId>org.wildfly</groupId>
                   <artifactId>wildfly-jms-client-bom</artifactId>
                   <version>10.1.0.Final</version>
                   <type>pom</type>
              </dependency>
              
              • 4. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
                gberish

                Hi Vincent,

                 

                Thanks.  But now I guess I need to learn how to use Mavin. May take some, because I haven't done that yet.

                 

                But just in case it's a simple answer, where does pom.xml live?

                If not, I guess I've got some reading to do, which means it'll be a few days.

                 

                Just for info,

                I ended up with the jars I had by removing them all. Then running main () until I satisfied all ClassNotFoundExceptions and all the steps thru getting a valid Queue lookup() worked right.

                • 5. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
                  gberish

                  Vincent,

                   

                  One quick question.

                   

                  Do your examples run inside or outside WF's container?.

                   

                  I ask because the quick Mavin intro I read stresses Maven produces "packages". And to me that sounds like things deployed inside WF's container.

                   

                  But my class runs "remotely". I.e. on the same PC I'm running WF, but otherwise outside of it?

                   

                  I mean I haven't had any problems yet with say my MDB looking up Queues and using them as consumers.  Just my free standing "remote" java client.

                   

                  Thanks again..

                  • 6. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
                    vincent.sourin

                    If you don't use build automation tools, please ensure that jboss-client.jar (it contains all needed libs for standalone app) is in your classpath. It lies in ${wildfly-root}/bin/client/

                    My example is "standalone" example intended to run in a SE Environment not in WF.

                    Here, maven just allows to compile the project without  bother to select the right libraries by hand

                    • 7. Re: Why Doesn't This Simple JMS Messaging Example Work - Wildfly 10
                      gberish

                      Hi Vincent,

                       

                      It just worked.

                      I removed all jars.

                      Added jboss-client.jar back

                      3 jars later it ... well ... worked.

                       

                      Good lesson ... grin ... neatness counts

                       

                      So I amended the original question to be correct as it now shows.

                       

                      Thank you.