If you're looking for a good place to start learning how to create a Java Bean, look no further. This article explains how to create an entity bean. It is taken from chapter 4 of the book Enterprise JavaBeans 3.0 Fifth Edition, written by Richard Monson-Haefel and Bill Burke (O'Reilly, 2006; ISBN: 059600978X).
Developing Your First Beans - Creating a Client Application (Page 4 of 5 )
Now that the Cabin entity and TravelAgent EJBs have been deployed, we want to access them from a remote client. In this section, we create a remote client that connects to the EJB server, locates the EJB remote interface for the TravelAgent EJB, and interacts with the TravelAgent EJB to create and pull Cabin entities from the database. The following code shows a Java application that creates a new Cabin entity, sets its name, deckLevel , shipId , and bedCount properties, and then locates it again using its primary key:
public static Context getInitialContext() throws javax.naming.NamingException {
Properties p = new Properties(); // ... Specify the JNDI properties specific to the vendor. return new javax.naming.InitialContext(p); } }
To access an enterprise bean, a client starts by using JNDI to obtain a directory con nection to a beans container. JNDI is an implementation-independent API for directory and naming systems. Every EJB vendor must provide a directory service that is JNDI-compliant. This means that they must provide a JNDI service provider, which is a piece of software analogous to a driver in JDBC. Different service providers connect to different directory servicesnot unlike JDBC, where different drivers connect to different relational databases. The getInitialContext() method uses JNDI to obtain a network connection to the EJB server.
The code used to obtain a JNDI context depends on which EJB vendor you use. Consult your vendors documentation to find out how to obtain a JNDI context appropriate to your product. For example, the code used to obtain a JNDI context in WebSphere might look something like the following:
public static Context getInitialContext( ) throws javax.naming.NamingException {
java.util.Properties properties = new java.util.Properties(); properties.put(javax.naming.Context.PROVIDER_URL, "iiop:///"); properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.ibm.ejs.ns.jndi. CNInitialContextFactory"); return new InitialContext(properties); }
The same method developed for JBoss would be different:
public static Context getInitialContext() throws javax.naming.NamingException {
Properties p = new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces. NamingContextFactory"); p.put(Context.URL_PKG_PREFIXES, " org.jboss.naming:org.jnp. interfaces"); p.put(Context.PROVIDER_URL, "jnp://localhost:1099"); return new javax.naming.InitialContext(p); }
Once a JNDI connection is established and a context is obtained from the getInitialContext() method, the context can be used to look up the remote interface of the TravelAgent EJB:
Throughout this book, well use lookup names like "TravelAgentBean/remote"for remote client applications. The actual name you use to do a lookup may be differ ent, depending on the requirements of your vendor. You will need to bind a lookup name to the EJB servers naming service, and some vendors may require a special directory path or provide a default binding.
If you are using a standard Java EE component (Servlet, JSP, EJB, or Java EE Application Client), you will not need to set the properties explicitly when creating a JNDI InitialContext , no matter which EJB vendor you are using. Thats because the JNDI properties can be configured at deployment time and are applied automatically. A Java EE component would obtain its InitialContext as follows:
public static Context getInitialContext( ) throws javax.naming.NamingException {
return new javax.naming.InitialContext(); }
This is simpler and more portable than configuring JNDI properties for simple Java clients. All Java EE components use the same JNDI naming system that enterprise beans use to look up any service. Specifically, they require that EJB references be bound to the "java:comp/env/ejb/" namespace. For example, for a different Java EE component like a servlet, heres all we need to look up the TravelAgent EJB:
At deployment time, you would use the vendors deployment tools to map that JNDI name to the TravelAgent EJBs remote interface. In later sections, well see that spe cial annotations allow you to inject EJB references directly into the bean class. We already saw an example of one of them when the EntityManager service was injected into the TravelAgentBean class. In this book, Java client applications will need to use explicit parameters for JNDI lookups. As an alternative, you could use a special Java EE component called a Java EE Application Client, but this type of component is outside the scope of this book. For more information about Java EE Application Client components, consult the Java EE 5 specification.
The Client application uses the PortableRemoteObject.narrow() method to narrow the Object ref to a TravelAgentRemote reference:
Object ref = jndiContext.lookup("TravelAgentRemote"); CabinHomeRemote home = (TravelAgentRemote) PortableRemoteObject.narrow(ref,TravelAgentRemote.class);
The PortableRemoteObject.narrow() method was first introduced in EJB 1.1 and continues to be used on remote clients in EJB 3.0. It is needed to support the requirements of RMI over IIOP. Because CORBA supports many different languages, casting is not native to CORBA (some languages dont have casting). Therefore, to get a remote reference to TravelAgentRemote , we must explicitly narrow the object returned from lookup() .
The name used to find the TravelAgent EJB's remote interface is set by a vendor-specific default value, a vendor-specific annotation or deployment descriptor, or the deployer using a deployment wizard if one exists for that EJB product. The JNDI name is entirely up to the person deploying the bean; it can be the same as the bean name set in the XML deployment descriptor, or something completely different.