Search
Calendar
November 2017
S M T W T F S
« Sep    
 1234
567891011
12131415161718
19202122232425
2627282930  
Your widget title
Archives

Posts Tagged ‘JMS’

PostHeaderIcon Tutorial: Tomcat / OpenJMS integration

Install and Config

  • Let’s assume you would like to run OpenJMS and Tomcat on the same server, eg myLocalServer
  • Download OpenJMS from this page.
  • Unzip the archive, extract it to C:\exe\openjms-0.7.7-beta-1
  • Set an environment variable:set OPENJMS_HOME=C:\exe\openjms-0.7.7-beta-1
  • Take the archive $OPENJMS_HOME/lib/openjms-tunnel-0.7.7-beta-1.war
    • copy it to: $CATALINA_HOME/webapps
    • rename it as: openjms-tunnel.war
  • Edit OPENJMS_HOME/config/openjms.xml:
    • Before the ending tag</connectors>, add the block:
      <Connector scheme="http">
            <ConnectionFactories>
              <ConnectionFactory name="HTTPConnectionFactory"/>
            </ConnectionFactories>
       </Connector>
    • After the ending tag </connectors>, add the block:
      <HttpConfiguration port="3030" bindAll="true"
             webServerHost="myLocalServer" webServerPort="8080"
             servlet="/openjms-tunnel/tunnel"/>


Run applications

  • Launch $OPENJMS_HOME/bin/startup.bat. The following output is expected:
    OpenJMS 0.7.7-beta-1
    The OpenJMS Group. (C) 1999-2007. All rights reserved.
    http://openjms.sourceforge.net
    15:15:27.531 INFO  [Main Thread] - Server accepting connections on tcp://myLocalServer:3035/
    15:15:27.547 INFO  [Main Thread] - JNDI service accepting connections on tcp://myLocalServer:3035/
    15:15:27.547 INFO  [Main Thread] - Admin service accepting connections on tcp://myLocalServer:3035/
    15:15:27.609 INFO  [Main Thread] - Server accepting connections on rmi://myLocalServer:1099/
    15:15:27.609 INFO  [Main Thread] - JNDI service accepting connections on rmi://myLocalServer:1099/
    15:15:27.625 INFO  [Main Thread] - Admin service accepting connections on rmi://myLocalServer:1099/
    15:15:27.625 INFO  [Main Thread] - Server accepting connections on http-server://myLocalServer:3030/
    15:15:27.625 INFO  [Main Thread] - JNDI service accepting connections on http-server://myLocalServer:3030/
    15:15:27.625 INFO  [Main Thread] - Admin service accepting connections on http-server://myLocalServer:3030/
  • Launch Tomcat. A webapp with path /openjms-tunnel and display name “OpenJMS HTTP tunnel” should appear.


Checks

    • Open Console² or an MS-DOS prompt
    • Go to $OPENJMS/examples/basic
    • Run: build. This will compile all the examples.


Check that OpenJMS is OK:

    • Edit jndi.properties,
      • Comment the property
        java.naming.provider.url
      • Add the line:
        java.naming.provider.url=tcp://myLocalServer:3035
    • Run:
      run Listener queue1
    • Open a second tab
    • Run:
      run Sender queue1 5

      • Expected output in the second tab:
        C:\exe\openjms-0.7.7-beta-1\examples\basic>run Sender queue1 5
        Using OPENJMS_HOME: ..\..
        Using JAVA_HOME:    C:\exe\beaweblo922\jdk150_10
        Using CLASSPATH:    .\;..\..\lib\openjms-0.7.7-beta-1.jar
        Sent: Message 1
        Sent: Message 2
        Sent: Message 3
        Sent: Message 4
        Sent: Message 5
      • Expected output in the first tab:
        C:\exe\openjms-0.7.7-beta-1\examples\basic>run Listener queue1
        Using OPENJMS_HOME: C:\exe\openjms-0.7.7-beta-1
        Using JAVA_HOME:    C:\exe\beaweblo922\jdk150_10
        Using CLASSPATH:    .\;C:\exe\openjms-0.7.7-beta-1\lib\openjms-0.7.7-beta-1.jar
        Waiting for messages...
        Press [return] to quit
        Received: Message 1
        Received: Message 2
        Received: Message 3
        Received: Message 4
        Received: Message 5


Check that OpenJMS/Tomcat link is OK:


Manual Check

    • Stop the Listener instance launched sooner
    • Edit jndi.properties,
      • Comment the line
        java.naming.provider.url=tcp://myLocalServer:3035
      • Add the line:
        java.naming.provider.url=http://myLocalServer:8080

        (this is Tomcat manager URL)

    • Run: run Listener queue1
    • Open a second tab
    • Run:
      run Sender queue1 5
    • The expected output are the same as above.


GUI Check

  • Stop the Listener instance launched sooner
  • Ensure jndi.properties contains the line:
    java.naming.provider.url=http://myLocalServer:8080
  • Run: $OPENJMS_HOME/bin/admin.bat

    • A Swing application should start.
    • Go to:
      Actions > Connections > Online
    • The queue queue1 should be followed by a ‘0’.
    • Run: run Sender queue1 50

      • Action > Refresh
      • The queue queue1 should be followed by a ’50’.
    • Run: run Listener queue1

      • Action > Refresh
      • The queue queue1 should be followed by a ‘0’.

PostHeaderIcon java.io.StreamCorruptedException: invalid type code: 31

Context:

Client-server communication over JMS.

Stacktrace:

Caused by: java.rmi.UnmarshalException: failed to unmarshal class weblogic.security.acl.internal.AuthenticatedUser; nested exception is:
java.io.StreamCorruptedException: invalid type code: 31
at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:203)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:224)
at weblogic.common.internal.RMIBootServiceImpl_921_WLStub.authenticate(Unknown Source)
at weblogic.security.acl.internal.Security$1.run(Security.java:185)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
at weblogic.security.acl.internal.Security.authenticate(Security.java:181)
at weblogic.jndi.WLInitialContextFactoryDelegate.authenticateRemotely(WLInitialContextFactoryDelegate.java:726)
at weblogic.jndi.WLInitialContextFactoryDelegate.pushSubject(WLInitialContextFactoryDelegate.java:659)

Explanation – Fix

The client JVM was in version 1.6, the server was in 1.5.
To fix the issue, the client must be run with Java 1.5.
Possibly, the client may laucnh the JVM with the option -Dsun.lang.ClassLoader.allowArraySyntax=true.

PostHeaderIcon javax.naming.ConfigurationException / java.net.MalformedURLException

Context

I have to send JMS messages on queues on clustered servers: t3://firstServer:1234 and t3://secondServer:5678.

The destination queues are retrieved in Spring, thanks to a property like:

&lt;property name=&quot;providerURL&quot; value=&quot;t3://firstServer:1234,t3://secondServer:5678&quot;/&gt;

Error:

I receive the following error:

javax.naming.ConfigurationException [Root exception is java.net.MalformedURLException: port expected: t3://firstServer:1234,t3://secondServer:5678]

Explanation and fix:

When you send messages on many queues, you must not repeat the protocol (here: t3://)! Fixing the issue is very simple: you have to remove the second t3:// in Spring property:

&lt;property name=&quot;providerURL&quot; value=&quot;t3://firstServer:1234,secondServer:5678&quot;/&gt;

PostHeaderIcon java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[myRole]

Short stacktrace:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myJmsTemplate' (...) Invocation of init method failed; nested exception is java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[myRole]

Complete stacktrace

(copy paste in a text editor if the complete stack is not displayed in your browser):

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myJmsTemplate' defined in URL [zip:C:/workarea/development/servers/wl_server/servers/XXXX/tmp/_WL_user/XXXXXXXXXXXX-ear/7gtxm8/XXXXXXXX-services-ejb.jar!/com/XXXXX/businessApplicationContext-XXXXXXXX.xml]: Cannot resolve reference to bean 'myJmsQueueConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myJmsQueueConnectionFactory' defined in URL [zip:C:/workarea/development/servers/wl_server/servers/ejbtier/tmp/_WL_user/XXXXXX-ear/7gtxm8/XXXXXXXX.jar!/com/bnpparibas/primeweb/businessApplicationContextXXXXXXXXXXXX.xml]: Invocation of init method failed; nested exception is java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[myRole]
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:104)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1245)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
 at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:881)
(...)

The issue appears when I try to deploy an EJB sending JMS messages from my Weblogic server, to another one, in another domain.

Fix:

  • I have not fixed the issue myself, I gave pieces of advice to the teams in charge of solving them. But I assume following guidelines are OK.
  • Indeed there are two issues: one on credentials and another on servers
  • Servers need trust each other. More information is available here. I assume trust is granted thanks to the use of certificates.
  • On another hand, credentials from my server, it is to say here “myRole” must be accepted by distant Ldap juridiction. I assume that distant EJB environment must something like:
    • distantEnvironment.put(InitialContext.SECURITY_PRINCIPAL, "myRole");

Now it should work!

PostHeaderIcon Deploy a JMS destination queue with Spring

Abstract

Case: we have to send JMS messages to a third-party server, using Spring. Of course, we have to discriminate production, UAT and developments environments. We can decide to use one Spring configuration file per environment, but it is complex to maintain.

Here is the way I proceded:

Declare the factory

<bean id="myJmsQueueConnectionFactory">
    <property name="jndiName" value="my.jms.QueueConnectionFactory"/>
   <property name="jndiTemplate" ref="myJmsJndiTemplate"/>
 </bean>

Declare a Jndi Template

<bean id="myJmsJndiTemplate">
   <property name="environment">
     <props>
       <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
       <prop key="java.naming.provider.url"><strong>${my.jms.host}</strong></prop>
     </props>
   </property>
 </bean>

The variable ${my.jms.host} is used to indicate the actual destination host. The value is given in a property file myConfig.properties, for instance:

my.jms.host=t3://127.0.0.1:1234

Obviously, each environnement needs its ad hoc property file!

Declare a JMS Template

It gathers the factory and the queue name.

<bean id="myJmsTemplate">
  <property name="connectionFactory" ref="myJmsQueueConnectionFactory"/>
  <property name="defaultDestination" ref="myJmsQueue"/>
 </bean>

Declare the destination queue

<bean id="myJmsQueue">
 <property name="jndiName" value="my.jms.destination.queue.name"/>
</bean>

Ensure the property file is in classpath

<bean id="conf">
   <property name="locations">
   <list>
     <value>classpath*:myConfig.properties</value>
   </list>
  </property>
 </bean>

Restart WebLogic, deploy your EAR. Now it should work!

Notice: in case you’re not sure the distant host is up or not, you may add this attribute to your beans: lazy-init="true"