Filling in the Gaps




Filling in the Gaps

The Java EE specification attempts to fill in the gaps between the web components and Enterprise JavaBeans by defining how these technologies come together to form a complete platform. One of the ways in which Java EE adds value is by creating a consistent programming model across web components and enterprise beans through use of annotations, injection, JNDI ENC, and XML deployment descriptors. A servlet in Java EE can access JDBC DataSource objects, environment entries, and references to enterprise beans through injection annotations or the JNDI ENC in exactly the same way that enterprise beans use them. If you do not want to use injection annotations such as @EJB, @Resource , and @PersistenceContext directly within your servlet and JSP code, web components have their own XML deployment descriptors that allow you to declare the same elements that are available in EJB (<ejb-ref>, <resource-ref>, <env-entry>, and <persistence-context-ref>), as well as security roles and other elements specific to web components. In Java EE, web components are packaged along with any XML deployment descriptors and are deployed in JAR files with the extension .war, which stands for web archive . A .war file can contain several servlets and JSP documents that share an XML deployment descriptor. The use of injection annotations, the JNDI ENC, deployment descriptors, and JAR files in web components makes them consistent with the EJB programming model and unifies the entire Java EE platform.

Using the JNDI ENC makes it much simpler for web components to access Enterprise JavaBeans. The web component developer does not need to be concerned with the network location of enterprise beans; the server will map any @EJB or <ejb-ref> elements listed in the deployment descriptor to the enterprise beans at deployment time.

Optionally, Java EE vendors can allow web components to access the EJB local component interfaces of enterprise beans. This strategy makes a lot of sense if the web component and the bean are located in the same Java Virtual Machine, because the Java RMI-IIOP semantics can hurt performance if the communicating components are in the same virtual machine. Most Java EE vendors are expected to support this option.

Besides injecting resources, persistence contexts, and EJBs, you also have access to a javax.jta.UserTransaction object, as is the case in EJB. The UserTransaction object allows the web component to manage transactions explicitly. The transaction context must be propagated to any enterprise beans accessed within the scope of the transaction (according to the transaction attribute of the enterprise bean method).

Java EE also defines a .ear file (enterprise archive file), which is a JAR file for packaging EJB JAR files and web component JAR files (.war files) together into one complete deployment, called a Java EE application. A Java EE application may have its own optional XML deployment descriptor that points to the EJB and web component JAR files (called modules ) as well as other elements such as icons, descriptions, and the like. This .ear deployment descriptor is not required. When a Java EE application is created, interdependencies such as @EJB and @PersistenceContext annotations can be resolved and security roles can be edited to provide a unified view of the entire web application. Figure illustrates the file structure of a Java EE archive file.

Contents of a Java EE .ear file


Persistence Unit Scope

In previous chapters, we discussed a little bit about the scope of a persistence unit within a .ear file. There are a few rules governing the visibility of a persistence unit, depending on how it is packaged. A persistence unit can be packaged within an EJB-JAR file, within a WAR's WEB-INF/lib directory, or within an EAR's lib/ directory. A persistence unit packaged within an EAR's lib/ directory is visible to every component deployed in the .ear. Any EJB, servlet, or JSP can reference the persistence unit by name with the @PersistenceContext and @PersistenceUnit annotations, or with the <persistence-context-ref> and <persistence-unit-ref> XML deployment descriptor elements. This isn't the case for persistence units that are defined within an EJB-JAR or a WAR file. Only EJBs or servlets defined within the scope of that archive are allowed to reference a scoped persistence unit.

If only one persistence unit is defined in a scoped archive, then that persistence unit may be referenced with an empty string, "", for the persistence unit name. If an EJB or WAR archive has a persistence unit with the same name as one defined in an EAR's lib/ directory, then the # syntax discussed in Chapter 14 can be used to distinguish the name:

@PersistenceUnit(unitName="../lib/titan.jar#MyPU")

These types of name clashes are very rare and should be avoided if possible so that the structure of your deployment is not reflected in code or configuration.

Java EE Application Client Components

In addition to integrating web and enterprise bean components, Java EE introduces a new component model: the application client component. An application client component is a Java application that resides on a client machine and accesses enterprise bean components on the Java EE server. Client components also have access to a JNDI ENC that operates the same way as the JNDI ENC for web and enterprise bean components. The client component includes an XML deployment descriptor that declares the <env-entry>, <ejb-ref>, and <resource-ref> elements of the JNDI ENC in addition to a <description>, <display-name>, and <icon> that can be used to represent the component in a deployment tool. As with all other Java EE components, the injection annotations (@PersistenceContext, @EJB, @Resource ) are also supported.

A client component is simply a Java program that uses the JNDI ENC to access environment properties, enterprise beans, and resources (JDBC, JavaMail, and so on) made available by the Java EE server. Client components reside on the client machine, not on the Java EE server. Here is an extremely simple component:

public class MyJavaEEClient 
 {
    private static @EJB ProcessPaymentRemote processPayment;

    public static void main(String [] args) {

        InitialContext 
 jndiCntx = new InitialContext( );

        Object ref = jndiCntx.lookup("java:comp/env/ejb/TravelAgent");
        TravelAgentRemote bean = (TravelAgentRemote)
            PortableRemoteObject.narrow(ref,TravelAgentRemote.class);

        Customer cust = new Customer( );
        cust.setName("Bill");
        bean.setCustomer(cust);
        TicketDO ticket = bean.bookPassage(...);

    }
}

MyJavaEEClient illustrates how a client component is written. Notice that the client component did not need to use a network-specific JNDI InitialContext. In other words, we did not have to specify the service provider in order to connect to the Java EE server. This is the real power of the Java EE application client component: location transparency . The client component does not need to know the exact location of the Ship EJB or choose a specific JNDI service provider; the JNDI ENC takes care of locating the enterprise bean.

When application components are developed, an XML deployment descriptor is created that specifies the JNDI ENC entries. At deployment time, a vendor-specific Java EE tool generates the class files needed to deploy the component on client machines. A client component is packaged into a JAR file with its XML deployment descriptor and can be included in a Java EE application. Once a client component is included in the Java EE application deployment descriptor, it can be packaged in the .ear file with the other components, as Figure illustrates.

Contents of a Java EE .ear file with application components


Guaranteed Services

The Java EE specifications require application servers to support a specific set of protocols and Java enterprise extensions, ensuring a consistent platform for deploying Java EE applications. Java EE application servers must provide the following "standard" services:


Java Virtual Machine

Java EE 5 products must support Java JDK 5.


Enterprise JavaBeans

Java EE 5 products must support EJB 2.1 as well as EJB 3.0.


Servlets

Java EE 5 products must support Servlets 2.5.


JavaServer Pages

Java EE 5 products must support JSP 2.1.


HTTP and HTTPS

Web components in a Java EE server service both HTTP and HTTPS requests. The Java EE product must be capable of advertising HTTP 1.0 and HTTPS (HTTP 1.0 over SSL 3.0) on ports 80 and 443, respectively. Components must have full access to HTTP/HTTPS client APIs.


JavaServer Faces 1.2

This framework simplifies the building and assembly of reusable user interface components for the Web and for Swing applications.


Java RMI-IIOP

Support for Java RMI-IIOP is required. However, the vendor may also use other protocols, as long as they are compatible with Java RMI-IIOP semantics.


Java RMI-JRMP

Java EE components can be native Java RMI (JRMP) clients.


Java IDL

Web components and enterprise beans must be able to access CORBA services that are hosted outside the Java EE environment using JavaIDL, a standard part of the Java 2 platform.


JDBC

Java EE 5 requires support for JDBC 3.0. Java EE 1.3 requires support for JDBC 2.0 and some parts of the JDBC 2.0 extension.


Java Naming and Directory Interface (JNDI)

Web and enterprise bean components must have access to the JNDI ENC to access things such as EJB objects, JTA UserTransaction objects, JDBC DataSource objects, Java Message Service ConnectionFactory objects, and JAX-RPC ConnectionFactory objects.


JavaMail and JAF

Java EE 5 products must support JavaMail 1.3, including access to a message store. The platform must also support the Java Activation Framework (JAF) 1.0, which is needed to support different MIME types and required for JavaMail.


Java Message Service (JMS)

Java EE 5 products must support JMS 1.1 and provide support for point-to-point (p2p) and publish-and-subscribe (pub/sub) messaging models, as well as the unified messaging model.


Java API for XML Parsing (JAXP)

Java EE 5 products must support JAXP 1.2, which includes XML Schema validation, and Java EE 1.3 products must support JAXP 1.1.


Java EE Connector Architecture (JCA)

Java EE 5 products must support JCA 1.5, which includes asynchronous messaging.


Java Authentication and Authorization Service (JAAS)

Java EE 5 products must support the use of JAAS 1.0, as described in the JCA specifications.


Java Transaction API 1.0.1

Java EE 5 and 1.3 products must support JTA 1.0.1 and must have access to the UserTransaction objects via the JNDI ENC.


Web Services for Java EE (WS-Java EE)

Java EE 5 must support web services for Java EE 1.1. The specification includes JAX-RPC 1.1, JAXR 1.0, and SAAJ 1.2.


Web Services Metadata for Java EE

This specification defines annotations that can be used to describe web services.


Java Logging API

Java EE 5 products must support the logging of events using the java.util.logging package, which is part of the J2SDK 5 core.


Java EE Management API

Java EE 5 products must support the Java EE Management API 1.0, including support for some features of JMX 1.2.


Java EE Deployment API

Java EE 5 products must support the Java EE Deployment API 1.1. Vendors must support the plug-in component for tool vendors.


Java Authorization Service Provider Contract (JACC)

Java EE 5 must support JACC 1.0, which defines a contract between a Java EE application server and an authorization policy provider.