9 Replies Latest reply on Nov 17, 2009 12:51 PM by mnenchev

    How to load external parameters in ejb?

    mnenchev

      Hi,
      i implemented jboss->websphere jms messaging using resource adapter from websphere.
      In the ds.xml config file i declared ConnectionFactory with name TESTCF and queue with name TESTQUEUE. I need to lookup the ConnectionFactory and Queue objects in my message sender ejb, but i do need those names to be configurable. I wrote that this could be done with @Resource injection, and the names are configured in ejb-jar.xml?

      Can somebody help me with this, i need that to be configurable without to compile my source code on Change.
      Regards.

        • 2. Re: How to load external parameters in ejb?
          mnenchev

          Hi, thanks for the response.
          I looked at the tutorials and the code examples, and i did the following:
          1) In my ear meta-inf i created jboss.xml :

          <?xml version="1.0" encoding="UTF-8"?>
          
          <jboss>
           <enterprise-beans>
           <session>
           <ejb-name>QueueSenderBean</ejb-name>
          
           <resource-ref>
           <res-ref-name>CF.1</res-ref-name>
           <jndi-name>CF.1</jndi-name>
           </resource-ref>
          
           <resource-ref>
           <res-ref-name>CF.2</res-ref-name>
           <jndi-name>CF.2</jndi-name>
           </resource-ref>
          
           <resource-ref>
           <res-ref-name>CF.3</res-ref-name>
           <jndi-name>CF.3</jndi-name>
           </resource-ref>
          
           <resource-ref>
           <res-ref-name>QUEUE1</res-ref-name>
           <jndi-name>QUEUE1</jndi-name>
           </resource-ref>
          
           <resource-ref>
           <res-ref-name>QUEUE2</res-ref-name>
           <jndi-name>QUEUE2</jndi-name>
           </resource-ref>
          
           <resource-ref>
           <res-ref-name>QUEUE3</res-ref-name>
           <jndi-name>QUEUE3</jndi-name>
           </resource-ref>
           </session>
           </enterprise-beans>
          </jboss>


          2) After that i created ejb-jar.xml :
          <?xml version="1.0" encoding="UTF-8"?>
          <ejb-jar>
           <enterprise-beans>
           <session>
           <ejb-name>QueueSenderBean</ejb-name>
           <ejb-class>x.y.x.QueueSenderBean</ejb-class>
           <home>x.y.z.IQueueSenderLocal</home>
           <session-type>Stateless</session-type>
           <transaction-type>Container</transaction-type>
          
           <resource-ref>
           <description>Websphere Connection Factory</description>
           <res-ref-name>CF.1</res-ref-name>
           <res-type>javax.jms.QueueConnectionFactory</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
          
           <resource-ref>
           <description>Websphere Connection Factory</description>
           <res-ref-name>CF.2</res-ref-name>
           <res-type>javax.jms.QueueConnectionFactory</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
          
           <resource-ref>
           <description>Websphere Connection Factory</description>
           <res-ref-name>CF.3</res-ref-name>
           <res-type>javax.jms.QueueConnectionFactory</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
          
           <resource-ref>
           <description>Websphere Queue</description>
           <res-ref-name>Queue1</res-ref-name>
           <res-type>javax.jms.Queue</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
          
           <resource-ref>
           <description>Websphere Queue</description>
           <res-ref-name>Queue2</res-ref-name>
           <res-type>javax.jms.Queue</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
          
           <resource-ref>
           <description>Websphere Queue</description>
           <res-ref-name>Queue3</res-ref-name>
           <res-type>javax.jms.Queue</res-type>
           <res-auth>Container</res-auth>
           </resource-ref>
           </session>
           </enterprise-beans>
          </ejb-jar>
          


          3) Simple send method:
          // The method is in statless ejb :QueueSenderBean.java
          public void sendToQueue(Serializable obj, String queueName, String cf) {
           Connection queueConnection = null;
           Session queueSession = null;
           Queue queue = null;
           MessageProducer sender = null;
           try {
           final Context initCtx = new InitialContext();
           final ConnectionFactory qFactory = (ConnectionFactory) initCtx.lookup(queueName);
           queueConnection = qFactory.createConnection();
           queueSession = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
           queue = (Queue) initCtx.lookup(cf);
           sender = queueSession.createProducer(queue);
           log.debug("Sending message to " + queue);
           final Message msg = queueSession.createTextMessage((String) obj);
           sender.send(msg);
           } catch (final javax.jms.JMSException e) {
           log.error("send() -> JMS Error: ", e);
           } catch (final NamingException e) {
           log.error("sendToQueue() -> JNI Error: ", e);
           } catch (final Exception e) {
           log.error("sendToQueue() -> Error: ", e);
           } finally {
           try {
           if (queueConnection != null) {
           queueConnection.close();
           }
           if (queueSession != null) {
           queueSession.close();
           }
           queue = null;
           if (sender != null) {
           sender.close();
           }
           } catch (final Exception e) {
           log.error("sendToQueue() -> Error while closing resources: ", e);
           }
           }
           }


          And i call it like this:
          sender.sendToQueue(xml, "java:comp/env/QUEUE1", "java:comp/env/CF.1");


          • 3. Re: How to load external parameters in ejb?
            mnenchev

            Hi, PLEASE ignore my previous posts.
            Here is my last config:
            ejb-jar.xml

            <?xml version="1.0" encoding="UTF-8"?>
            <ejb-jar>
             <enterprise-beans>
             <session>
             <ejb-name>QueueSenderBean</ejb-name>
            
             <resource-env-ref>
             <resource-env-ref-name>AS.1.BFT_ORDERS</resource-env-ref-name>
             <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
             </resource-env-ref>
            
             <resource-ref>
             <description>JMS Connection Factory</description>
             <res-ref-name>CF.1</res-ref-name>
             <res-type>javax.jms.QueueConnectionFactory</res-type>
             <res-auth>Container</res-auth>
             <res-sharing-scope>Shareable</res-sharing-scope>
             </resource-ref>
             </session>
             </enterprise-beans>
            </ejb-jar>
            


            jboss.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <jboss>
             <enterprise-beans>
             <session>
             <ejb-name>IGBetQueueSenderBean</ejb-name>
            
             <resource-env-ref>
             <resource-env-ref-name>AS.1.BFT_ORDERS</resource-env-ref-name>
             <jndi-name>AS.1.BFT_ORDERS</jndi-name>
             </resource-env-ref>
             <resource-ref>
             <res-ref-name>CF.1</res-ref-name>
             <jndi-name>java:/CF.1</jndi-name>
             </resource-ref>
             </session>
             </enterprise-beans>
            </jboss>


            I try to send message like this:
            bean.send(xml, "java:comp/env/AS.1.BFT_ORDERS", "java:comp/env/CF.1");


            And here is my send method implementation:
            
            @Stateless
            public class QueueSenderBean implements ISenderLocal {
            
             private static final Logger log = Logger.getLogger(QueueSenderBean.class);
            
             public void sendToQueue(Serializable obj, String queueName, String cf) {
             Connection queueConnection = null;
             Session queueSession = null;
             Queue queue = null;
             MessageProducer sender = null;
             try {
             final Context initCtx = new InitialContext();
             final ConnectionFactory qFactory = (ConnectionFactory) initCtx.lookup(cf);
             queueConnection = qFactory.createConnection();
             queueSession = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             queue = (Queue) initCtx.lookup(queueName);
             sender = queueSession.createProducer(queue);
             log.debug("Sending message to " + queue);
             final Message msg = queueSession.createTextMessage((String) obj);
             sender.send(msg);
             } catch (final javax.jms.JMSException e) {
             log.error("send() -> JMS Error: ", e);
             } catch (final NamingException e) {
             log.error("sendToQueue() -> JNI Error: ", e);
             } catch (final Exception e) {
             log.error("sendToQueue() -> Error: ", e);
             } finally {
             try {
             if (queueConnection != null) {
             queueConnection.close();
             }
             if (queueSession != null) {
             queueSession.close();
             }
             queue = null;
             if (sender != null) {
             sender.close();
             }
             } catch (final Exception e) {
             log.error("sendToQueue() -> Error while closing resources: ", e);
             }
             }
             }
            
            }
            
            I got NamingException that says that CF.1 is not bound
            javax.naming.NameNotFoundException: CF.1 not bound
             at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
             at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
             at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
             at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
             at org.jnp.server.NamingServer.lookup(NamingServer.java:399)
             at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:726)
             at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:833)
             at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686)
             at javax.naming.InitialContext.lookup(InitialContext.java:392)
             at claire.ejb.logic.msg.beans.IGBetQueueSenderBean.sendToQueue(IGBetQueueSenderBean.java:40)
             at claire.ejb.logic.msg.beans.IGBetQueueSenderBean.send(IGBetQueueSenderBean.java:29)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:597)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
             at org.jboss.ejb3.EJBContainerInvocationWrapper.invokeNext(EJBContainerInvocationWrapper.java:69)
             at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorSequencer.java:73)
             at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(InterceptorSequencer.java:59)
             at sun.reflect.GeneratedMethodAccessor428.invoke(Unknown Source)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:597)
             at org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:174)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(InvocationContextInterceptor.java:72)
             at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_fillMethod_12384824.invoke(InvocationContextInterceptor_z_fillMethod_12384824.java)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:88)
             at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_12384824.invoke(InvocationContextInterceptor_z_setup_12384824.java)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:62)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:56)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:68)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.aspects.tx.TxPolicy.invokeInNoTx(TxPolicy.java:66)
             at org.jboss.ejb3.tx.TxInterceptor$NotSupported.invoke(TxInterceptor.java:114)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:176)
             at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:216)
             at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
             at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
            


            Here is my jndi view:
            java: Namespace
            
             +- CF.3 (class: com.ibm.mq.connector.outbound.ConnectionFactoryImpl)
             +- securityManagement (class: org.jboss.security.integration.JNDIBasedSecurityManagement)
             +- comp (class: javax.namingMain.Context)
             +- ClaireBLogicDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
             +- DeploymentManager (class: org.jboss.aop.generatedproxies.AOPProxy$4)
             +- CF.2 (class: com.ibm.mq.connector.outbound.ConnectionFactoryImpl)
             +- XAConnectionFactory (class: org.jboss.jms.client.JBossConnectionFactory)
             +- JBossCorbaInterfaceRepositoryPOA (class: org.omg.PortableServer.POA)
             +- JmsXA (class: org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl)
             +- CF.1 (class: com.ibm.mq.connector.outbound.ConnectionFactoryImpl)
            ...........
            Global JNDI Namespace
            
             +- UserTransactionSessionFactory (proxy: $Proxy358 implements interface org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory)
             +- AS.2.BFT_ORDERS (class: com.ibm.mq.jms.MQQueue)
            ........
            


            Please ignore CF.2 and CF.3. I can't see any thing in the java:comp namespaces about my resources. I think that ejb can't lookup the res-ref-name CF.1.


            • 4. Re: How to load external parameters in ejb?
              jaikiran

              The ejb-name values in your ejb-jar.xml and jboss.xml do not match

              • 5. Re: How to load external parameters in ejb?
                mnenchev

                Yes, excuse me, i forgot to rename the second bean. That is not the problem.

                • 6. Re: How to load external parameters in ejb?
                  mnenchev

                  I think, res-ref-name>CF.1</res-ref-name> is not bound. When i lookup my connection factory with "java:comp/env/CF.1", jboss will search for resource with that name and will "return" the real jndi in my case "java:/CF.1" and that jndi will be used to lookup my connectionfactory (which i can see from the jndi view is bound). So i assume that the res-ref-name not used properly. Is there any way to see in the jmx console those res-ref-names, or something?

                  • 7. Re: How to load external parameters in ejb?
                    jaikiran

                     

                    bean.send(xml, "java:comp/env/AS.1.BFT_ORDERS", "java:comp/env/CF.1");


                    1) I assume that this is a typo in your post and you actually meant bean.sendToQueue. If it's not a typo then please post the exact code and config files, so that there's no confusion
                    2) How do you get hold of the "bean" in that code?

                    • 8. Re: How to load external parameters in ejb?
                      jaikiran

                       

                      "jaikiran" wrote:


                      1) I assume that this is a typo in your post and you actually meant bean.sendToQueue. If it's not a typo then please post the exact code and config files, so that there's no confusion
                      2) How do you get hold of the "bean" in that code?


                      Ignore, both those questions. The stacktrace that you posted has the answers to both those questions.

                      Could you please post the code in the send method (which invokes sendToQueue), just want to make sure there's nothing wrong in there?


                      • 9. Re: How to load external parameters in ejb?
                        mnenchev

                        Hi, here is the whole stateles bean class:

                        
                        @Stateless
                        public class QueueSenderBean implements ISenderLocal {
                        
                         private static final Logger log = Logger.getLogger(QueueSenderBean.class);
                        
                         @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                         public void send(final Serializable obj, String queueName, String cf) {
                         sendToQueue(obj, queueName, cf);
                         }
                        
                         @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                         private void sendToQueue(Serializable obj, String queueName, String cf) {
                         Connection queueConnection = null;
                         Session queueSession = null;
                         Queue queue = null;
                         MessageProducer sender = null;
                         try {
                         final Context initCtx = new InitialContext();
                         final ConnectionFactory qFactory = (ConnectionFactory) initCtx.lookup(cf);
                         queueConnection = qFactory.createConnection();
                         queueSession = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                         queue = (Queue) initCtx.lookup(queueName);
                         sender = queueSession.createProducer(queue);
                         log.debug("Sending message to " + queue);
                         final Message msg = queueSession.createTextMessage((String) obj);
                         sender.send(msg);
                         } catch (final javax.jms.JMSException e) {
                         log.error("send() -> JMS Error: ", e);
                         } catch (final NamingException e) {
                         log.error("sendToQueue() -> JNI Error: ", e);
                         } catch (final Exception e) {
                         log.error("sendToQueue() -> Error: ", e);
                         } finally {
                         try {
                         if (queueConnection != null) {
                         queueConnection.close();
                         }
                         if (queueSession != null) {
                         queueSession.close();
                         }
                         queue = null;
                         if (sender != null) {
                         sender.close();
                         }
                         } catch (final Exception e) {
                         log.error("sendToQueue() -> Error while closing resources: ", e);
                         }
                         }
                         }
                        
                        }
                        


                        I use TransactionAttributeType.NOT_SUPPORTED because i send messages to websphere in CLIENT transportType, which throws exceptions if this is done in transaction scope, so i added this attribute.
                        Regards.