5 Replies Latest reply on Jul 8, 2009 4:08 AM by jaikiran

    Dependency injection is not working

      Hi guy,

      I start to be a bit confuse with the dependency injection. I really want to understand how this works.
      I try several thinkg and sometime it is working sometimes not.
      Basicaly I have an application (i.e. MM) which consists of a set of Message driven beans, beans, and entities that I want to used in another application (i.e. CMS) as a kind of sub-component.
      So I do include MM in CMS (the ejb-jar.xml, and persistence.xml file are used to "configurate" MM).
      For some reason MM need to know the application (e.g. CMS) that is using it so I used the ejb-jar.xml file and a <env-entry> specification in each of my message driven and other beans to specify this information.
      Each bean (message driven or others) in MM has a property (i.e. applicationName) annotated with @Resource and a get and set method to access it.
      It seems that the injection of the resource my approach is working only for message-driven bean but not the other beans and I do not understand why.

      MM is deploy within CMS on JBOSS with a .ear file which as this structure:


      CMS.EAR
       |--META-INF
       | |--application.xml
       |--CMC.jar (message driven and persitence beans)
       | |--META-INF
       | |--ejb-jar.xml
       |--CMejb.jar (entities classes)
       | |--META-INF
       | |--persistence.xml
       |--MMejb.jar (MM message driven beans)
       |--MSMejb.jar (MM entity classes and persistence beans)
       |--CMSweb.war (CMS servlet...)
       |--MMweb.war (MM Servlet ...)
      


      the application.xml in CMS.ear is:

      <application>
       <display-name>CMS</display-name>
       <module>
       <ejb>lib/cmsconfiguratorclient.jar</ejb>
       </module>
       <module>
       <ejb>CMC.jar</ejb>
       </module>
       <module>
       <ejb>CMejb.jar</ejb>
       </module>
       <module>
       <web>
       <web-uri>CMSweb.war</web-uri>
       <context-root>CARDWeb</context-root>
       </web>
       </module>
      
      <!-- MM -->
      
       <module>
       <ejb>MMweb.war</ejb>
       </module>
       <module>
       <ejb>MMejb.jar</ejb>
       </module>
       <module>
       <ejb>MSMejb.jar</ejb>
       </module>
      
      </application>
      


      the ejb-jar.xml in CMC is

      <?xml version="1.0" encoding="UTF-8"?>
      <ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
      
       <display-name>CMS</display-name>
       <enterprise-beans>
      
       <message-driven >
       <display-name>MessagerReceiver</display-name>
       <ejb-name>MessageReceiver</ejb-name>
       <ejb-class>com.messaging.messagemanager.receiving.MessageReceiver</ejb-class>
       <transaction-type>Container</transaction-type>
       <activation-config>
       <activation-config-property>
       <activation-config-property-name>destinationType</activation-config-property-name>
       <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
       </activation-config-property>
       <activation-config-property>
       <activation-config-property-name>destination</activation-config-property-name>
       <activation-config-property-value>queue/CMS</activation-config-property-value>
       </activation-config-property>
       </activation-config>
       <env-entry>
       <description>The name of the application</description>
       <env-entry-name>com.messaging.messagemanager.receiving.MessageReceiver/applicationName</env-entry-name>
       <env-entry-type>java.lang.String</env-entry-type>
       <env-entry-value>CMS</env-entry-value>
       </env-entry>
       </message-driven>
      
       <session>
       <ejb-name>IncomingMessageHandler</ejb-name>
       <ejb-class>com.ecebs.multefile.messaging.messagemanager.receiving.IncomingMessageHandler</ejb-class>
       <env-entry>
       <description>The name of the application</description>
       <env-entry-name>com.messaging.messagemanager.receiving.IncomingMessageHandler/applicationName</env-entry-name>
       <env-entry-type>java.lang.String</env-entry-type>
       <env-entry-value>CMS</env-entry-value>
       </env-entry>
       </session>
      
       <session>
       <ejb-name>MessageStoreManagerBean</ejb-name>
       <ejb-class>com.messaging.messagestoremanager.MessageStoreManagerBean</ejb-class>
       <env-entry>
       <description>The name of the application</description>
       <env-entry-name>com.messaging.messagestoremanager.MessageStoreManagerBean/applicationName</env-entry-name>
       <env-entry-type>java.lang.String</env-entry-type>
       <env-entry-value>CMS</env-entry-value>
       </env-entry>
       <persistence-context-ref>
       <persistence-context-ref-name>messagemanager_em</persistence-context-ref-name>
       <persistence-unit-name>messagemanager</persistence-unit-name>
       </persistence-context-ref>
       </session>
      
      
       </enterprise-beans>
      
      </ejb-jar>
      


      all beans from MM are defined here with the same <env-entry>. here I put only few of them to make it short.
      when I debug my application and send a mock message to the "MessagerReceiver" the "applicationName" is set with CMS so the dependency injection did work.
      When i simulate I use the IncomingMessageHandler bean, the applicationName is not set with the value specified in the ejb-jar.xml (i.e. CMS).

      here the code of the incomingMessageHandler bean and MessageReceiver message driven bean:
      @Stateless
      public class IncomingMessageHandler implements IIncomingMessageHandler{
      
       //...
      
       @Resource
       private String applicationName;
      
       public String getApplicationName() {
       return applicationName;
       }
      
       public void setApplicationName(String applicationName) {
       this.applicationName = applicationName;
       }
      
       //...
      }
      
      public class MessageReceiver implements MessageListener{
       //...
      
       @Resource
       private String applicationName;
      
       public String getApplicationName() {
       return applicationName;
       }
      
       public void setApplicationName(String applicationName) {
       this.applicationName = applicationName;
       }
      
       public void onMessage(Message message) {
       //...
       }
       //...
      


      a little help and explaination will be appreciated to understand what is wrong in my code/approach.
      Any good references/internet link that could help me to understand the structure of an ear file or how to use ejb-jar.xml and persistence.xml in ear are also welcome.

      Thanks a lot


        • 1. Re: Dependency injection is not working
          jaikiran

           

          <env-entry-name>com.messaging.messagemanager.receiving.IncomingMessageHandler/applicationName</env-entry-name>
          


          Change this to:

          <env-entry-name>applicationName</env-entry-name>


          The syntax that you used seems to be applicable when a injection-target is used instead of java annotations.

          Any good references/internet link that could help me to understand the structure of an ear file or how to use ejb-jar.xml and persistence.xml in ear are also welcome.


          Section 16.4.1 of the EJB3 spec has the details about the syntax and some examples.

          Having said that, i am surprised that you are seeing a different behaviour for MDBs. Let us know how that change goes.

          By the way, which version of JBoss AS do you use?


          • 2. Re: Dependency injection is not working

            Hi,

            thanks for answering.

            I did try to use only the name of the property within the env-entry definition ass you mentioned but I still have the same problem. Even worth, the message driven bean are not properly initialised. I need to do a look up of the context to get the appropriate value of the application name.

            in summary, if i do not include the package tath within the env-entry e.g.

            <env-entry-name>applicationName</env-entry-name>
            

            I need to lookup the context to get the application name set in the ejb-jar.xml. here the code in my session of my bean

            //...
            try {
             Context ctx = new InitialContext();
             Context envContext = (Context) ctx.lookup( "java:comp/env" );
             String appName = (String) envContext.lookup( "applicationName" );
             this.applicationName = appName;
            
            } catch (NamingException e){
             log.debug( "application name not found" );
            }
            


            if I include the full package path
            <env-entry-name>com.messaging.messagemanager.receiving.IncomingMessageHandler/applicationName</env-entry-name>
            


            I do not need to do a look up within my message driven bean.

            However within the other beans the injection does not work.

            I am not sure to understand how the injection work

            Thanks for you help



            • 3. Re: Dependency injection is not working
              jaikiran

              Which version of JBossAS do you use? Try this against AS 5.1.0

              • 4. Re: Dependency injection is not working

                Thanks for replying.
                I am using JBOSS 4.2.3_GA

                • 5. Re: Dependency injection is not working
                  jaikiran

                  Please try this on JBoss AS 5.1.0 GA