2 Replies Latest reply on Nov 8, 2015 7:25 PM by George Berish

    Why Doesn't Standalone Java Client Get InitialContext from localhost WildFly 8?

    George Berish Novice

        I am a beginner escaping from Glassfish to WildFly.  And failing miserably. So at this point any help would be welcome.

       

      My key need is getting a Java client to swap JMS messages with a JEE app deployed on WildFly.  Ultimate client will be a Java Swing GUI launched by Browser via WebStart(JNPL).  For now its the java program below running on Eclipse Mars.  Wildfly 8 is running on local host.  All are on same machine.

       

      Step 1 is to get a JMS ConnectionFactory.  Before Oracle messed up JMS in GF4, that was a trivial lookup(). Per WildFly documentation (always a sketchy thing) I thought it would still be easy.

      https://docs.jboss.org/author/display/WFLY8/Messaging+configuration

      "Since JMS 2.0, a default JMS connection factory is accessible to EE application under the JNDI name java:comp/DefaultJMSConnectionFactory."

       

      Two weeks later: Many questions posted to many sites. No solution.  I'm nowhere. 


      So here's the code as simplified as I can make it.  The comments keep track of jars various people have said are needed.  Any insight, help,  direction, or suggestions (other than quit) would be welcome. (Note: The client does not run in a JEE container, so nothing that involves "injection" is applicable.) 

       

      I'm obviously missing something fundamental.  I mean I can't even kill the @!&@%$! unrelated, unneeded, Derby warning.

      And the ClassNotFound org.jboss.as.naming.InitialContextFactory.class

      makes no sense to me.  See imports where I even imported it to be sure it was in the build path

       

      CLIENT CODE:

      package org.america3.wildfly.jms;

       

      import java.util.Hashtable;

      import javax.naming.Context;

      import javax.naming.InitialContext;

      import com.sun.messaging.ConnectionFactory;

      import org.jboss.as.naming.InitialContextFactory;

      public class JMSTest1 {

       

        static Hashtable<String, String> ENV = new Hashtable<String,String>() {

          private static final long serialVersionUID = 1L;

          {

           put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.as.naming.InitialContextFactory.class");

           /*

            * InitialContextFactory is in wildfly-naming-9.0.2.Final.jar

            * WildFly stores the jar in <WILDFLY_HOME>\modules\system\layers\base\org\jboss\as\naming\main

            * I added it to the Eclipse build path

            */

           put(Context.PROVIDER_URL, "localhost:8080");

          }

        };

       

        static public void main (String[] args) {

          try {

            final Context context = new InitialContext(ENV);

            ConnectionFactory factory = (ConnectionFactory) context.lookup("java:comp/DefaultJMSConnectionFactory");

            System.out.println(factory);

          } catch (Exception e) {

            System.out.println("MY EXCEPTION CATCH");

            System.out.println("Name:    " + e.getClass().getName());

            System.out.println("Message: " + e.getMessage());

            e.printStackTrace();

          }

        }

        /*

         * This is a list of jar files added to WildFly and/or the Eclipse

         * build path

         *

         * derbyclient.jar and derby-driver.jar are stored in these files:

         * <WILDFLY_HOME>\standalone\deployments

         * <WILDFLY_HOME>\standalone\deployments\lib

         * C:\Program Files\Java\jdk1.8.0_05\lib

         * C:\Program Files\Java\jdk1.8.0_05\jre\lib

         *

         * Added the entire Derby API and derby-driver.jar to the Eclipse

         * build path for this class.

         *

         * Also added these jars from <WILDFLY_HOME>\modules\system\layers\base\

         * to Eclipse build path

         * jboss-common-core-2.5.0.Final.jar

         * jboss-ejb3-ext-api-2.1.0.jar

         * jboss-ejb-client-2.1.1.Final.jar

         * jboss-iiop-client-1.0.0.Final.jar

         * wildfly-appclient-9.0.2.Final.jar

         * wildfly-naming-9.0.2.Final.jar

         * hornetq-core-client-2.4.7.Final.jar

         * hornetq-jms-client-2.4.7.Final.jar

         */

      }

       

      CONSOLE OUTPUT:

      MY EXCEPTION CATCH

      Name:    javax.naming.NoInitialContextException

      Message: Cannot instantiate class: org.jboss.as.naming.InitialContextFactory.class

      1. javax.naming.NoInitialContextException: Cannot instantiate class: org.jboss.as.naming.InitialContextFactory.class [Root exception is java.lang.ClassNotFoundException: org.jboss.as.naming.InitialContextFactory.class]

                     at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)

                     at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)

                     at javax.naming.InitialContext.init(Unknown Source)

                     at javax.naming.InitialContext.<init>(Unknown Source)

                     at org.america3.wildfly.jms.JMSTest1.main(JMSTest1.java:27)

      Caused by: java.lang.ClassNotFoundException: org.jboss.as.naming.InitialContextFactory.class

                     at java.net.URLClassLoader$1.run(Unknown Source)

                     at java.net.URLClassLoader$1.run(Unknown Source)

                     at java.security.AccessController.doPrivileged(Native Method)

                     at java.net.URLClassLoader.findClass(Unknown Source)

                     at java.lang.ClassLoader.loadClass(Unknown Source)

                     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

                     at java.lang.ClassLoader.loadClass(Unknown Source)

                     at java.lang.Class.forName0(Native Method)

                     at java.lang.Class.forName(Unknown Source)

                     at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)

                     at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)

                     ... 5 more

        • 1. Re: Why Doesn't Standalone Java Client Get InitialContext from localhost WildFly 8?
          Jay SenSharma Master

          There are couple of things incorrect in your approach.

           

          1). Your code is trying to lookup a resource with JNDI name "java:comp/DefaultJMSConnectionFactory"  Outside of the JVM, where as only the JNDI name which starts with "java:jboss/exported"  can only be looked up out side of the JVM

           

          2). In your classpath you are adding "<WILDFLY_HOME>\modules\system\layers\base\org\jboss\as\naming\main\wildfly-naming-9.0.2.Final.jar"   rather WildFly provide s a single JAR which can be used for the clients  that is "$JBOSS_HOME/bin/client/jboss-client.jar"  this jar contains almost all the needed client related stuff.

           

          3). The Code is also not correct (remoting based client approach)

           

                    Context context=null;
                    try {
                          Properties props = new Properties();
                          props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
                          props.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");   // NOTICE: "http-remoting" and port "8080"
                          props.put(Context.SECURITY_PRINCIPAL, "jmsuser");
                          props.put(Context.SECURITY_CREDENTIALS, "jmsuser@1");
                          props.put("jboss.naming.client.ejb.context", true);
                          context = new InitialContext(props);
                         System.out.println("\n\tGot initial Context: "+context);
          
                          ConnectionFactory factory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");  // NOTICE
                     } catch (Exception e) {
                          e.printStackTrace();
                     }
          
          

           

          NOTICE:  in the above code snippet we are not looking up "java:comp/DefaultJMSConnectionFactory" because it is not accessible outside of the JVM.  You should lookup the  "" which is defined in your WildFly profile as following:

           

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

           

           

          Also the user  jmsuser/jmsuser@1   are created using $JBOSS_HOME/bin/add-user.sh  script in ApplicationRealm and that user has "guest" role.

          The client Classpath need only the JAR "wildfly-8.x.Final/bin/client/jboss-client.jar"

           

           

           

          You can find the complete code sample and the explanation on some common issues in this perspective in the following article:

           

           

          Wildfly 8 based standalone JMS client code common issues and remedies ? «  JBoss

          http://middlewaremagic.com/jboss/?p=2724

           

           

          Regards

          Jay SenSharma

          • 2. Re: Why Doesn't Standalone Java Client Get InitialContext from localhost WildFly 8?
            George Berish Novice

            Jay:

            Thank you.

             

            To beginners who follow.  The solution is perfect.

            The linked article was excellent and provides much more than just the solution to my problem.

            It even made the Derby warning go away.


            The only thing I needed to adjust was the class used to implement RemoteConnectionFactory.

            import org.hornetq.jms.client.HornetQJMSConnectionFactory;

            HornetQJMSConnectionFactory factory = (HornetQJMSConnectionFactory) context.lookup("jms/RemoteConnectionFactory");

            George Berish