Taking Enterprise Java to a New Level

Java EE 6: A Better Development Experience Awaits!

Mike Keith
A-Better-Developer-Experience-Awaits

Java EE 6: What’s been added?

Enterprise Java standards have come a long way since 1998, when the first release of Enterprise JavaBeans (EJB) emerged. In 1999 the Java 2 Enterprise Edition (J2EE) platform was created, grouping EJB together with a suite of enterprise technologies and launching what was to become a comprehensive and practical set of vendor and developer standards for enterprise applications. The Java Enterprise Edition (Java EE) 6 specification, released in December of 2009, is the latest installment of that dynasty and has already started to make its mark on the Java community.

Who needs standards? In an era of substantial IT budgets (often measured in millions of dollars), most people see the value of standards. Companies win because their software investments are more protected than if they were to invest in proprietary technologies. If their relationship with a particular vendor turns sour, or their trust in its future is in question, or even if they just feel they can get more value elsewhere, they can change the underlying product that implements the standards to which their applications are written. They can also more easily find and hire developers to work on those products, since a standard set of well-defined technologies provides a common foundation and vocabulary for training, communicating, and assessing developer skills. But it’s not just the corporations that benefit from the existence of standards. Developers are also better off because their knowledge and experience is transferable across jobs and across implementations. They are not left stranded in a “dead-end job”, accumulating knowledge of little use outside of their immediate work environment.

Even vendors appreciate the value of standards, since by implementing standards they know that they have a greater chance of selling their software to a company that is risk averse. Product offerings will be more widely applicable and more readily consumed.

Too Slow and Too Fast

Technology changes at a pace unlike almost any other industry, prompting some to claim that a two to three year Java EE release cycle is just too long. They complain that too many new programming innovations occur between releases and that it takes too long to incorporate these into the platform. On the other hand, corporate IT folks complain that releases are too close together. A company with a software system containing three million lines of code cannot easily upgrade it to use a new technology. The momentum of massive software makes it simply impossible to make large changes in short periods of time. For these companies, changing the standards too quickly renders their systems obsolete sooner and makes it more difficult to find people to work on them.

Most people recognize the balancing act that must be followed. For a standard to be successful it must be adopted not only by the consultants, who are eagerly riding the bleeding edge of as many new technologies as they can fit into an application, but by corporations with large systems. New technology innovations should be given some time in the testing grounds of practice before being incorporated into the specification.

Adopting new practices before they have reached widespread adoption or been proven to be of value would place the platform at risk and be doing a disservice to both the platform implementors and the users.

Breaking it Down

The Java EE 6 platform offers some new and exciting features to attract new developers, as well as some significant enhancements to some of the known stalwart specifications. We haven’t got the space to describe all of the changes in this article so we will focus primarily on the novel aspects of Java EE 6 and the new specifications that have been added. But before we break into the details let’s take a high level look at the Java EE 6 platform and the various specifications that make it up. Table 1 gives a brief description of each sub-specification and the changes that were made to it in Java EE 6.

With six new specifications added and thirteen updated it is clear that Java EE 6 is not your mother’s enterprise Java platform. Java EE has indisputably undergone a fairly dramatic evolution in terms of how developers can program applications.

Targeting the Web

One of the major thrusts of the release was to make web application development easier than ever. To this end, three major areas of improvement were pursued: creating a special profile tailored to web applications, features for more convenient web component development, and simpler archive packaging to round off the experience.

A separate Java EE profile for web applications is really just an instance of a more general profiling concept. The idea is that a given class of application may typically only make use of a subset of Java EE technologies, and that by defining a profile around that set it will be easier to produce and consume the software relevant to that application type. Vendors can implement and sell just the parts that are included in that profile, yet still be able to market it as a fully compliant profile.

Developers can purchase only the software they need for their applications without having to pay for or develop with the entire Java EE stack. It represents a reduction of both the development and production runtime footprints.

Given the prominence that web applications has in the industry right now a Web Profile was the obvious first profile candidate. The Web Profile was defined to contain enough for most web applications to do what they need, while leaving out the technologies that the majority of web applications don’t use. The following specifications make up the Web Profile. The version of each of these is the same as the one listed in Table 1.

• EJB Lite

• Servlet

• JavaServer Pages (JSP)

• Expression Language (EL)

• Java Transaction API (JTA)

• JSP Debugging

• Java Standard Tag Library (JSTL)

• JavaServer Faces (JSF)

• Common Annotations

• Java Persistence API (JPA)

• Bean Validation

• Managed Beans

• Interceptors

• Dependency Injection for Java

• Contexts and Dependency Injection

You may have noticed that the list does not specify EJB, but rather EJB Lite, a subset of EJB that includes only the more current POJO style components. The older components, based on an EJBHome and EJBObject client view, as well as some other portions of the specification that are seldom used for web applications, are not part of EJB Lite.

Many features have been added into the web and presentation components, as well as the new specifications (to be discussed later) that can be used in web components, but it suffices to say that creating presentation objects is much more convenient and flexible now than in previous releases. Support for annotations, asynchronous returns, AJAX, standardized facelets, validation, advanced injection, and more, puts more power into the hands of web developers and requires less effort.

Lastly, packaging a web archive was rendered less complicated for applications that have more than just web artifacts and persistent entities. Using transactional business components to encode the domain logic has long been accepted as a best practice, and up until now EJBs needed to be in a separate JAR file. An application that used both EJBs and web components needed to create an EAR file to house both the WAR and the JAR files. The packaging requirements have been loosened in EE 6 to allow EJB components to be packaged in WAR files, making an EJB JAR file completely unnecessary and an EAR file similarly unwarranted. The WAR file is the new application archive, and web applications that rely only on the Web Profile can be packaged completely within a single WAR file, from servlets and JSPs to EJBs and JPA persistence units. Figure 1 shows how a trivial application needed to be packaged in Java EE 5 and how it can be packaged in Java EE 6.

 

         

New Specifications

At this point we will introduce some of the specifications that are brand new to this release. With so much to say and so little space to say it in we can only give a taste of some of the added features of these specifications, but it should be enough to make the improvements obvious. We will not go into JASPIC because it is strictly a Service Provider Interface (SPI) for internal use within the container, and we won’t discuss interceptors because they existed in the previous release as part of the EJB specification and are therefore not really new.

RESTful Web Services

Because JAX-RS existed in 1.0 form before being included in Java EE 6 it had already become fairly widely adopted. Adding the 1.1 version to Java EE 6 gave it an enterprise blessing and ensured an integration with other Java EE components.

The simplicity of REST makes it an attractive alternative to SOAP-based protocols and also enables an existing enterprise application to easily export parts of itself as web services. A few annotations and a simple configuration model unite to create an almost effortless service creation experience. Listing 1 shows part of a root resource class for a RESTful web service.

The @Path annotation specifies the URI that directs a request to be serviced by this resource class. The URI is always relative to the server and can contain any number of variable names, each enclosed by curly braces and separated by slashes. For example, the path in Listing 1 is specified as /employee/{id}, meaning that a request with a URI of the form http://someserver.com/employeeApp/someContextRoot/employee/24513 may be serviced by this resource class. The last URI component will get assigned to the id variable as a result of the @PathParam injection, which in this example occurs in the constructor.

The @GET annotation denotes the HTTP method that is to be responded to. There are annotations for each of the other HTTP methods as well. @Produces matches the request with the service method that returns the corresponding return type, and @QueryParam injects the value of the named query parameter into the target. A URI of http://someserver.com/employeeApp/someContextRoot/employee/24513?count=5 would cause the size method parameter to be injected with the value 5 in our example.

RESTful web services are a much simpler way to achieve interoperability across systems than traditional XML-based web services, and this has led to REST becoming more and more popular. The JAX-RS standard provides the simplest possible model for developers to be able to leverage REST, while still staying within a familiar and standard programming model.

Managed Beans

A managed bean is really just a generic managed class that can be used virtually anywhere in the container. It is as simple as a JavaBean, but can be adorned with annotations to cause additional services to be supplied by the container, including resource injection, lifecycle callbacks and interception. Their container-wide applicability means they can be both injected into an EJB and act as a traditional JSF managed bean. They can also be an injection target for CDI, but more on that later.

An example of a managed bean can be quite trivial indeed, with nothing more than a class annotated with @Managed-Bean. The @Resource annotation can be used to inject resources. The lifecycle annotations, such as @PostConstruct, will be recognized by the container to cause the appropriate callback method invocations to occur. Interception annotations, as defined by the Interceptors specification, may even be applied to trigger interceptors. An example of a managed bean is in Listing 2.

Contexts and Dependency Injection

In Java EE 5 a fairly limited form of resource injection was available using @Resource and a few other specific annotations for certain resource types. The dependency injection state-of-the-art had gone far beyond that point, however, so an advanced form of injection was created. Contexts and Dependency Injection (CDI) defines a set of injection rules combined with a well-defined lifecycle for objects bound to contexts and ends up providing not only qualifiable injection but event notification, interception and decoration. We won’t go into all of the features of CDI, but a couple of examples show how easy and powerful injection has become.

The Dependency Injection for Java specification defined a set of standard annotations that can be used by injection frameworks and containers. CDI supports two of those annotations for developers to use on their domain code and two meta-annotations to decorate their own annotations for their injection infrastructure:

@Inject – specifies an injection point

@Qualifier – meta-annotation used to denote an annotation that will further constrain injection points

@Scope – meta-annotation used when defining a new scope

@Named – a built-in qualifier annotation for naming a bean

Because of the integration with the rest of Java EE, CDI can both inject, and inject into, managed beans (in JSF or not) and EJBs. It can also inject into servlets. The contexts can correspond to any of the three Request, Session and Application scopes in servlets, as well as a new Conversation scope in JSF. A unique user-defined scope can be added if needed.

A qualifier is an annotation that is typically defined by the application developer and can be used at an injection point to provide more details about the object to inject. It provides semantics to the injection, but decouples the actual injection point from the code or logic that dictates what gets injected. Listing 3 shows an example of using qualified injection. The @Preferred qualifier is defined and then qualifies the injection for the Customer object to be a WebCustomer. Because CustomerOrder is scoped to the HTTP session (being annotated with the built-in @SessionScoped annotation) the same contextual CustomerOrder stateful session bean instance will be injected and referenced everywhere within the current session. The life cycle of the stateful session bean will be controlled and managed by CDI.

Much more is possible with CDI so some experimentation or going through a tutorial is highly recommended. See the Java EE tutorial for a good starting point.

Bean Validation

Validation of state is a reasonably common task that can happen at almost any layer in an application. Sometimes it is even performed at multiple layers, for example at the presentation layer and again at the backend persistence engine. In order to prevent duplication, and to enable practical and versatile validation of domain object state, the bean validation standard was created. Validation can be performed through the use of a set of standard annotations and APIs, and a compliant pluggable validation provider that implements the specification.

Setting a bean up to be validated is as easy as putting constraint annotations on the bean fields (or properties) to be checked. They can be placed on a class for validation to occur against the entire class, but most times it makes sense just to validate individual state fields. The validation will occur either programmatically by invoking a validation API or as a result of a lifecycle state change in a JSF or JPA application. If a bean fails validation then the validator will throw a ValidationException indicating that the bean is invalid in its current state.

Developers can additionally define their own constraints and validation logic, enabling validation to take any form or to perform almost any checking. The result is that validation can be as simple or as complex as you want or need it to be, with additional flexibility to create groups of constraints to be validated at specific times. Listing 4 shows a class decorated with some of the built-in constraints, along with a custom @ValidScore constraint. The constraint definition (with its three required attributes) and the validation implementation class are also shown.

The HockeyGame class was left as a simple class to keep it clear of other artifacts unrelated to validation, but it would likely be an entity that was annotated as such and contained JPA mappings. Instances could be validated at the time they are created, or further down the stack at database insertion time. When being validated, the ScoreValidator.isValid() method will be invoked against the ScoringInfo instance stored in the game.

Summary

The Java EE 6 platform is a complete multi-vendor Java platform, and the fact that it is based on standards means it can used by more developers and more applications. Although Java as a language has had more and more features added to it, sometimes adding its share of complexity to the programming experience, the enterprise platform has become easier and easier to use with each new release. More is available and less is required on the part of vendors and developers. At the same time, Java EE has retained its reputation as being a stable and reliable platform for consultants and corporate IT departments alike.

We have tried to give you an idea of the kinds of features that have been added to Java EE 6, but much has been left unsaid. The best way to get a more accurate feel for the platform is to download it and try it out. The Glassfish Reference Implementation server is open source and free and can be used both for experimenting and for deploying applications into production. See [4] for more information about how to download and get started with Glassfish. A better development experience awaits!

Author
Mike Keith
Mike Keith was a co-lead of the EJB 3.0 and JPA 1.0 specifications in addition to representing Oracle on the Java EE 5 specification expert group. He co-authored the premier JPA reference book called Pro EJB 3: Java Persistence API and has over 15 years of teaching, research and development experience in object-oriented and distributed systems, specializing in object persistence. He currently works as an architect for Java persistence strategies at Oracle and represents Oracle on the JPA 2.0 (JSR 317) and Java EE 6 (JSR 316) expert groups. He is a popular speaker at numerous conferences and events around the world.
Comments
comments powered by Disqus