Resources in J2EE Apps
Post on 18-Nov-2014
Embed Size (px)
Page 1 of 30
Resource ConnectionsDale Green Both enterprise beans and Web components can access a wide variety of resources, including databases, mail sessions, Java Message Service objects, and URLs. The J2EE platform provides mechanisms that allow you to access all of these resources in a similar manner. This chapter describes how to get connections to several types of resources. Although the code samples in this chapter are from enterprise beans, they will also work in Web components. In This Chapter JNDI Names and Resource References deploytool Tips for Resource References Database Connections for Enterprise Beans Coded Connections Connection Pooling Mail Session Connections Running the ConfirmerEJB Example URL Connections Running the HTMLReaderEJB Example
JNDI Names and Resource ReferencesFirst, let's define some terms. JNDI is the acronym for the Java Naming and Directory Interface API. J2EE components locate objects by invoking the JNDI lookup method. A JNDI name is a people-friendly name for an object. These names are bound to their objects by the naming and directory service that is provided by the J2EE server. Because J2EE components access this service through the JNDI API, we usually refer to an object's people-friendly name as its JNDI name. The JNDI name of the Cloudscape database is jdbc/Cloudscape. When it starts up, the J2EE server reads information from a configuration file and automatically adds JNDI database names such as jdbc/Cloudscape to the name space. A connection factory is an object that produces connection objects that enable a J2EE component to access a resource. The connection factory for a database is a javax.sql.DataSource object, which creates a java.sql.Connection object. A resource reference is an element in a deployment descriptor that identifies the component's coded name for the resource. More specifically, the coded name references a connection factory for the resource. In the example in the following section, the resource reference name is jdbc/SavingsAccountDB. The JNDI name of a resource and the name of the resource reference are not the same. This approach to naming requires that you map the two names before deployment, but it also decouples components from resources. Because of this decoupling, if at a later time the component needs to access a different resource, you don't have to change the name in the code.
Page 2 of 30
This flexibility also makes it easier for you to assemble J2EE applications from preexisting components.
deploytool Tips for Resource ReferencesThe instructions that follow refer to the entity bean described in the section The SavingsAccountEJB Example. The SavingsAccountEJB code is in the j2eetutorial/examples/src/ejb/savingsaccount directory. A sample SavingsAccountApp.ear file is in the j2eetutorial/examples/ears directory. Specifying a Resource Reference 1. In deploytool, select SavingsAccountEJB from the tree. 2. Select the Resource Refs tab. 3. Click Add. 4. In the Coded Name field, enter jdbc/SavingsAccountDB. The SavingsAccountBean code refers to the database as follows:private String dbName = "java:comp/env/jdbc/SavingsAccountDB";
The java:comp/env prefix is the name of the JNDI context for the component. The jdbc/SavingsAccountDB string is the JNDI name for the resource reference. The JNDI names for JDBC DataSource objects are stored in the java:comp/env/jdbc subcontext. 5. In the Type combo box, select javax.sql.DataSource. A DataSource object is a factory for database connections. 6. In the Authentication combo box, select Container. 7. If you want other enterprise beans to share the connections acquired from the DataSource, select the Sharable checkbox. If the preceding steps are followed, the Resource Refs tab will appear as shown in Figure 16-1.
Page 3 of 30
Figure 16-1 Resource Refs Tabbed Pane of SavingsAccountEJB Mapping a Resource Reference to a JNDI Name 1. Select the J2EE application from the tree. 2. Select the JNDI Names tab. 3. In the References table, select the row containing the resource reference. For the SavingsAccountEJB example, the resource reference is jdbc/SavingsAccountDB, the name you entered in the Coded Name field of the Resource Refs tab. 4. In the row you just selected, enter the JNDI name. For the SavingsAccountEJB example, you would enter jdbc/Cloudscape in the JNDI Name field. The JNDI Names tab for SavingsAccountApp is shown in Figure 16-2.
Page 4 of 30
Figure 16-2 JNDI Names Tab of SavingsAccountApp
Database Connections for Enterprise BeansThe persistence type of an enterprise bean determines whether or not you code the connection routine. You must code the connection for enterprise beans that access a database and do not have container-managed persistence. Such beans include entity beans with bean-managed persistence and session beans. For entity beans with container-managed persistence, deploytool generates the connection routines for you.
Coded ConnectionsHow to Connect The code examples in this section are from the SavingsAccountBean class, which connects to the database via the following steps. 1. Specify the database name.private String dbName = "java:comp/env/jdbc/SavingsAccountDB";
2. Obtain the DataSource associated with the logical name.
http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Resources4.html InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName);
Page 5 of 30
3. Get the Connection from the DataSource.Connection con = ds.getConnection();
When to Connect When coding an enterprise bean, you must decide how long it will retain the connection. Generally you have two choices: either hold the connection for the lifetime of the bean, or hold it only during each database call. Your choice determines the method (or methods) in which your bean connects to a database.
Long-Term ConnectionsYou can design an enterprise bean that holds a database connection for its entire lifetime. Because the bean connects and disconnects just once, its code is slightly easier to write. But there's a trade-off--other components cannot acquire the connection. Session and entity beans issue the lifelong connections in different methods. Session Beans The EJB container invokes the ejbCreate method at the beginning of a session bean's life cycle and invokes the ejbRemove method at the end. To retain a connection for the lifetime of a session bean, you connect to the database in ejbCreate and disconnect in ejbRemove. If the session bean is stateful, you must also connect in ejbActivate and disconnect in ejbPassivate. A stateful session bean requires these additional calls because the EJB container may passivate the bean during its lifetime. During passivation, a stateful session bean is saved in secondary storage, but a database connection cannot be saved in this manner. Because a stateless session bean cannot be passivated, it does not require the additional calls in ejbActivate and ejbPassivate. For more information on activation and passivation, see The Life Cycle of a Stateful Session Bean. For an example of a stateful session bean with a long-term connection, see the TellerBean.java code in the j2ee/tutorial/1_3fcs/examples/src/ejb/teller/TellerBean.java file. Entity Beans with Bean-Managed Persistence After instantiating an entity bean and moving it to the pooled stage, the EJB container invokes the setEntityContext method. Conversely, the EJB container invokes the unsetEntityContext method when the entity bean leaves the pooled stage and becomes eligible for garbage collection. To retain a database connection for its entire life span, an entity bean connects in the setEntityContext method and disconnects in the unsetEntityContext method. To see a diagram of the life cycle, see Figure 3-5. For an example of an entity bean with a long-term connection, see the SavingsAccountBean.java code in the j2ee/tutorial/1_3fcs/examples/src/ejb/savingsaccount/SavingsAccountBean.java file.
Page 6 of 30
Briefly held connections allow many components to share the same connection. Because the EJB container manages a pool of database connections, enterprise beans can quickly obtain and release the connections. For example, a business method might connect to a database, insert a row, and then disconnect. In a session bean, a business method that connects to a database should be transactional. The transaction will help maintain data integrity. deploytool Tips for Specifying Database Users and Passwords The instructions in this section do not apply to entity beans with container-managed persistence. For those entity beans, see the instructions in Specifying the Database JNDI Name, User Name, and Password. To connect to the Cloudscape database bundled with this release, you do not specify a database user name and password; authentication is performed by a separate service. For more information about authentication, see Chapter 15. However, some types of databases do require a user name and password during connection. For these databases, if the getConnection call has no parameters, you must specify the database user name and password with deploytool. To specify these values, perform these steps: 1. Select the enterprise bean in the tree view. 2. Select the Resource Refs tab. 3. Select the appropriate row in the table labeled Resource Fa