{"id":1333,"date":"2013-10-23T21:53:14","date_gmt":"2013-10-23T20:53:14","guid":{"rendered":"http:\/\/www.xenonique.co.uk\/blog\/?p=1333"},"modified":"2013-10-23T21:53:14","modified_gmt":"2013-10-23T20:53:14","slug":"sorry-jms-2-0-standalone-examples-are-not-that-simple","status":"publish","type":"post","link":"https:\/\/www.xenonique.co.uk\/blog\/2013\/10\/23\/sorry-jms-2-0-standalone-examples-are-not-that-simple\/","title":{"rendered":"Sorry, JMS 2.0 standalone examples are not that simple"},"content":{"rendered":"<p>Well I going to have to leave this one for somebody who is more expert than me, because I have more things to do with my time now. I had a question from a reader about the source code for <a href=\"https:\/\/www.packtpub.com\/java-ee-7-developer-handbook\/book\" title=\"Java EE 7 Developer Handbook\">Java EE 7 Developer Handbook<\/a>. Does JMS 2.0 standalone work as a client? What I understood from this, was that a developer should be able to run GlassFish 4 and get access to JMS queues and topics from a standalone container. I used to do this for investment banks using J2EE 1.4 with WebSphere and WebLogic application servers and so I said sure that code I worked with several months is bound to work, the reader&#8217;s question is more likely my own oversight. I must have been dreaming about these results. <\/p>\n<p>I am sorry say, I spent several days going through this experience of getting GlassFish Embedded 4.0, then Managed Server to work together in order to demonstrate a straightforward JMS 2.0 standalone example. I also a use Arquillian test to work and then also tried a non-Arquillian version and now I am very perturbed. It would appear nobody knows on the Net how to exactly configure a standalone JMS 2.0 as a Java SE application. <\/p>\n<p>This is as far as I get:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npackage je7hb.jms.essentials;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\nimport javax.annotation.Resource;\r\nimport javax.ejb.*;\r\nimport javax.jms.*;\r\nimport javax.naming.Context;\r\nimport javax.naming.InitialContext;\r\nimport javax.naming.NamingException;\r\n\r\nimport org.jboss.arquillian.container.test.api.Deployment;\r\nimport org.jboss.arquillian.container.test.api.RunAsClient;\r\nimport org.jboss.arquillian.junit.Arquillian;\r\nimport org.jboss.shrinkwrap.api.ArchivePaths;\r\nimport org.jboss.shrinkwrap.api.ShrinkWrap;\r\nimport org.jboss.shrinkwrap.api.asset.EmptyAsset;\r\nimport org.jboss.shrinkwrap.api.spec.JavaArchive;\r\nimport org.jboss.shrinkwrap.api.spec.WebArchive;\r\nimport org.junit.*;\r\nimport org.junit.runner.RunWith;\r\n\r\nimport java.io.File;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Properties;\r\n\r\n@RunWith(Arquillian.class)\r\npublic class AsynchronousJMSMessageArquillianTest {\r\n\r\n    @Deployment\r\n    public static WebArchive createDeployment() {\r\n        WebArchive webArchive = ShrinkWrap.create(WebArchive.class, &quot;asyncjms.war&quot;)\r\n                .addClasses(PayloadCheck.class)\r\n                .addAsWebInfResource(\r\n                        new File(&quot;src\/test\/resources-glassfish-managed\/glassfish-resources.xml&quot;),\r\n                        &quot;glassfish-resources.xml&quot;)\r\n                .addAsWebInfResource(\r\n                        EmptyAsset.INSTANCE, &quot;beans.xml&quot;);\r\n\r\n        System.out.println(webArchive.toString(true));\r\n        return webArchive;\r\n    }\r\n\r\n    private List&lt;String&gt; messages = new ArrayList&lt;&gt;();\r\n\r\n    private CompletionListener completionListener = new CompletionListener() {\r\n        @Override\r\n        public void onCompletion(Message msg) {\r\n            TextMessage textMsg = (TextMessage)msg;\r\n            try {\r\n                System.out.printf(&quot;%s.onCompletion(%s) Thread: %s\\n&quot;,\r\n                        getClass().getSimpleName(), textMsg.getText(), Thread.currentThread());\r\n            } catch (JMSException e) {\r\n                e.printStackTrace(System.err);\r\n            }\r\n        }\r\n\r\n        @Override\r\n        public void onException(Message msg, Exception ex) {\r\n            ex.printStackTrace(System.err);\r\n        }\r\n    };\r\n\r\n    @Test\r\n    @RunAsClient\r\n    public void shouldFire() throws JMSException, InterruptedException, NamingException {\r\n        Properties properties = new Properties();\r\n\/\/        properties.put(&quot;com.sun.appserv.iiop.endpoints&quot;, &quot;localhost:7676&quot;);\r\n\/\/        properties.put(&quot;org.omg.CORBA.ORBInitialHost&quot;, &quot;localhost&quot;);\r\n\/\/        properties.put(&quot;org.omg.CORBA.ORBInitialPort&quot;, &quot;3700&quot;);\r\n\/\/        properties.put(Context.INITIAL_CONTEXT_FACTORY, &quot;com.sun.enterprise.naming.SerialInitContextFactory&quot;);\r\n\/\/        properties.put(Context.PROVIDER_URL, &quot;mq:\/\/localhost:7676\/&quot;);\r\n\/\/        properties.put(&quot;java.naming.factory.url.pkgs&quot;, &quot;com.sun.enterprise.naming&quot;);\r\n\/\/        properties.put(&quot;java.naming.factory.state&quot;, &quot;com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl&quot;);\r\n\r\n        properties.put(Context.INITIAL_CONTEXT_FACTORY, &quot;com.sun.enterprise.naming.SerialInitContextFactory&quot;);\r\n        properties.put(Context.URL_PKG_PREFIXES, &quot;com.sun.enterprise.naming&quot;);\r\n        properties.put(Context.STATE_FACTORIES, &quot;com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl&quot;);\r\n\/\/        properties.put(&quot;org.omg.CORBA.ORBInitialHost&quot;, &quot;localhost&quot;);\r\n\/\/        properties.put(&quot;org.omg.CORBA.ORBInitialPort&quot;, &quot;3700&quot;);\r\n        properties.put(Context.PROVIDER_URL, &quot;mq:\/\/localhost:7676&quot;); \/\/ vm:\/\/localhost:\r\n\/\/        properties.put(Context.PROVIDER_URL, &quot;iiop:\/\/localhost:7676&quot;); \/\/ vm:\/\/localhost:\r\n\r\n        InitialContext jndiContext = new InitialContext(properties);\r\n        System.out.printf(&quot;\\t jndiContext=%s\\n&quot;, jndiContext);\r\n\r\n        ConnectionFactory connectionFactory =\r\n                (ConnectionFactory)jndiContext.lookup(&quot;jms\/demoConnectionFactory&quot;);\r\n\r\n        Queue queue = (Queue)jndiContext.lookup(&quot;jms\/demoQueue&quot;);\r\n\r\n        assertNotNull(connectionFactory);\r\n        assertNotNull(queue);\r\n\r\n        Connection connection = connectionFactory.createConnection();\r\n        JMSContext context = connectionFactory.createContext(\r\n                Session.AUTO_ACKNOWLEDGE );\r\n        JMSProducer producer = context.createProducer();\r\n\r\n        messages.clear();\r\n\r\n        producer.setAsync(completionListener);\r\n\r\n        producer.send(queue, &quot;hello&quot;);\r\n        producer.send(queue, &quot;world&quot;);\r\n        producer.send(queue, &quot;asynchronously&quot;);\r\n\r\n        Thread.sleep(2000); \/\/ Delay before shutdown\r\n\r\n        System.out.println(&quot;Done&quot;);\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>The evidence is in the code and you can review commented out lines, because every which way and some has been tried. <\/p>\n<p>The reason is that certain calls such as <code>setAsync<\/code> are forbidden in a Java EE and web container. Therefore if you want an asynchronous JMS reader or writer in EE you can forget about it.<\/p>\n<p>The glassfish resource configuration file is:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;!DOCTYPE resources PUBLIC &quot;-\/\/GlassFish.org\/\/DTD GlassFish Application Server 3.1 Resource Definitions\/\/EN&quot; &quot;https:\/\/glassfish.org\/dtds\/glassfish-resources_1_5.dtd&quot;&gt;\r\n&lt;resources&gt;\r\n    &lt;admin-object-resource enabled=&quot;true&quot; jndi-name=&quot;jms\/demoQueue&quot; object-type=&quot;user&quot; res-adapter=&quot;jmsra&quot; res-type=&quot;javax.jms.Queue&quot;&gt;\r\n        &lt;description\/&gt;\r\n        &lt;property name=&quot;Name&quot; value=&quot;PhysicalQueue&quot;\/&gt;\r\n    &lt;\/admin-object-resource&gt;\r\n    &lt;admin-object-resource enabled=&quot;true&quot; jndi-name=&quot;jms\/demoTopic&quot; object-type=&quot;user&quot; res-adapter=&quot;jmsra&quot; res-type=&quot;javax.jms.Topic&quot;&gt;\r\n        &lt;description\/&gt;\r\n        &lt;property name=&quot;Name&quot; value=&quot;PhysicalTopic&quot;\/&gt;\r\n    &lt;\/admin-object-resource&gt;\r\n    &lt;connector-connection-pool name=&quot;jms\/demoDestinationFactoryPool&quot;\r\n                               connection-definition-name=&quot;javax.jms.QueueConnectionFactory&quot;\r\n                               resource-adapter-name=&quot;jmsra&quot; \/&gt;\r\n    &lt;connector-resource enabled=&quot;true&quot;\r\n                        jndi-name=&quot;jms\/demoConnectionFactory&quot;\r\n                        pool-name=&quot;jms\/demoDestinationFactoryPool&quot;\r\n                        object-type=&quot;system-all&quot; \/&gt;\r\n&lt;\/resources&gt;\r\n<\/pre>\n<p>In fact, it is such an embarrassing state of affairs, I would recommend not look at GlassFish for a standalone JMS client, but maybe to wait for <a href=\"https:\/\/www.wildfly.org\/\" title=\"JBoss Wildfly\"><strong>WildFly<\/strong><\/a> or <a href=\"https:\/\/tomee.apache.org\/\" title=\"TomEE apache server\"><strong>Tom EE<\/strong><\/a>. Clearly, using JMS 2.0 <em>outside<\/em> of EE container is very unamusing, and I think this has be bloody easier for new developers, otherwise they want touch Java EE with a barge pole. If the technical expert cannot develop a simple example of outside-of-container JMS use then what is the point? The <a href=\"https:\/\/mq.java.net\/downloads\/ri\/\" title=\"JMS 2.0 Reference Implementation\">official JMS 2.0 page<\/a> is also unhelpful.<\/p>\n<p>Part of the problem is that there is no standard client side JMS API for Java SE, JAX RS 2.0 now has a client-side API. Another is that some of the GlassFish Maven artifacts have huge dependencies, which cause the download of the entire application server&#8217;s modules (I pointing a finger at <code>gf-client:4.0-SNAPSHOT<\/code>). Finally, this hardshell problem is not really documented and sadly, Java EE 7 tutorial sample code is only accessible as part of a bundle and not independently for quick access. <\/p>\n<p>So my plan, is to leave this <code>JMS async<\/code> project as part of the book&#8217;s code distribution. I am sorry that the code does not work at all. This code should work as a single integration test in the reference implementation GlassFish and Arquillian. I have no more time to devote it, but I will exclude building it (because the test fails) in the new Gradle dynamic task sub-project enhancements, which I am currently writing now. <\/p>\n<p>\ud83d\ude10  +PP+<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Well I going to have to leave this one for somebody who is more expert than me, because I have more things to do with my time now. I had a question from a reader about the source code for Java EE 7 Developer Handbook. Does JMS 2.0 standalone work as a client? What I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[75,110,143,40],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1333"}],"collection":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=1333"}],"version-history":[{"count":2,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1333\/revisions"}],"predecessor-version":[{"id":1335,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1333\/revisions\/1335"}],"wp:attachment":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=1333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=1333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=1333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}