Technical Article

Introducing the Java EE 6 Platform: Part 1

By Ed Ort, December 2009

Published July 2000

Java Platform, Enterprise Edition (Java EE) is the industry-standard platform for building enterprise-class applications coded in the Java programming language. Based on the solid foundation of Java Platform, Standard Edition (Java SE), Java EE adds libraries and system services that support the scalability, accessibility, security, integrity, and other requirements of enterprise-class applications.

Since its initial release in 1999, Java EE has matured into a functionally rich, high performance platform. Recent releases of the platform have also stressed simplicity and ease of use. In fact, with the current release of the platform, Java EE 5, development of Java enterprise applications has never been easier or faster.


Java EE 6 adds significant new technologies and extends the usability improvements made in previous Java EE releases.

Progress continues. The next release of the platform, Java EE 6, adds significant new technologies, some of which have been inspired by the vibrant Java EE community. It also further simplifies the platform, extending the usability improvements made in previous Java EE releases.

This article highlights some of the significant enhancements in Java EE 6.

Java EE 6 Goals

Here are the main goals for the Java EE 6 platform:

More Flexible Technology Stack. Over time, the Java EE platform has gotten big, in some cases too big for certain types of applications. To remedy this, Java EE 6 introduces the concept of profiles, configurations of the Java EE platform that are designed for specific classes of applications. A profile may include a subset of Java EE platform technologies, additional technologies that have gone through the Java Community Process, but are not part of the Java EE platform, or both. Java EE 6 introduces the first of these profiles, the Web Profile, a subset of the Java EE platform designed for web application development. The Web Profile includes only those technologies needed by most web application developers, and does not include the enterprise technologies that these developers typically don't need.

In addition, the Java EE 6 platform has identified a number of technologies as candidates for pruning. These candidates include technologies that have been superseded by newer technologies or technologies that are not widely deployed. Pruning a technology means that it can become an optional component in the next release of the platform rather than a required component.

Java EE 6 introduces the Web Profile, a subset of the Java EE platform designed for web application development.

Enhanced Extensibility. Over time, new technologies become available that are of interest to web or enterprise application developers. Rather than adding these technologies to the platform — and growing the platform without bounds — Java EE 6 includes more extensibility points and more service provider interfaces than ever before. This allows you to plug in technologies — even frameworks — in your Java EE 6 implementations in a standard way. Once plugged in, these technologies are just as easy to use as the facilities that are built into the Java EE 6 platform.

More extensibility points and service provider interfaces as well as web tier features such as support for self-registration makes the platform highly extensible.

Particular emphasis on extensibility has been placed on the web tier. Web application developers often use third-party frameworks in their applications. However, registering these frameworks so that they can be used in Java EE web applications can be complicated, often requiring developers to add to or edit large and complex XML deployment descriptor files. Java EE 6 enables these frameworks to self-register, making it easy to incorporate and configure them in an application.

Further Ease of Development. Java EE 5 made it significantly easier to develop web and enterprise applications. For instance, Java EE 5 introduced a simpler enterprise application programming model based on Plain Old Java Objects (POJOs) and annotations, and eliminated the need for XML deployment descriptors. In addition, Enterprise JavaBeans (EJB) technology was streamlined, requiring fewer classes and interfaces and offering a simpler approach to object-relational mapping by taking advantage of the Java Persistence API (informally referred to as JPA).

Usability improvements in many areas of the platform makes it even easier to develop web and enterprise applications.

Java EE 6 makes it even easier to develop enterprise or web applications. Usability improvements have been made in many areas of the platform. For example, you can use annotations to define web components such as servlets and servlet filters. Furthermore, a set of annotations for dependency injection has been standardized, making injectable classes much more portable across frameworks. In addition, Java EE application packaging requirements have been simplified. For example, you can add an enterprise bean directly to a web archive (WAR) file. You no longer need to package an enterprise bean in a Java archive (JAR) file and then put the JAR file in an enterprise archive (EAR) file.

Powerful New Technologies

Java EE 6 adds significant new technologies that make the platform even more powerful. Three of these are described below:

Java API for RESTful Web Services (JAX-RS)

Java API for RESTful Web Services (JAX-RS), JSR 311 enables you to rapidly build lightweight web services that conform to the Representational State Transfer (REST) style of software architecture. An important concept in REST is the existence of resources, each of which can be referred to with a global identifier, that is, a URI. In particular, data and functionality are considered resources that can be identified and accessed through URIs. To manipulate these resources, components of the network, clients and servers, communicate through a standardized interface such as HTTP and a small, fixed set of verbs — GET, PUT, POST, and DELETE — and exchange representations of these resources.

RESTful web services are web services built according to the REST architectural style. Building web services with the RESTful approach has emerged as a popular alternative to using SOAP-based technologies thanks to REST's lightweight nature and the ability to transmit data directly over HTTP.

JAX-RS makes it simple to create RESTful web services in Java.

JAX-RS furnishes a standardized API for building RESTful web services in Java. The API contributes a set of annotations and associated classes and interfaces. Applying the annotations to POJOs enables you to expose web resources. This approach makes it simple to create RESTful web services in Java.

The specification for the initial release of the technology, JAX-RS 1.0, was finalized in October 2008 and a reference implementation named Jersey is also available. Java EE 6 includes the latest release of the technology, JAX-RS 1.1, which is a maintenance release that aligns JAX-RS with new features in Java EE 6.

Let's take a look at a RESTful web service that uses JAX-RS.

 import javax.ws.rs.Path;

   import javax.ws.rs.Produces;
   import javax.ws.rs.Get;
   import javax.ws.rs.Post;
   import javax.ws.rs.Consumes;
   import javax.ws.rs.core.Response;
   import javax.ws.rs.core.MediaType;
   import javax.ws.rs.core UriInfo;
   import javax.ws.rs.core.UriBuilder;
   import java.net.URI;

   @Path ("items")
   @Produces (MediaType.APPLICATION_XML)
   Public class ItemsResource {

       @Context UriInfo uriInfo;

       @GET
       Items listItems() {
           Return Allitems();
       }

       @POST
       @Consumes (MediaType.APPLICATION_XML)
       Public Response create(Item item) throws ItemCreationException {
           Item newItem = createItem(item);
           URI newItemURI = uriInfo.getRequestUriBuilder().path(newItem.getId()).build();
           return Response.created(newItemURI).build();
       }

       ...
   }

In this example, the ItemsResource class is a web service that manages a set of items. The imports in the class are for JAX-RS 1.1 annotations, classes, and interfaces.

Annotations add much of the information needed to identify resources and serve HTTP requests.

The @Path annotation specifies a relative path for the resource, in this case "items". The URI for the class resource is based on the application context. So if the application context for this example is http://example.com, the URI for the class resource is http://example.com/items. This means that if a client directs a request to the URI http://example.com/items, the ItemsResource class will serve it.

The @GET annotation specifies that the annotated method, here the listItems() method, handles HTTP GET requests. When a client directs an HTTP GET request to the URI for the ItemsResource resource, the JAX-RS runtime invokes the listItems() method to handle the GET request.

Notice the @Produces annotation. It specifies the MIME media types that the methods in the resource can produce and return to the client. In the ItemsResource example, the @Produces annotation specifies MediaType.APPLICATION_XML. The MediaType class is an abstraction of a MIME media type. Constants supplied to the class identify the particular media type to be abstracted. The MediaType.APPLICATION_XML specification is an abstraction of the MIME media type for XML content, "application/xml".

JAX-RS automatically translates between Java types and MIME media types.

Annotations such as @Produces suggest some of the content type translation that JAX-RS handles automatically. For example, the listItems() method returns a Java object of type Items. JAX-RS automatically translates that Java type to the "application/xml" MIME type to be used in the HTTP response to the client. Note that the translation is automatic only if the returned type is supported by default. For instance, if Items is a JAXB-annotated bean, then the translation would be automatic. However, if Items is a POJO, you would need to implement a MessageBodyReader to handle the serialization.

You can also specify a @Produces annotation on a method. In that case, the MIME type you specify on the method overrides the MIME types in any @Produces annotation that you specify on the class. For example, you could specify a @Produces annotation for the listItems() method as follows:

       @GET

       @Produces (MediaType.TEXT_PLAIN)
       Items listItems() {
           Return Allitems();
       }

JAX-RS would then translate the Items Java type to the "text/plain" MIME type, which represents plain text, and return content of that type in the HTTP response to the client.

The @POST annotation specifies that the annotated method, in this case, the create() method, responds to HTTP POST requests. In this example, the method creates a new item, perhaps in a database, and then returns a response indicating that it created the new item. When a client directs an HTTP POST request to the URI for the ItemsResource resource, the JAX-RS runtime invokes the create() method to handle the POST request.

Notice that the @Consumes annotation is specified on the create() method. The annotation specifies the MIME media types that the methods in the resource can accept from the client. As is the case for the @Produces annotation, if you specify @Consumes on a class, it applies to all the methods in the class. If you specify @Consumes on a method, it overrides the MIME type in any @Consumes annotation that you specify for the class. In the example, the @Consumes annotation specifies that the create() method can accept XML content, that is, the MIME type "application/xml". Here the type translation is from MIME type to Java type. When a client submits XML content in a POST request to the URI for the ItemsResource class, JAX-RS invokes the create() method and automatically translates the incoming XML to the Item Java type required for the method's argument.

Utility classes and interfaces further simplify actions related to building and using RESTful web services.

JAX-RS also includes a number of utility classes and interfaces that further simplify actions related to building and using RESTful web services in Java. You've already seen one of them: MediaType, a class for abstracting MIME media types. Some others are:

  • UriInfo, an interface for accessing URI information. In this example, the @Context annotation injects the UriInfo interface into the uriInfo field of the ItemsResource class.
  • UriBuilder, a class for building URIs from their components
  • Response, a class represents an HTTP response
  • Response.ResponseBuilder, a class that builds Response objects, in accordance with the well-known Builder Pattern

These classes and interfaces are used in the following statements in the example:

   URI newItemURI = uriInfo.getRequestUriBuilder().path(newItem.getId()).build();

   return Response.created(newItemURI).build();

The first statement builds a URI for the new item. The getRequestUriBuilder() method is a UriInfo method that creates a UriBuilder object. The path() and build() methods are UriBuilder methods that together construct the URI for the new item.

The second statement creates a Response object for the new item to be returned to the client. The created method is a Response method that creates a Response.ResponseBuilder object. The build() method is a Response.ResponseBuilder method that creates the Response object for the new item. This object delivers metadata to the JAX-RS runtime to construct the HTTP response.

JAX-RS eliminates a lot of the low-level programming required in HTTP-aware web applications.

These utility classes and interfaces hide a lot of the complexity of HTTP programming — another reason why using JAX-RS is a simple way to build RESTful web services. However, this simplicity also extends beyond web services. JAX-RS can simplify the development of many types of HTTP-aware web applications. For example, if you need to build a web application that examines HTTP headers, you can probably code it in a much simpler way by using JAX-RS rather than other approaches.

JAX-RS has other convenient features. For example, JAX-RS includes a number of parameter-based annotations to extract information from a request. One of these is @QueryParam, with which you can extract query parameters from the Query component of a request URL. Some other parameter-based annotations are @MatrixParam, which extracts information from URL path segments, @HeaderParam, which extracts information from HTTP headers, and @CookieParam which extracts information from the cookies declared in cookie-related HTTP headers.

For information about all the features in JAX-RS 1.1, see Java API for RESTful Web Services (JAX-RS), JSR 311.

Contexts and Dependency Injection for the Java EE Platform

Contexts and Dependency Injection for the Java EE Platform (CDI), JSR 299 is a technology that supplies a powerful set of services to Java EE components. These services allow Java EE components, including EJB session beans and JavaServer Faces (JSF) managed beans, to be bound to lifecycle contexts, to be injected, and to interact in a loosely coupled way by firing and observing events. Perhaps most significantly, CDI unifies and simplifies the EJB and JSF programming models. It allows enterprise beans to replace JSF managed beans in a JSF application.

CDI unifies and simplifies the EJB and JSF programming models. It allows enterprise beans to act as JSF managed beans in a JSF application, and brings transactional support to the web tier.

In essence, CDI helps bridge what was a major gap between the web tier of the Java EE platform and the enterprise tier. The enterprise tier, through technologies such as EJB and JPA, has strong support for transactional resources. For example, using EJB and JPA you can easily build an application that interacts with a database, commits or rolls back transactions on the data, and persists the data. The web tier, by comparison, is focused on presentation. Web tier technologies such as JSF and JavaServer Pages (JSP pages) render the user interface and display its content, but have no integrated facilities for handling transactional resources.

Through its services, CDI brings transactional support to the web tier. This can make it a lot easier to access transactional resources in web applications. For example, CDI makes it a lot easier to build a Java EE web application that accesses a database with persistence provided by JPA.

Let's look at some key parts of a web application that uses CDI services. The application, which processes user login and user logout requests, includes both JSF and EJB components. Here is the code for an input form on a JSF page that displays a login prompt for the web application:

   <f:view>

       <h:form>
           <h:panelGrid columns="2" rendered="#{!login.loggedIn}">
              <h:outputLabel for="username">Username:</h:outputLabel>
              <h:inputText id="username" value="#{credentials.username}"/>
              <h:outputLabel for="password">Password:</h:outputLabel>
              <h:inputText id="password" value="#{credentials.password}"/>
           </h:panelGrid>
           <h:commandButton value="Login" action="#{login.login}" rendered="#{!login.loggedIn}"/>
           <h:commandButton value="Logout" action="#{login.logout}" rendered="#{login.loggedIn}"/>
       </h:form>
   </f:view>

As you can see from the code, the login prompt displays fields for a user to enter a user name and password. It also displays a Login button and a Logout button. Notice the unified expression language (EL) expressions such as #{credentials.username} and #{login.login}. These expressions refer to beans, named credentials and login.

CDI builds on managed beans, which are designed to unify all of the various types of beans in Java EE 6.

Note that CDI builds on a new concept introduced in Java EE 6 called managed beans, which is designed to unify all of the various types of beans in Java EE 6. A managed bean is a Java class that is treated as a managed component by the Java EE container. Optionally, you can give it a name in the same namespace as that used by EJB components. A managed bean can also rely on a small number of container-provided services, mostly related to lifecycle management and resource injection. Other Java EE technologies such as JSF, EJB, and CDI build on this basic definition of a managed bean by adding services. So for example, a JSF managed bean adds lifecycle scopes, an EJB session bean adds services such as support for transactions, and CDI adds services such as dependency injection. In CDI a managed bean or simply a bean is a Java EE component that can be injected into other components, associated with a context, or reached through EL expressions.

You declare a managed bean by annotating its class with the javax.annotation.ManagedBean annotation or by using one of several CDI annotations such as a scope annotation or a qualifier annotation. Scope annotations and qualifier annotations are discussed later in this section. The annotation-based programming model makes it possible for a bean to begin as a POJO and later become another type of Java EE component such as an EJB component — perhaps to take advantage of more advanced functionality, such as transactional and security annotations or the instance pooling facility offered by EJB containers. For example, you can turn a POJO into a stateful session bean by adding a @Stateful annotation to the object. Clients that use CDI to access a bean are unaffected by the bean's transition from POJO to EJB.

Any bean can be bound to a lifecycle context, can be injected, and can interact with other beans in a loosely coupled way by firing and observing events. In addition, a bean may be called directly from Java code, or as in this example, it may be invoked in a unified EL expression. This enables a JSF page to directly access a bean, even a bean that is implemented as an EJB component such as a session bean.

In this application, a bean named Credentials has a lifecycle that is bound to the JSF request. The Credentials bean is implemented as a JavaBean as follows:

   @Model

   public class Credentials {

      private String username;
      private String password;

      public String getUsername() { return username; }
      public void setUsername(String username) { this.username = username; }

      public String getPassword() { return password; }
      public void setPassword(String password) { this.password = password; }
   }

To request CDI services, you annotate a Java EE component with CDI annotations. The @Model annotation is a CDI annotation that identifies the Credentials bean as a model object in an Model-View-Controller (MVC) architecture. The annotation, which is built into CDI, is a stereotype annotation. A stereotype annotation marks a class as fulfilling a specific role within the application.

CDI services allow Java EE components, including EJB components, to be bound to lifecycle events.

The application also includes a Login bean whose lifecycle is bound to the HTTP session. The Login bean is implemented as an EJB stateful session bean, as follows:

   @Stateful

   @SessionScoped
   @Model
   public class Login {

      @Inject Credentials credentials;
      @Inject EntityManager userDatabase;

      private User user;

      @TransactionAttribute(REQUIRES_NEW)
      @RolesAllowed("guest")
      public void login() {
         ...
      }

      public void logout() {
         user = null;
      }

      public boolean isLoggedIn() {
         return user!=null;
      }

      @RolesAllowed("user")
      @Produces @LoggedIn User getCurrentUser() {
         ...
      }
   }

The @Stateful annotation is an EJB annotation that specifies that this bean is an EJB stateful session bean. The @TransactionAttribute and @RolesAllowed annotations are also EJB annotations. They declare the EJB transaction demarcation and security attributes of the annotated methods.

All beans have a scope. Among other things, this gives EJB components access to the request, session, and application contexts of web tier components.

The @SessionScoped annotation is a CDI annotation that specifies a scope for the bean. All beans have a scope that determines the lifecycle of its instances and the instances of the bean that are made visible to instances of other beans. This is an important feature because components such as EJB components do not have a well-defined scope. In particular, EJB components are not aware of the request, session, and application contexts of web tier components such as JSF managed beans, and do not have access to the state associated with those contexts. In addition, the lifecycle of a stateful EJB component cannot be scoped to a web-tier context.

By contrast, scoped objects in CDI exist in a well-defined lifecycle context that is managed by the Java EE container. Scoped objects may be automatically created when needed and then automatically destroyed when the context in which they were created ends. Significantly, the state of a scoped object is automatically shared by clients that execute in the same context. This means that clients such as other beans that execute in the same context as a scoped object see the same instance of the object. But clients in a different context see a different instance. The @SessionScoped annotation specifies that the scope type for the Login bean is session scope. Objects that are not associated with any of the usual scopes, but instead exist for the exclusive benefit of an object that triggered their creation, are said to be dependents of their owner. The lifecycle of these dependent objects is tied to that of the owner. In particular, a dependent object is destroyed whenever the owner is destroyed.

CDI services allow Java EE components, including EJB and JPA components, to be injected.

Beans typically acquire references to other beans through dependency injection. The dependency injection mechanism is completely type safe. CDI uses the annotations specified in JSR 330: Dependency Injection for Java for dependency injection. One of those annotations, @Inject, identifies a point at which a dependency on a Java class or interface can be injected. The container then provides the needed resource. In this example, the Login bean specifies two injection points. The first use of the @Inject annotation in the example injects a dependency on the Credentials bean. In response, the container will inject the Credentials bean into any instance of Login created within this context. The second @Inject annotation injects a dependency on the JPA EntityManager. The container will inject the EntityManager to manage the persistence context. Refer to Standardized Annotations for Dependency Injection to learn more about the @Inject annotation and other annotations in JSR 330.

The @Produces annotation identifies the getCurrentUser() method as a producer method. A producer method is called whenever another bean in the system needs an injected object of the specified type. In this case, the injected object is the currently logged-in user, which is injected by the qualifier annotation @LoggedIn. A qualifier identifies a specific implementation of a Java class or interface to be injected. In order to use a qualifier annotation, you first need to define its type as a qualifier. You use the @Qualifier annotation, another JSR 330 annotation, to do that. For example:

   @Target( { TYPE, METHOD, PARAMETER, FIELD })

   @Retention(RUNTIME)
   @Documented
   @Qualifier
      public @interface LoggedIn {...}

Let's return to the login prompt discussed earlier. When a user responds to the prompt and clicks the Submit button, CDI technology goes into action. The Java EE container automatically instantiates a contextual instance of the Credentials bean and the Login bean. An instance of a bean that is bound to a context is called a contextual instance. JSF assigns the user name and password the user entered to the Credentials bean contextual instance. Next, JSF calls the login() method in the Login bean contextual instance. This instance continues to exist for and is available to other requests in the same HTTP session, and provides the User object that represents the current user to any other bean that requires it.

This example demonstrates only some of the features in this powerful technology. Another feature enables beans to produce or consume events. Yet another lets you define interceptors that bind additional function across all bean types, or define decorators that apply the additional function to a specific bean type. To learn about these and the other features in CDI technology, see Contexts and Dependency Injection for the Java EE Platform, JSR 299.

Bean Validation

Validating data is a common task that occurs throughout an application. For example, in the presentation layer of an application, you might want to validate that the number of characters a user enters in a text field is at most 20 characters or that the number a user enters in a numeric field is positive. If you set those constraints, you probably want the same data to be validated before it's used in the business logic of the application and when the data is stored in a database.

Developers often code the same validation logic in multiple layers of an application, something that's time consuming and error-prone. Or they put the validation logic in their data model, cluttering it with what is essentially metadata.

Bean Validation affords a standard framework for validation, in which the same set of validations can be shared by all the layers of an application.

Bean Validation, JSR 303 makes validation simpler and reduces the duplication, errors, and clutter that characterizes the way validation is often handled in enterprise applications. Bean Validation affords a standard framework for validation, in which the same set of validations can be shared by all the layers of an application.

Specifically, Bean Validation offers a framework for validating Java classes written according to JavaBeans conventions. You use annotations to specify constraints on a JavaBean — you can annotate a JavaBean class, field, or property. You can also extend or override these constraints through XML descriptors. A validator class then validates each constraint. You specify which validator class to use for a given type of constraint.

Here, for example, is part of a class that declares some constraints through Bean Validation annotations:

   public class Address {

       @NotNull @Size(max=30)
       private String addressline1;

       @Size(max=30)
       private String addressline2;

        ...

       public String getAddressline1() {
              return addressline1;
       }

       public void setAddressline1(String addressline1) {
              this.addressline1 = addressline1;
       }

        ...
   }

The @NotNull annotation specifies that the annotated element, addressline1, must not be null. The @Size annotation specifies that the annotated elements, addressline1 and addressline2, must not be longer than the specified maximum, 30 characters.

When an Address object is validated, the addressline1 value is passed to a validator class that is defined for the @NotNull constraint as well as to a validator class defined for the @Size constraint. The addressline2 value is also passed to the validator class for the @Size constraint. The pertinent validator classes perform the validations.

Bean Validation includes a number of built-in constraint definitions. You add your own constraints by declaring an annotation type that specifies a validator class.

Both the @NotNull and @Size constraints are built into the Bean Validation framework so you do not need to define validator classes for them. However, you can add your own constraints to the built-in constraints, in which case, you need to define validator classes. For example, you can define a constraint named @ZipCode as follows:

   @Size(min=5, max=5)

   @ConstraintValidator(ZipcodeValidator.class)
   @Documented
   @Target({ANNOTATION_TYPE, METHOD, FIELD})
   @Retention(RUNTIME)
   public @interface ZipCode {
       String message() default "Wrong zipcode";
       String[] groups() default {};
   }

Then you can specify the @ZipCode constraint on a class, field, or property just like any other constraint. Here is an example:

   public class Address {

        ...

       @ZipCode
       private String zipCode;

       public String getZipCode() {
              return zipCode;
       }

       public void setZipCode(String zipCode) {
              this.zipCode = zipCode;
       }

        ...
   }

When an Address object is validated, the zipCode value is passed to the ZipcodeValidator class for validation. Notice that the constraint definition includes another constraint: @Size(min=5, max=5). This means that an element annotated by the @ZipCode annotation must be exactly 5 characters in length. The element is validated against this constraint in addition to the primary constraint check that ZipcodeValidator performs. Bean Validation allows you to create a constraint that is composed of other constraints. In fact, any composing constraint can itself be composed of constraints. Notice too that the constraint definition specifies an error message to be returned if the constraint fails the validation check. Here, the error message is "Wrong zipcode".

In addition to validating individual objects, you can use Bean Validation to validate an entire object graph.

You can also use Bean Validation to validate an entire object graph in a straightforward way. An object graph is an object composed of other objects. If you specify the @Valid annotation on the root object of an object graph, it directs the pertinent validator to recursively validate the associated objects in the object graph. Consider the following example:

   public class Order {

       @OrderNumber private String orderNumber;
       @Valid @NotNull private Address delivery;
   }

When an Order object is validated, the Address object and the associated objects in its object graph are validated too.

Bean Validation is integrated across the Java EE 6 platform.

To meet the objective of sharing the same set of validations across all the layers of an application, Bean Validation is integrated across the Java EE 6 platform. For example, presentation-layer technologies such as JSF and enterprise-layer technologies such as JPA have access to the constraint definitions and validators available through the Bean Validation framework. You no longer need to specify constraints in multiple places and in multiple ways across the layers of an application.

To learn more about Bean Validation, see Bean Validation, JSR 303.