jmswebsphere-libertysolaceopen-liberty

Configuring the jmsConnectionFactory in server.xml for solace resource adapter doesn't work


I am trying to integrate solace with web sphere liberty 20 version using ejb2 and solace Resource adapter. I have configured MDB bean in ejb which listens to a queue. I am able to get the messages on the MDB, but while processing I need to publish the response back to a queue and this queue name is dynamic based on the messages from the upstream system. So I can not configured publisher as stateless bean in container.

Now I want to use the connection factory in publisher code which is configured in server.xml for MDB using solace resource adapter.

I have tried the following way.

in server.xml:

   <featureManager>
    <feature>javaee-8.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>jndi-1.0</feature>
    <feature>wasJmsClient-2.0</feature>
    <feature>wasJmsServer-1.0</feature>
    <feature>wasJmsSecurity-1.0</feature>
    <feature>mdb-3.2</feature>
    <feature>servlet-4.0</feature>
    <feature>ejb-3.2</feature>
    <feature>ejbHome-3.2</feature>
    <feature>adminCenter-1.0</feature>
    <feature>jca-1.7</feature>  
    <feature>jms-2.0</feature>
    <feature>webProfile-8.0</feature>

<resourceAdapter autoStart="true" id="solace" location="sol-jms-ra-10.10.0.rar">
    <properties.solace ConnectionURL="URL" UserName="user1" Password="pwd" MessageVPN="TEST_VPN"/>
</resourceAdapter>

<jmsActivationSpec  id="JNDI/LISTENER">
    <properties.solace connectionFactoryJndiName="myCF" destination="queue" destinationType="javax.jms.Queue" />
</jmsActivationSpec >

<jmsConnectionFactory id="JNDI/J2C/CF" jndiName="JNDI/J2C/CF">
    <properties.solace ConnectionFactoryJndiName="myCF"/>
</jmsConnectionFactory>

and In my publisher code, doing jndi lookup as below.

 Context ctx = new InitialContext();
 connectionFactory = (QueueConnectionFactory) ctx.lookup("java:comp/env/JNDI/J2C/CF");
 connection = connectionFactory.createQueueConnection();

but getting the below exception

    javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:comp/env/JNDI/J2C/CF
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:355)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:370)
    at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:149)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)

can someone please help me here.


Solution

  • You need to define a binding from resource reference name java:comp/env/JNDI/J2C/CF to the configured jndiName, JNDI/J2C/CF.

    One standard way to do that is with an @Resource annotation in your web or ejb component that wants to look it up (you could also use the value injected by the @Resource annotation instead of the lookup). For example,

    @Resource(name = "java:comp/env/JNDI/J2C/CF", lookup = "JNDI/J2C/CF")
    QueueConnectionFactory qcf;
    
    

    Another approach that you can use instead to define the resource reference is to do so within your ejb-jar.xml file. For example,

    <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
              http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
              version="2.1">
      <enterprise-beans>
        <message-driven>
          <ejb-name>MyMessageDrivenBean</ejb-name>
          <ejb-class>org.example.MyMessageDrivenBean</ejb-class>
          <messaging-type>javax.jms.MessageListener</messaging-type>
          <transaction-type>Bean</transaction-type>
          <resource-ref>
            <res-ref-name>java:comp/env/JNDI/J2C/CF</res-ref-name>
            <res-type>javax.jms.QueueConnectionFactory</res-type>
            <res-auth>Container</res-auth>
            <res-sharing-scope>Shareable</res-sharing-scope>
            <lookup-name>JNDI/J2C/CF</lookup-name>
          </resource-ref>
        </message-driven>
      </enterprise-beans>
    </ejb-jar>
    

    or

    <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
              http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
              version="2.1">
      <enterprise-beans>
        <session>
          <ejb-name>MyStatelessBean</ejb-name>
          <ejb-class>org.example.MyStatelessBean</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Bean</transaction-type>
          <resource-ref>
            <res-ref-name>java:comp/env/JNDI/J2C/CF</res-ref-name>
            <res-type>javax.jms.QueueConnectionFactory</res-type>
            <res-auth>Container</res-auth>
            <res-sharing-scope>Shareable</res-sharing-scope>
            <lookup-name>JNDI/J2C/CF</lookup-name>
          </resource-ref>
        </session>
      </enterprise-beans>
    </ejb-jar>
    

    Also, given that you want a QueueConnectionFactory, you need to be using the jmsQueueConnectionFactory configuration element,

    <jmsQueueConnectionFactory id="JNDI/J2C/CF" jndiName="JNDI/J2C/CF">
        <properties.solace ConnectionFactoryJndiName="myCF"/>
    </jmsQueueConnectionFactory>