Introducing the Java EE Web Profile
Reza Rahman looks at the Web Profile: what it is, what it contains and why it’s empowering.
Introduced in Java EE 6, the Web Profile radically streamlines the platform and enables the creation of a new dawn of lightweight, agile, compelling application servers with a laser focus on web application development. In this article, we will discuss what the Web Profile is, what it contains, why it is so empowering, give you a quick tour of the profile and tell you about the application servers – currently available and upcoming – that implement the Web Profile.
Much like other mainstream development platforms like Microsoft .NET, Java EE attempts to provide a comprehensive runtime covering as many server-side application use-cases as possible. As a result Java EE has had an ever-expanding set of APIs gradually added to it over the years. The problem is that until the introduction of Profiles, Java EE has also been a monolithic API set. This one-size-fits-all approach has meant that most applications do not use a significant number of APIs in Java EE. For example, most web applications do not use remoting but do use the web tier APIs like Servlet, JSP and JSF.
Similarly, SOA centric “headless” applications might use features like messaging, remoting, SOAP and REST but have no use for JSF or JSP. The heavyweight feel of application servers that implement the entire Java EE API set is a symptom of this underlying problem (although this is not the only source of the problem; some commercial offerings have now become notorious for adding extraneous “enterprise” bells and whistles beyond Java EE to their platform that approaches the magnitude of gigabytes!). This “heaviness” often manifests itself as large download sizes, convoluted installation, slow startup/shutdown times, large runtime memory footprint, slow deployment, elaborate management consoles and sluggish administrative responsiveness.
Profiles in Java EE 6 are aimed at this problem by defining sub-sets of APIs geared towards particular types of serverside applications (it is also a not-so-subtle hint to some implementers that “enough is enough”). Following the previous examples, profiles geared towards web applications or SOA applications might make sense. The Web Profile is the first and only profile defined in Java EE 6 (the expectation is that other profiles will be defined going forward as needed).
Inside the Web Profile
The Web Profile is composed of a complete set of Java EE APIs that is needed for a majority of modern web applications. This includes APIs for the presentation tier, business tier, persistence tier, transactions, security, dependency injection, cross-cutting logic, constraint management and testing. Table 1 outlines the specific APIs included in the Java EE 6 Web Profile.
Note the Web Profile includes EJB Lite, not the full EJB API. Like profiles, EJB 3.1 Lite is a sub-set of the full EJB API intended specifically for web applications. It includes stateless session beans, stateful session beans, singleton beans, declarative and programmatic transactions, declarative and programmatic security as well as an embedded container geared towards testing. EJB 3.1 Lite does not have support for message driven beans, asynchronous processing, scheduling, REST (JAX-RS) end-points, SOAP (JAX-WS) end-points, RMI/CORBA based remoting as well as backwards compatibility requirements for EJB 2. Table 2 shows features in the EJB Lite vs. full EJB API.
The Java EE 6 Web Profile leaves out a number of APIs that are not used frequently in web applications such as JAX-WS, JAX-RPC, JAXR, SAAJ, JAX-RS, JAXB, JMS, JAAS, JASPIC, JACC, JCA, JavaMail, the Java EE Management Specification (JSR 77) and the Java EE Deployment Specification (JSR 88). The Web Profile also only includes support for WAR files and not EAR files.
Note profiles do not stop a vendor from adding APIs and features as they see fit. For example, as I’ll discuss shortly, Resin adds support for JMS, EJB scheduling, asynchronous processing, message driven beans and remoting.
It’s Always about the Tradeoffs
As you can see, the Java EE 6 Web Profile is all about trade-offs and those trade-offs were not easy to decide on. Adding redundant APIs would mean making the profile less streamlined. Missing frequently used APIs would mean leaving obvious gaps that Java EE developers would have to fill themselves (likely by integrating third-part APIs) – taking away from the Java EE promise of standardization, portability, vendor-neutrality and providing a platform that trends towards zero configuration so that developers can focus on application-level development concerns rather than system-level configuration concerns.
Ultimately, the overriding motivation was making the Web Profile as small as possible by focusing on the 80% web application use-case. Particularly tough were the decisions on whether or not to include JavaMail and JAX-RS. Similarly it was difficult to decide whether or not to include JCA for greater vendor pluggability. In some ways, the Web Profile gets rid of the cruft that has built up in Java EE over the years and paves the way for a next-generation of lightweight Java EE application servers. In fact, for the Resin team, it raises the question of whether full profile application servers have a significant place in the server-side market any more.
The flip side of the profile story is whether it compromises flexibility – so what happens when you want to use APIs outside the Web Profile? There are three answers to this question. The first is that the vendor you are using may provide you a smooth upgrade path by providing the additional APIs in a transparent, pluggable fashion. As we will discuss shortly, the OSGi based GlassFish Web Profile server is a great example of this. The second answer is for you to choose a vendor that ships with the additional APIs you need (remember that the vendors can add whatever APIs they want beyond the Web Profile). The last and probably the most unlikely option is to simply switch application server implementations.
Another facet of the profile debate is whether or not to simply have a profile with the Servlet specification and no other Java EE APIs. While this option might seem compelling in a Zen-inspired minimalist sense, it quickly leads to a lot of easily avoidable complexity for a majority of cases.
The fundamental problem is that modern web applications use a lot more than the Servlet API. In fact, there are very few non-legacy applications that use the Servlet API directly. Most applications need a transaction manager, persistence mechanism and higher-level presentation layer API, not to mention dependency injection, security and crosscutting logic. As a result, starting with a plain Servlet engine necessitates configuring numerous third-party APIs on top of the minimal container to get these features. Even while using the most efficient integration solution, configuring and maintaining these third-party APIs become tasks in their own right, especially compounded by the number of applications that need to be configured in an ad-hoc fashion.
The complexity involved in such configuration tasks have very little to do with solving business domain problems. In reality the configuration task is really the domain of an administrator or integrator working at the system level rather than a developer working at the application level. This complex development model is in stark contrast to platforms like Ruby on Rails which effectively promote ease-of-use and convention-over-configuration. Indeed this development model is likely sensible only in contrast to using a full-scale Java application server that is very heavyweight or for systems that are really very specialized. This is also an approach that has the most potential to severely limit standardization and vendor-neutrality.
A First Taste
The Java EE 6 Web Profile is actually so streamlined that it is possible to walk though the entire stack in the space of a few written pages. Without further ado, let’s do that right now. It will give you a first-hand flavor of how the stack actually looks. Figure 2 shows a simple login page written in JSF 2. Listing 1 shows the Facelet based JSF 2 code for the page. As you might be able to gather from the <ui:composition> tag, a template stored in template.xhtml is applied to the page and contains the header and footer. Listing 2 shows the template, it’s pretty simple.
Notice that the template <ui:insert> tag names match up with the <ui:define> tag names in the login page such that the content of the <ui:define> tags are placed into the template. Facelet templates are one of the more powerful things added in JSF 2. Just like templates, Facelets also allows you to define components through simple markup. Going back to the login page, notice that the page uses a component defined by the <login:loginPanel> tag. The component itself is actually a Facelet page that looks like Listing 3.
While the interface of the <login:loginPanel> component is defined in the <composite:interface> section, the implementation is defined in <composite:implementation>. The <composite:attribute> tags define the parameters to the component and the cc.attrs variable is used to reference these parameters in the component implementation. The login component references two backing beans – “credentials” and “login”. While the username and password is bound to the “credentials” bean, the “login” bean actually handles the login event. Both beans are CDI managed beans. The “credentials” bean looks like Listing 4.
The credentials bean is @Named so it can be referenced from a Facelet page and is in the request scope. @NotNull and @Size are bean validation constraints. JSF automatically evaluates them when the login event is triggered and fails the submission with the specific message if needed. JPA 2 similarly automatically evaluates bean validation constraints on entities. The login bean has a little bit more going on (Listing 5).
The login event handler is named and session scoped. This is because we would need the login information throughout the session. The request scoped “credentials” bean is injected into the “login” bean so that the login entered can be checked. A back-end service, UserService, is also injected into the “login” bean. The user service is used in the login method to retrieve the user corresponding to the login. If the login succeeds, the user is forwarded to the accounts page. Note that the user is stored in an instance variable so that we can retrieve it throughout the session via the “login” bean or check for the current login state (as we do in template. xhtml). The user back-end service is an EJB stateless session bean:
Because the service is an EJB, it is automatically transactional, completely thread-safe and most likely pooled, so you have to do nothing to effectively use resources like database connections or JPA entity managers. Listing 5 shows how the injected user DAO looks.
The DAO is a plain CDI managed bean with no name and default scope (in fact, it has no annotations on it except for the @PersistenceContext annotation). An entity manager is injected into it and used as needed (it is perfectly OK since the DAO is protected by the EJB layer). The code above also shows you the newly added JPA 2 criteria query facility. As you can guess, User is a JPA entity. Listing 7 shows how it looks.
As you can see, the entity is mapped to a table named USERS. Like the credentials bean, it also has bean validation constraints. Lastly, thanks to CDI, Java EE 6 embedded containers and tools like JBoss Arquillian can unit test any layer of your application. Here is some code to show you how an Arquillian JUnit test for the user service might look:
As you can see, the actual EJB can be injected right into the unit test using Arquillian. Because of the embedded container, everything is seamless and self-contained. No external application server needs to be running and there is no deployment process to go through!
Believe it or not, we just toured through the entire Java EE 6 Web Profile stack including JSF 2, CDI, EJB 3.1, JPA 2 and bean validation! Obviously, this is a very small tip of a very, very large iceberg and each API at each layer has a lot more features to explore.
Web Profile Implementations
There are a number of Java EE 6 web profile implementations currently available or actively underway including GlassFish, JBoss AS and Resin. Here are some details on each:
• GlassFish: GlassFish has both a Web Profile and Full Profile offering. Because GlassFish is the reference implementation, it strictly adheres to the Java EE 6 Web Profile and does not add any additional APIs. However, because GlassFish is based on OSGi, you can use the GlassFish console update center to dynamically add any other Java EE API you need – often without a restart!
• Resin: Resin is the only major open source application server solely focused on the Web Profile. Although most people think of Resin as a fast, reliable Servlet container, Resin has been more than just a Servlet container for a long time. For example, Resin has had database connection pooling, clustering, load-balancing and Hessian based remoting for years. In fact, Resin embraced EJB 3 with Resin 3. The problem was that because of backwards compatibility requirements in EJB 3, it was still necessary to fully implement EJB 2 and RMI/CORBA remoting. Due to the absence of profiles, Resin would have also been forced to support bloated APIs like JAX-RPC, JAXR, SAAJ, JACC, JAAS, JASPIC and the like. With CDI and the Web Profile, the Resin team has been an enthusiastic supporter of Java EE 6 and Resin 4 now passes the Java EE 6 Web Profile TCK. Besides the Java EE 6 Web Profile APIs, Resin 4 includes JMS as well as almost the entire EJB API except for EJB 2 and RMI/CORBA support. Resin also allows you to use all EJB service annotations in plain CDI managed beans and includes a Resin optimized JUnit test framework. Resin supports JAX-WS, JAX-RS and Java-Mail as additional plug-ins.
• JBoss AS: JBoss will offer both a Web Profile and full profile implementation. The Web Profile implementation is currently available.
• Others: Geronimo is very close to finishing the Java EE 6 Web Profile and will also offer a full profile server. Web Logic 11g R2 will support both the full and Web Profile
– it’s planned for calendar year 2011. SIwpas is a Tomcat based open source Java EE 6 Web Profile offering leveraging Apache projects from a Turkish company MechSoft.
– they have not pursued certification yet. TomEE is another Tomcat based open source Java EE 6 Web Profile leveraging Apache projects, from the Apache OpenEJB folks – they have not pursued certification yet either. TomEE adds Java-Mail, JCA, JMS, JAX-WS and JAX-RS to the Web Profile.
There are bound to be other offerings on the table as time progresses for the Java EE 6 Web Profile, including possibly one from OW2.
The Java EE 6 Web Profile truly streamlines the platform and enables the creation of a simple, lightweight, compelling, cohesive set of next-generation application servers for painless web application development. There are a number of Web Profile choices available today with more on the way. If you have not done so yet, you really should give the Java EE 6 Web Profile a spin!