Enterprise Java
JNDI Enterprise Naming Conext (ENC) and Injection
Goals
Enterprise Java
• Configure applications using the JNDI Enterprise Naming Context (ENC)
v081029
2
Objectives • • • • •
Enterprise Java
JNDI ENC Overview JNDI ENC Lookup XML Population Annotation Population Dependency Injection
v081029
3
JNDI ENC Overview
Enterprise Java
• Component's individual address space • Holds references to values and objects in the environment • Theoretical equivalent to Unix soft links
– ln -s <some physical file path> $HOME/<my logical path> • Object's registered – EJB interfaces (local and remote) – JMS connection factories – JMS destinations – data sources – any JCA resource – primitive values
v081029
4
JNDI ENC and Injection
Enterprise Java
• Objects are placed in the component's JNDI ENC by the container • Components may look these values up
– using raw JNDI calls – using SessionContext convenience method – allows any nested component to also get the environment
• Components may have values injected into properties/fields. – fewer lines of code dedicated to lookups – inversion of control
v081029
5
Reading JNDI ENC
Enterprise Java
• JNDI InitialContext jndi = new InitialContext(); object = jndi.lookup(“java:comp/env/encname);
• SessionContext SessionContext ctx; ... object = ctx.lookup(“encname”);
• Note: “java:comp/env” does not work with JBoss 4.0.xGA EJB3
– use “java:comp.ejb3/env” or SessionContext in the short term – works with 4.2.xGA
v081029
6
Example: Deployed JNDI Tree
Enterprise Java
• Local JNDI Namespace
+- ejavaDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
• Global JNDI Namespace – default names
+- jndiDemoEAR (class: org.jnp.interfaces.NamingContext) | +- Hospital (class: org.jnp.interfaces.NamingContext) | | +- local (... ejava.examples.jndidemo.ejb.HospitalLocal ...) | | +- remote (... ejava.examples.jndidemo.ejb.HospitalRemote ...)
– custom-configured JNDI names (jboss.xml) +- ejava (class: org.jnp.interfaces.NamingContext) | +- examples (class: org.jnp.interfaces.NamingContext) | | +- jndidemo (class: org.jnp.interfaces.NamingContext) | | | +- AidScheduler (class: org.jnp.interfaces.NamingContext) | | | | +- local (... ejava.examples.jndidemo.ejb.AidSchedulerLocal | | | | +- remote (... ejava.examples.jndidemo.ejb.AidSchedulerRemote
v081029
7
XML Population: Example POJO Style
Enterprise Java
//@Local declared by ejb-jar.xml entry public interface HospitalLocal extends Scheduler {} //@Remote declared by ejb-jar.xml entry public interface HospitalRemote extends Scheduler {} //@Stateless(name=”Hospital”) declared by ejb-jar.xml entry public class HospitalEJB extends SchedulerBase implements HospitalLocal, HospitalRemote { public String getName() { return "HospitalEJB"; } @Resource public void setSessionContext(SessionContext ctx) { this.ctx = ctx; } } //@Local declared by ejb-jar.xml entry public interface AidSchedulerLocal extends Scheduler {} //@Remote declared by ejb-jar.xml entry public v081029 interface AidSchedulerRemote extends Scheduler {}
8
XML Population: Example POJO Style
Enterprise Java
//@Stateless(name=”AidScheduler”) declared by ejb-jar.xml entry public class AidSchedulerEJB extends SchedulerBase implements AidSchedulerLocal, AidSchedulerRemote { private EntityManager em; private DataSource ds; private String message; private HospitalLocal hospital; @Resource //in super - protected SessionContext ctx; public void setSessionContext(SessionContext ctx) { this.ctx = ctx; } public void init() { log.info("************* AidScheduler Created ************"); log.debug("ctx=" + ctx); log.debug("ejb/hospital=" + ctx.lookup("ejb/hospital")); log.debug("message=" + message); log.debug("em=" + em); log.debug("ds=" + ds); log.debug("hospital=" + hospital); } public String getName() { return "AidScheduler"; } }v081029
9
XML Population: Example Output
Enterprise Java
[AidSchedulerEJB] ******************* AidScheduler Created ****************** DEBUG [AidSchedulerEJB] ctx=org.jboss.ejb3.BaseSessionContext@5f6ac6 DEBUG [AidSchedulerEJB] ejb/hospital=Hospital DEBUG [AidSchedulerEJB] message=Hello Helping World DEBUG [AidSchedulerEJB] em=org.jboss.ejb3.entity.TransactionScopedEntityManager@16fa2a5 DEBUG [AidSchedulerEJB] ds=org.jboss.resource.adapter.jdbc.WrapperDataSource@ede19e DEBUG [AidSchedulerEJB] hospital=Hospital DEBUG [JNDIHelper] listing java:comp/env ... listing java:comp/env +jdbc :org.jnp.interfaces.NamingContext ----myds :javax.naming.LinkRef +ejb :org.jnp.interfaces.NamingContext ----hospital :javax.naming.LinkRef +persistence :org.jnp.interfaces.NamingContext ----jndidemo :org.jboss.ejb3.entity.TransactionScopedEntityManager +vals :org.jnp.interfaces.NamingContext ----message :java.lang.String
v081029
10
XML Population: META-INF/ejb-jar.xml Enterprise Java
<ejb-jar 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" version="3.0"> <enterprise-beans> ... <session> <ejb-name>Hospital
ejava.examples.jndidemo.ejb.HospitalRemote ejava.examples.jndidemo.ejb.HospitalLocal <ejb-class>ejava.examples.jndidemo.ejb.HospitalEJB
v081029
11
XML Population: META-INF/ejb-jar.xml Enterprise Java
<enterprise-beans> <session> <ejb-name>AidScheduler
ejava.examples.jndidemo.ejb.AidSchedulerRemote ejava.examples.jndidemo.ejb.AidSchedulerLocal <ejb-class>ejava.examples.jndidemo.ejb.AidSchedulerEJB <post-construct>
init
v081029
12
XML Population: env-entry
Enterprise Java
<env-entry> <env-entry-name>vals/message <env-entry-type>java.lang.String <env-entry-value>Hello Helping World
ejava.examples.jndischeduler.ejb.AidSchedulerEJB message
v081029
13
XML Population: ejb-local-ref
Enterprise Java
<ejb-local-ref> <ejb-ref-name>ejb/hospital <ejb-ref-type>Session
ejava.examples.jndischeduler.ejb.HospitalLocal <ejb-link>Hospital
ejava.examples.jndischeduler.ejb.AidSchedulerEJB hospital
v081029
14
XML Population: DataSource
Enterprise Java
jdbc/myds javax.sql.DataSource Container ejava.examples.jndidemo.ejb.AidSchedulerEJB ds
v081029
15
XML Population: EntityManager
Enterprise Java
persistence/jndischeduler jndischeduler Transaction ejava.examples.jndischeduler.ejb.AidSchedulerEJB em
v081029
16
Enterprise Java
XML JNDI mapping META-INF/jboss.xml <jboss 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://www.jboss.org/j2ee/schema/jboss_5_0.xsd" version="3.0"> <enterprise-beans> <session> <ejb-name>AidScheduler <jndi-name> ejava/examples/jndidemo/AidScheduler/remote
ejava/examples/jndidemo/AidScheduler/local jdbc/myds <jndi-name>java:/ejavaDS v081029
17
Example: Deployed JNDI Tree
Enterprise Java
• Local JNDI Namespace
+- ejavaDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
• Global JNDI Namespace – default names +- jndiDemoEAR (class: org.jnp.interfaces.NamingContext) | +- CookEJB (class: org.jnp.interfaces.NamingContext) | | +- local (.. ejava.examples.jndidemo.ejb.CookLocal ...) | +- BakeScheduler (class: org.jnp.interfaces.NamingContext) | | +- remote (class: java.lang.Object) | | +- remoteStatefulProxyFactory (... org.jboss.ejb3.ProxyFactory)
v081029
18
Annotation Population: Example Entities
Enterprise Java
@Local public interface CookLocal extends Scheduler {} @Stateless public class CookEJB extends SchedulerBase implements CookLocal { public String getName() { return "CookEJB"; } @Resource protected void setSessionContext(SessionContext ctx) { super.ctx = ctx; } }
@Remote public interface BakeSchedulerRemote extends Scheduler {}
v081029
19
Annotation Population: Example Java Class
Enterprise Java
@Stateful(name="BakeScheduler") @EJBs({ @EJB(name="ejb/cook", beanInterface=CookLocal.class, beanName="CookEJB") }) @PersistenceContext(unitName="jndischeduler", name="persistence/jndischeduler", type=PersistenceContextType.EXTENDED) public class BakeSchedulerEJB extends SchedulerBase implements BakeSchedulerRemote { @Resource(name=”persistence/jndischeduler”) private EntityManager em; @Resource(mappedName=”java:/ejavaDS”) private DataSource ds; @Resource protected void setSessionContext(SessionContext ctx) { super.ctx = ctx; } v081029
20
Annotation Population: Example Java Class
Enterprise Java
@Resource(name=”ejb/cook”) protected CookLocal cook; @Resource(name="vals/message") String message; @PostConstruct public void init() { log.info("********* BakeScheduler Created ********"); log.debug("ctx=" + ctx); log.debug("ejb/cook=" + ctx.lookup("ejb/cook")); log.debug("em=" + em); log.debug("ds=" + ds); log.debug("persistence/jndischeduler=" + ctx.lookup("persistence/jndischeduler")); log.debug("message=" + message); log.debug("cook=" + cook); } } v081029
21
Annotation Population: Example Output
Enterprise Java
BakeSchedulerEJB] ******************* BakeScheduler Created ****************** [BakeSchedulerEJB] ctx=org.jboss.ejb3.BaseSessionContext@a1a602 [BakeSchedulerEJB] ejb/cook=CookEJB [BakeSchedulerEJB] em=org.jboss.ejb3.entity.ExtendedEntityManager@16b3939 [BakeSchedulerEJB] ds=org.jboss.resource.adapter.jdbc.WrapperDataSource@155bd22 [BakeSchedulerEJB] persistence/jndidemo=org.jboss.ejb3.entity.ExtendedEntityManager@16b3939 [BakeSchedulerEJB] message=null [BakeSchedulerEJB] cook=null [BakeSchedulerEJB] cook2=CookEJB [JNDIHelper] listing java:comp/env +env :org.jnp.interfaces.NamingContext +ejb :org.jnp.interfaces.NamingContext ---cook :javax.naming.LinkRef +ejava.examples.jndidemo.ejb.BakeSchedulerEJB :org.jnp.interfaces.NamingContext ---ds :javax.naming.LinkRef +persistence :org.jnp.interfaces.NamingContext ---jndidemo :org.jboss.ejb3.entity.ExtendedEntityManager
v081029
22
Dependency Injection
Enterprise Java
• fields
– simple, less verbose
• property setter
– easier to plug into unit tests – no need for getter – inheritance supported
v081029
23
Summary
Enterprise Java
• Populate – XML – Annotations
• Lookup – JNDI – SessionContext
• Property Assignment – Lookup – Dependency Injection
v081029
24
References
Enterprise Java
• “Enterprise JavaBeans 3.0, 5th Edition”; Burke & Monsen-Haefel; ISBN 0-596-00978-X; O'Reilly
v081029
25