4 Replies Latest reply: Sep 2, 2009 3:00 PM by Tom B RSS

    Injecting JMS Queue / Destination into MDB fails

      I am trying to inject a Destination into an EJB3 MDB using
          @Resource(name = "queue/abc/Responses")
          private Destination m_responseQueue;
      In the ejb-jar.xml file I declare the following
                  <!--Inherited From AbstractManagedBean -->
                  <!--Local Resources -->
      and in weblogic-ejb-jar.xml I add
              <!--Inherited From AbstractManagedBean -->
              <!--Local Resources -->         
      Initially I didn't have the resource-description in the weblogic-ejb-jar.xml file, but even after adding it I am still getting the following exception during deployment
      [EJB:011026]The EJB container failed while creating the java:/comp/env namespace for
       this EJB deployment. weblogic.deployment.EnvironmentException: 
      [EJB:010176]The resource-env-ref 'queue/abc/Responses' declared in the ejb-jar.xml 
      descriptor or annotation has no JNDI name mapped to it. The resource-ref must
      be mapped to a JNDI name using the resource-description element of the 
      weblogic-ejb-jar.xml descriptor or corresponding annotation.
           at weblogic.ejb.container.deployer.EnvironmentBuilder.addResourceEnvReferences(EnvironmentBuilder.java:639)
           at weblogic.ejb.container.deployer.EJBDeployer.setupEnvironmentContext(EJBDeployer.java:247)
           at weblogic.ejb.container.deployer.EJBDeployer.setupEnvironmentFor(EJBDeployer.java:1014)
           at weblogic.ejb.container.deployer.EJBDeployer.setupBeanInfos(EJBDeployer.java:908)
           at weblogic.ejb.container.deployer.EJBDeployer.prepare(EJBDeployer.java:1188)
           at weblogic.ejb.container.deployer.EJBModule.prepare(EJBModule.java:425)
      By injecting a Queue rather then a destination I can work around this issue, however I would prefer to use a Destination as this allows me to change the behavior of my application without making code changes. It seems like a bug in 10.3 to me.

      Edited by: ejb3workshop on Sep 1, 2009 1:44 PM

      Edited by: ejb3workshop on Sep 1, 2009 1:59 PM

      Edited by: ejb3workshop on Sep 2, 2009 3:11 PM
        • 1. Re: Injecting Destination fails
          I even tried using :
          in weblogic-ejb-jar.xml, as well as
          in ejb-jar.xml, however I am still not able to deploy and start my application. Using resource-env-description instead of resource-description caused the application to fail during startup with "Responses is already bound".
          • 2. Re: Injecting Destination fails
            I tried specifying the resource injection via the deployment descriptor rather then via annotations.
            This let's me deploy the application however during startup of the application the following exception occurs:
            <Sep 2, 2009 12:57:34 PM BST> <Info>
            <org.springframework.web.servlet.DispatcherServlet> <BEA-000000> <FrameworkServlet 'abc': initialization completed in 1321 ms> Startup Servlet Initialised <Sep 2, 2009 12:57:34 PM BST> <Emergency> <com.abc.backend.utilities.ConfigurationMonitor> <BEA-000000> <EJB
            Exception: ; nested exception is:
            Dependency injection failure: can't find the bean definition about class interface javax.jms.Queue; nested exception is
            No unique bean of type [javax.jms.Queue] is defined: No beans of type javax.jms.Queue;
            I am not quite sure what to make of this exception.

            Edited by: ejb3workshop on Sep 2, 2009 1:10 PM
            • 3. Re: Injecting JMS Queue / Destination into MDB fails
              user161771 - oracle
              Perhaps you can explain exactly what you are trying to accomplish or include the full source code for your MDB.

              There are MDB samples using EJB3 here:

              As you can see in the example, it does not require you to use a Destination object, rather that is configured as annotations via MappedName with an activationConfig and associated activationConfigProperty.

              There is also an EJB specific forum.
              • 4. Re: Injecting JMS Queue / Destination into MDB fails
                Tom B
                Because JMS resources by the very nature are "undependable", I think it is usually not advisable to inject JMS resources into an EJB except for MDB source destinations. The problem with injection of JMS resources is that if the JMS resource is not available at the point the EJB is originally deployed/initialized, the EJB deployment/initializaition will fail (except for MDBs, which will still deploy if the source is down, and will automatically retry internally). This is goodness for many types of resources, but since JMS resources are not necessarily always available by their very nature (down for maintenance, in the middle of a migration, initializing later in the boot, etc), most messaging applications should be specifically designed to be robustly handle the failure case during runtime.

                Anyhow, EJB3 does not require descriptors.

                I haven't fully vetted the following samples, but I think they should be pretty close to correct.

                Sample MDB code:
                // MDB will still deploy even if the source destination is down (the container will keep retrying internally).
                @MessageDriven(mappedName = "Server1Q1", 
                                        activationConfig = {@ActivationConfigProperty(
                                                                      propertyName = "connectionFactoryJndiName",
                                                                      propertyValue = "Server1CF")})
                public class MyMDB implements MessageListener {
                  private MyStateless myStateless;
                  public void onMessage(Message message) {
                    System.out.println("Got the message, version 5: "+message);
                Sample injected JMS resources - no resource descriptors needed:
                public class MyStatelessBean implements MyStateless {
                  int ctr;
                  private Queue queue1;
                  private QueueConnectionFactory connectionFactory2;
                Sample pseudo-code for non-injected JMS resources, no resource descriptors needed:
                Eg, instead of 
                 private QueueConnectionFactory cf;
                Do this:
                  // note the semi-colon!  turns off injection, note the type field -- required
                  // I'm not sure of exact syntax
                  //cfadmin is assumed to be the JNDI name if the
                  // JNDI name isn't specified in another parameter...  
                  @Resource(mappedName="cfadmin", type="javax.jms.QueueConnectionFactory");   
                  // this is not injected now
                  // cache cf for re-use (performance) 
                  private QueueConnectionFactory cf;
                  private SessionContext sctx;  // inject the session ctx
                And in the source code itself, do this:
                   int tryCount == 3;  
                   while (cf != null) {
                     try {  
                       // not quite sure if this is the righ syntax, but I think "java:/comp/env" prefix 
                       // isn't needed for the new EJB3.0 session context
                       cf = sctx.lookup("cfadmin");  //cfadmin is mappedname for resource above
                     } catch (NNN n) {  // don't know the exact exception
                       if (--tryCount == 0) throw n;
                       sleep 3 seconds  // don't want to retry in a tight loop