Enterprise Java Development@TOPIC@

Chapter 56. Configure EJB using Injection of ENC Resources

56.1. Setup
56.2. Inject Resources
56.3. Summary

In this section we will remove the specification of the JNDI lookups from the EJB bean class and perform injections indirectly through the JNDI ENC context populated by one of the XML deployment descriptors. We will again...

We will primarily be working with the following files

src/
|-- main
|   |-- java
|   |   `-- org
|   |       `-- myorg
|   |           `-- encconfig
|   |               `-- ejb
|   |                   `-- ENCAuditorEJB.java
|   `-- resources
|       `-- META-INF
|           `-- ejb-jar.xml
`-- test
    |-- java
    |   `-- org
    |       `-- myorg
    |           `-- encconfig
    |               `-- auditor
    |                   `-- ejb
    |                       `-- it
    |                           `-- ENCAuditorEJBIT.java
  1. Activate the ENCAuditorEJBIT test case. Since this test case extends the same base class as the previous test case (where we activated all the test methods) all test methods will immediately become active.

    //TODO enc-config 11: activate this testcase 
    
    @Ignore
    public class ENCAuditorEJBIT extends AuditorCheckerITBase {
  2. Re-run the IT tests for the EJB module. The test case you just activated above will fail with several errors

    java.lang.AssertionError: publishJMS value not injected
    java.lang.AssertionError: persistence context not injected
    java.lang.AssertionError: topic not injected
    java.lang.AssertionError: connection factory not injected
    java.lang.AssertionError: EJB not properly initialized expected:<2> but was:<0>
  3. Correct the first issue by injecting the value from the JNDI ENC placed there by the META-INF/ejb-jar.xml

    
    <session>
        <ejb-name>ENCAuditorEJB</ejb-name>
        <env-entry>
            <env-entry-name>val/publishJMS</env-entry-name>
            <env-entry-type>java.lang.Boolean</env-entry-type>
            <env-entry-value>true</env-entry-value>
        </env-entry>
    ...
    </session>

    Follow that up by injecting the the ENC name into the publishJMS property in the ENCAuditorEJB. We would have encountered a deployment error if this was not defined first.

    @Stateless
    
    public class ENCAuditorEJB extends AuditorBase 
    ...
    //TODO enc-config 12: define a resource value ENC injection
    //@Resource(name="val/publishJMS")
    private Boolean publishJMS;
  4. Re-deploy the EJB module using the maven cargo plugin

    $ mvn pre-integration-test
  5. Re-run the IT tests. The test you addressed above should now pass.

  6. Correct the next issue by injecting the persistence context from the JNDI ENC placed there by the META-INF/ejb-jar.xml

    
    <persistence-context-ref>
        <persistence-context-ref-name>jpa/em</persistence-context-ref-name>
        <persistence-unit-name>encconfig-lab</persistence-unit-name>
    </persistence-context-ref>

    The value is injected within ENCAuditorEJB using the @javax.persistence.PersistenceContext annotation

    @Stateless
    
    public class ENCAuditorEJB extends AuditorBase 
    ...
    //TODO enc-config 13: define a persistence context ENC injection
    //@PersistenceContext(name="jpa/em")
    private EntityManager em;

    Notice how the EJB class now knows less about the specific name of the persistence unit and simply accepts whatever is assigned to the logical name in the ENC. Now that we have this information in an XML file -- this opens up the possibility to change this assignment at build time through the manipulation of the XML file during the resource copy.

  7. Re-deploy the EJB module using the maven cargo plugin

    $ mvn pre-integration-test
  8. Re-run the IT tests. The test you addressed above should now pass.

  9. Correct the next issue by injecting the JMS topic from the JNDI ENC placed there by the META-INF/ejb-jar.xml

    
    <resource-env-ref>
        <resource-env-ref-name>jms/topic</resource-env-ref-name>
        <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
        <lookup-name>java:/topic/test</lookup-name>
    </resource-env-ref>

    This element uses a resource-env-ref since it is a value and not an object the container will communicate with.

    The value is injected within ENCAuditorEJB using the @javax.annotation.Resource annotation

    @Stateless
    
    public class ENCAuditorEJB extends AuditorBase 
    ...
    //TODO enc-config 14: define a resource-env ENC injection
    //@Resource(name="jms/topic")
    private Topic topic;
  10. Re-deploy the EJB module using the maven cargo plugin

    $ mvn pre-integration-test
  11. Re-run the IT tests. The test you addressed above should now pass.

  12. Correct the next issue by injecting the JMS connection factory from the JNDI ENC placed there by the META-INF/ejb-jar.xml

    
    <resource-ref>
        <res-ref-name>jms/cf</res-ref-name>
        <res-type>javax.jms.ConnectionFactory</res-type>
        <lookup-name>java:/JmsXA</lookup-name>
    </resource-ref>

    This element uses a resource-ref since it is an object the container will communicate with.

    The value is injected within ENCAuditorEJB using the @javax.annotation.Resource annotation

    @Stateless
    
    public class ENCAuditorEJB extends AuditorBase 
    ...
    //TODO enc-config 15: define a resource ENC injection
    //@Resource(name="jms/cf")
    private ConnectionFactory cf;
  13. Re-deploy the EJB module using the maven cargo plugin

    $ mvn pre-integration-test
  14. Re-run the IT tests. The test you addressed above should now pass.

  15. Correct the last issue by activating the EJB's @PostConstruct method so that it gets called after the resources have been injected. The method is activated within ENCAuditorEJB using the @javax.annotation.PostConstruct annotation

    @Stateless
    
    public class ENCAuditorEJB extends AuditorBase 
    ...
    //TODO enc-config 16: activate this method after injection
    //@PostConstruct
    public void init() {
        super.setLog(log);
        super.setConnectionFactory(cf);
        super.setEntityManager(em);
        super.setTopic(topic);
        super.setPublishJMS(isPublishJMS());
    }
  16. Re-deploy the EJB module using the maven cargo plugin

    $ mvn pre-integration-test
  17. Re-run the IT tests. All tests associated with this test case should now be passing.

You have finished injecting resources into your EJB bean using resources populated in the JNDI ENC using the META-INF/ejb-jar.xml.

In this chapter you successfully injected a value, persistence context, and administered resources into the EJB using the JNDI ENC. This technique allowed the actual JNDI names be abstracted away from the Java class and moved into an XML deployment descriptor where it can either be defined or form an override for the value in the Java class. Next we will take a look at a more programmatic way to access the JNDI ENC values that can make them available to any class within the EJB bean's scope.