3 Replies Latest reply on Dec 12, 2006 8:20 AM by marco.pehla

    EJB 3.0 String injection at deploying time?

    marco.pehla

      Hello,

      I'm a JBoss & EJB3 beginner and currently writing on a web service. I want to inject a simple String at deploying time that should hold a web address. I don't want to hard code this very web address inside of my EJB in order to be independed if the web address changes. Inside of the EJB I want to get the value of the injected String via JNDI. I've read that it should be possible to inject primitive types with the ejb-jar.xml deployment descriptor. (I know that a String is not really a primitive type, more a array of char's.)

      Does anybody have an example code or a link that helps me?


      with kind regards,
      Marco

        • 1. Re: EJB 3.0 String injection at deploying time?

          These types of configurable properties are called environment entries . The bean can use environment entries to customize its behavior.

          Although they can be defined using annotations, environment entries are almost always configured via XML, as they really are configuration values and not metadata. The <env-entry> element is used to define them. This element contains the subelements (optional), <env-entry-name> (required), <env-entry-type> (required), and <env-entry-value> (optional), as well as the element <injection-target> (optional). Here is a typical <env-entry> declaration:

          <ejb-jar>
          <enterprise-beans>

          <ejb-name>ProcessPaymentBean</ejb-name>
          <env-entry>
          <env-entry-name>minCheckNumber
          </env-entry-name>
          <env-entry-type>java.lang.Integer</env-entry-type>
          <env-entry-value>2000</env-entry-value>
          </env-entry>
          </enterprise-beans>
          </ejb-jar>



          The <env-entry-name> element is relative to the java:comp/env context. For example, the minCheckNumber entry can be accessed using the path java:comp/env/minCheckNumber in a JNDI ENC lookup:

          InitialContext jndiContext = new InitialContext( );
          int minValue = (Integer) jndiContext.lookup("java:comp/env/minCheckNumber");


          Alternatively, it can be looked up with the EJBContext.lookup( ) method using the minCheckNumber name.

          <env-entry-type> can be of type String or one of the several primitive wrapper types, including Integer, Long, Double, Float, Byte, Boolean, and Short.

          <env-entry-value> is optional. The value can be specified by the bean developer or deferred to the application assembler or deployer.

          • 2. Re: EJB 3.0 String injection at deploying time?
            marco.pehla

            Thank you for your reply.

            Today I tested some things and after all I installed the a new version of JBoss 4.0.5.

            javax.naming.NameNotFoundException: env not bound
            


            So that tells me that the env namespace is not bound, but why? And how to solve? Maybe JBoss doesn't find the jndi.properties file and this is the reason why it can't bound the right classes to the JBoss naming service?

            Here my EJB3: (after packaging inside the jar in the r2ml folder)
            ...
            @Stateless
            @WebService
            public class Webservice
            implements WebserviceInterface {
            
             public Webservice() {}
            
             @WebMethod
             public String translate(String sourceLanguage, String targetLanguage, String xmlInput) {
            
             try {
             javax.naming.Context initContext = new javax.naming.InitialContext();
             javax.naming.Context compEnv = (javax.naming.Context) initContext.lookup("java:comp/env");
             String str = "String: ";
             str += (String) compEnv.lookup("translationURL");
             System.out.println(str);
             } catch (Exception e) {
             System.out.println(e.toString());
             }//try-catch()
            
             return new Translator().translate(sourceLanguage, targetLanguage, xmlInput);
            }//translate()
            ...
            


            ejb-jar.xml : (after packaging inside the jar in the META-INF folder)
            ...
            <enterprise-beans>
             <session>
             <ejb-name>Webservice</ejb-name>
             <ejb-class>r2ml.Webservice</ejb-class>
             <env-entry>
             <env-entry-name>translationURL</env-entry-name>
             <env-entry-type>java.lang.String</env-entry-type>
             <env-entry-value>http://localhost/translations/</env-entry-value>
             </env-entry>
             </session>
             </enterprise-beans>
            ...
            


            jndi.properies (->after packaging the EJB jar, this file is in the same directory than the class files )

            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
            java.naming.provider.url=localhost:1099
            




            • 3. Re: EJB 3.0 String injection at deploying time?
              marco.pehla

              So, finially it works. I've made a mistake and put the ejb-jar.xml file in the EAR archive instead of the JAR archive.

              But I found out that it is much more easy to make a injection with the resource annotation.

              inside the EJB3:

              ...
              @Resource(mappedName="java:comp/env/translationURL") private String translationURL;
              ...
              @WebMethod
              public doSomething() {
               System.out.println("injected String: " + translationURL);
               ...
              }//doSomething()
              


              inside the ejb-jar.xml:
              ...
              <session>
               <ejb-name>YourClassName</ejb-name>
               <ejb-class>yourpackage.YourClassName</ejb-class>
               <env-entry>
               <env-entry-name>translationURL</env-entry-name>
               <env-entry-type>java.lang.String</env-entry-type>
               <env-entry-value>content of your String</env-entry-value>
               <injection-target>
               <injection-target-class>yourpackage.YourClassName</injection-target-class>
               <injection-target-name>translationURL</injection-target-name>
               </injection-target>
               </env-entry>
              </session>
              ...
              


              That's all. Really simple.