Resin Java EE 6 Web Profile
From Resin 3.0
Contents |
Introduction
Caucho Technologies aims to certify the Resin application server on the newly finalized Java EE 6 Web Profile. Resin enjoys a solid reputation for being one of the fastest, lightest and most stable application servers in the industry supporting some of the most high traffic web sites in the world including Salesforce, CNET and the Toronto stock exchange.
This white paper briefly discusses the Java EE 6 Web Profile, what it offers and how it fits with the firmly lightweight development philosophy of Resin as well as the details of our implementation including Resin extensions to the Java EE 6 Web Profile.
Java EE 6 Web Profile
Much like other mainstream development platforms like .NET, Java EE attempts to provide a comprehensive API set covering as many applications and use-cases as possible. As a result Java EE has had an ever-expanding set of APIs gradually added to it over time. The problem is that until the introduction of Profiles, Java EE has been a monolithic API set. This one-size-fits-all approach has meant that most applications do not use a large 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 footprint of application servers that implement the entire Java EE API set is a symptom of this underlying problem.
Profiles in Java EE 6 are designed to address this problem by defining sub-sets of APIs geared towards particular types of applications. Following the previous examples, profiles geared towards web applications and SOA applications might make sense. In fact, 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). 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, context management, dependency injection, crosscutting logic, constraint management and testing. The following table outlines the specific APIs included in the Java EE 6 Web Profile and their intended purpose:
API | Purpose |
---|---|
JSF 2, Facelet, JSP, Servlet 3 | Web tier |
CDI, managed beans, interceptors | Dependency injection, context management, cross-cutting logic, events, extensibility, integration, testing |
EJB 3.1 Lite | Business tier, declarative and programmatic transactions, declarative and programmatic security, testing |
JTA | Transaction management |
JPA 2 | Persistence tier |
Bean validation | Constraints management |
Like Profiles, EJB 3.1 Lite is a sub-set of the full EJB API. 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 out-of-container 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.x.
The Java EE 6 Web Profile leaves out a number of APIs that are not used often 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. As we will discuss shortly, we have chosen to add a very small number of Java EE APIs and features on top of the Web Profile. Specifically, we see value in adding support for scheduling, asynchronous processing, messaging, message driven beans and Hessian based remoting.
Resin and Java EE
The Resin team has always focused on delivering a lightweight, fast, reliable and easy-to-use application server. We have also always respected the value in standardization, developer choice, multilateral collaboration and having competing but compatible products. These ideas are clearly factors in the success of server-side Java that builds on the good foundations of a portable, scalable, type-safe programming language and leads to a lively industry ecosystem enriched by wide adoption, open source, innovation, disciplined development practices and enterprise credibility. However, before the Java EE 6 Web Profile, it was difficult to reconcile these concepts in Resin. The choices were really split between either creating a lightweight Java application server or aiming for full standards compliance. Resin has historically chosen the lightweight implementation route along the same lines as Tomcat and Jetty (with some important differences we will discuss shortly).
The problems with earlier versions of Java EE are now well understood. They included an over-emphasis on CORBA/remoting in EJB 1.x, the heavyweight programming paradigm in EJB 2.x, the flawed persistence model in EJB 2.x entity beans, serious problems in portability as well as the complexity in XML deployment descriptors. While Java EE 5 went a long way to solving the issues around ease-of-use, we still saw a number of practical roadblocks in the way of creating a really lightweight implementation that Resin developers would find compelling.
Because of backwards compatibility requirements in EJB 3.0, it was still necessary to fully implement EJB 2.x and RMI/CORBA remoting. Due to the absence of profiles, we would have been forced to support bloated APIs like JAX-WS, JAX-RPC, JAXR, SAAJ, JACC, JAAS, JASPIC, JAXB, JCA, the Java EE Management Specification (JSR 77) and the Java EE Deployment Specification (JSR 88). As a result, we decided to continue to primarily focus on the Servlet API instead pursuing Java EE 5 compliance while still supporting the annotation-driven programming model in EJB 3/JPA as well as maintaining lightweight alternatives to RMI/CORBA such as Hessian.
With the Java EE 6 Web Profile, we finally feel confident that we can deliver a fully standards compliant version of Resin that is really on the mark in terms of features and usability. We are excited in creating a very lightweight Java EE application server perhaps more compelling than any other server-side Java development option with a great "just-works-out-of-the-box" development experience.
Resin and Servlet Containers
While we are firm believers in lightweight development, we feel that taking the extreme approach of simply implementing the Servlet specification and nothing else is the wrong set of trade-offs to make. While this minimalist option seems good in theory, 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, scheduling and crosscutting logic. Some applications also need support for messaging as well as remoting via an efficient binary protocol like Hessian.
As a result, development shops that go the plain Servlet engine route end up 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. 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 development model is in stark contrast to platforms that provide end-to-end integrated solutions like Ruby on Rails which effective 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. Besides development APIs, a vast majority of enterprise applications also need scalability features like resource/connection pools, thread/process management, bandwidth throttling, caching, clustering, load-balancing and distributed transactions as well as management, monitoring and administration facilities. It is impossible or very difficult to add such features to a plain Servlet container as a third-party extension.
For these reasons, we believe a lightweight Resin implementation of the Java EE 6 Web Profile makes the right set of trade-offs by providing features that a majority of web applications need out-of-the-box and minimizing the configuration burden.
The Resin Java EE 6 Web Profile Implementation
The basic Resin strategy to supporting the Java EE 6 Web Profile is to provide Caucho implementations for core APIs and integrate best of breed pluggable open source implementations developed by other responsible, reputable organizations where it best makes sense. This strategy allows us to focus on delivering very high quality implementations where we can best add value to developers while not needlessly duplicating effort and leveraging the Java EE open source ecosystem in a sensible way.
In line with this philosophy, we are providing independent Caucho implementations for managed beans, interceptors, CDI, Servlet 3/JSP and EJB 3.1 Lite. Resin also includes its own high performance JTA compatible transaction manager, a very lightweight JMS implementation as well as the Hessian binary remoting protocol that offers better performance than RMI/CORBA and works over HTTP. Building on these core APIs, Caucho will integrate the reference implementations for JSF 2, Facelets, JPA 2, bean validation and JAX-RS. All of these implementations have been independently certified for Java EE 6 as part of the GlassFish application server.
Contexts and Dependency Injection
The Contexts and Dependency Injection for Java EE (CDI) API is one of key parts of the Web Profile. It provides robust context management including support for conversations, type-safe next-generation generic dependency injection, stereotypes, interceptors, decorators, lightweight events as well as a powerful SPI intended for building portable extensions. As active participants in JSR 299, the Resin team played an important part in providing visionary support for the CDI API. We are very proud in offering a very high quality independent implementation of CDI. Our implementation, CanDI is one of the three major implementations of CDI, along with Apache's OpenWebBeans and Weld, the reference implementation from JBoss. CanDI is the centerpiece for the Caucho implementation of the Java EE 6 Web Profile. Indeed, many parts of the Resin application server itself has been written using CanDI.
A number of possible additions to CDI are in the works via CanDI. For example, we are considering adding custom @TransactionScoped/@ThreadScoped in addition to the standard @ApplicationScoped, @SessionScoped, @RequestScoped and @ConversationScoped. We also plan to provide portable extensions for integrating popular open source and standard tools that developers would find useful. The possibilities include integration/ease-of-use CDI portable extensions for JMS, JDBC, JAXB, JavaMail, Struts 2, Wicket, iBATIS and Quartz. We will also fully support all portable extensions developed by the Apache and JBoss CDI projects on CanDI/Resin.
Servlet 3
Servlet 3 brings a major overhaul to this foundational Java EE API. The changes include full support for annotations, pluggable web.xml fragments, programmatic addition of Servlets, Filters, Listeners at runtime as well as asynchronous processing. While annotation support is geared towards ease-of-use and the asynchronous processing capabilities add better support for emerging paradigms like Comet, the rest of the changes are critical in improving pluggability for the rich set of third-party tools and frameworks that build on Servlets such as JSF, Facelets, Wicket, Struts 2 and the like. Taken as a whole, these changes will likely enable stronger innovation in the web tier based on the new capabilities in Servlet 3. We have long focused on excellent support for the Servlet API and will continue to do so with Servlet 3. In fact, it is one of our first APIs aimed to get officially certified against the Sun compatibility test kit.
EJB 3.1 Lite
EJB 3.1 has both further ease-of-use elements as well as core features frequently requested by developers. The changes include session bean optional interfaces, singleton beans with concurrency control, cron-style declarative and programmatic timers, asynchronous bean invocation, support for packaging EJBs in WARs, embedded container support for unit testing, standardized global JNDI naming as well as the definition of EJB Lite. In addition to basic support for EJB Lite, Resin will include support for EJB scheduling (@Schedule, @Timeout), asynchronous processing (@Asynchronous), message driven beans (@MessageDriven) and Hessian based remoting (@Remote).
In our view, one of the most important changes in EJB 3.1 is the redefinition of EJBs as simple managed bean POJOs with additional services. We have taken this realignment to the logical next step by allowing developers to use EJB annotations in CanDI managed beans in addition to EJBs including the @TransactionAttribute, @Schedule, @Asynchronous, @RolesAllowed, @PermitAll, @DenyAll, @RunAs, @Lock , @Startup and @Remote. Here are a few examples of this capability:
@ApplicationScoped @TransactionAttribute(REQUIRED) public class BidDao { // Resin thread-safe EntityManager proxy. @PersistenceContext private EntityManager entityManager; public void addBid (Bid bid) { entityManager.persist(bid); } }
@Startup @ApplicationScoped public class NewsLetterGenerator { @Schedule(dayOfMonth="L", month="*") // Last day of every month. public void generateMonthlyNewsLetter() { // Code to generate the monthly news letter goes here. } }
Unit Testing/Embedded Containers
Resin aims to provide excellent out-of-container unit/integration testing support for both JUnit and TestNG. Testing support will be based on the Resin embedded container built around CanDI, managed beans and EJB 3.1 Lite. Using JUnit and TestNG bootstrap mechanisms, the Resin test tools will inject components under test directly into testing artifacts that can be run from the command-line or IDE. The following code example shows these capabilities:
@RunWith(ResinJUnitRunner.class) // Deployment overrides for the test. @TestConfiguration(beanXML="beans-test.xml", ejbJar="ejb-jar-test.xml", persistenceXml="persistence-test.xml") public class AccountServiceTest { @Inject private AccountService accountService; @Test public void testGetAccount() throws Exception { Account account = accountService.getAccount(1007); assertNotNull(account); } }
Hessian Remoting
Hessian is an HTTP based binary communication protocol developed by Caucho. Hessian offers better performance than RMI/CORBA, SOAP or REST. Since it is HTTP based, it can work across firewalls much like web services. Because of these characteristics, we believe it is the ideal communication protocol for remoting using Resin and Java EE 6. Resin supports Hessian remoting through the EJB @Remote annotation as in the example below:
@Remote public interface BidService { public void addBid(Bid bid); } @ApplicationScoped public class DefaultBidService implements BidService { ... }
Spring Support
A large number of Resin customers currently use the popular Spring framework. We have always provided and will continue to provide excellent runtime support for the framework. Indeed, we believe great opportunities for even better Spring framework integration exist particularly via the common Dependency Injection for Java (JSR 330) annotations shared by both CDI and Spring IoC. We will explore such innovative integration possibilities going forward through the Resin Java EE 6 Web Profile implementation.