Q&A with Gavin King on the Impact of JSR-299 and Weld 1.0 on Java EE and JBoss

Red Hat's JBoss division has shipped Weld 1.0.0, Java EE 6's reference implementation for JSR-299: Contexts and Dependency Injection for Java EE (hereafter CDI). Weld is the implementation used in Sun's GlassFish Application Server version 3 and the upcoming JBoss AS 5.2.0. It does not need a full application server however. Weld can be run in a servlet container such as Jetty 6.1 or Tomcat 6, and also works with Java SE 5.0 and above. To demonstrate the latter, the Weld distribution comes with an example console application and an example Swing application.

Since a draft of JSR-299 was first submitted, Google and SpringSource submitted JSR-330 with the aim of standardising "a proven, non-controversial set of annotations that make injectable classes portable across frameworks", so when I caught up with CDI specification lead Gavin King I began by asking him what impact JSR-330 had on CDI.

CDI now uses the annotations defined by JSR-330 to declare injection points. This had a very minimal impact, since the model used in 330 is essentially identical to what 299 had already defined. It boiled down, more or less, to a change in annotation names.

Remember that 330 does not define a full dependency injection solution. It defines just enough to let you declare an injection point, with qualifiers, and then leaves the rest undefined.

InfoQ: How do CDI and EJB work with the Managed Bean model introduced in EE 6?

The new Managed Beans specification was the result of work we did in JSR-299 (what we were calling "simple Web Beans" in earlier drafts of the specification). Simple Web Beans supported dependency injection, EL names and interceptors, but did not have the programming restrictions or full capabilities of EJBs.

There was plenty of controversy as a result of this, with Red Hat arguing that we absolutely needed to be able to support injection of plain Java classes, and other EE stakeholders making clear that they were not comfortable with 299 defining a new kind of EE "component".

After much discussion, we arrived at a solution whereby this idea of a "simple" component would be removed to its own specification, forming the foundation of all other EE component programming models, including EJB, etc. That's a great vision, which we're all very happy with, though it is still not quite fully realized in EE 6.

The end result is: CDI can work with plain Java classes, now called "managed beans", or with EJBs. And EJBs are now considered just a special kind of managed bean, with some additional programming restrictions and some additional capabilities. It's a graduated programming model that makes EE significantly simpler to digest for new users.

InfoQ: Does EJB still need its own component model?

I think the direction for the EE platform is to gradually generalize the capabilities that are currently defined only for EJBs, and have them apply to all managed beans. For example, there's no reason why @TransactionAttribute and @RolesAllowed shouldn't be supported for all managed beans.

However, EJB will still have a place in defining endpoints for message delivery, remote and asynchronous method invocation, timers, etc. In these cases, the EJB lifecycle model makes plenty of sense.

InfoQ: Seam has provided inspiration to JSF 2 as well as CDI. What advantage does fixing the problems in JSF itself have over addressing them in Seam?

Well, as hard as we tried to make the user experience utterly transparent, we were never quite satisfied. Our users were always aware when they were using a feature of JSF, and when they were using a feature of Seam that should have been in JSF.

CDI grew out of Red Hat's experience with the open source Seam framework, and in broad terms standardises Seam's programming model as the programming model for Java EE 6. CDI serves three major purposes in Java EE 6. First it provides a declarative way to manage the scope, state and life-cycle of components bound to contexts. Second it provides a standardised, annotation-driven, type-safe dependency injection framework for the platform similar in approach to Google's Guice. Thirdly it provides a Service Provider Interface (SPI) for developing portable extensions for the Java EE platform.

CDI's Service Provider Interface has become a key part of Java EE's extensibility, a central aim of Java EE 6. The JSR-316 specification states:

...we believe it is desirable to enable more of these technologies to cleanly layer on or plug in to Java EE application servers. By adding more extensibility points and more service provider interfaces, these other technologies can plug in to platform implementations cleanly and efficiently, and be just as easy to use for developers as the facilities that are built into the platform.

An example of this in action can be found in the next release of Seam, version 3, which uses CDI as its core engine and then uses the CDI Service Provider Interface to offer a number of additional features not found in CDI such as BPM integration, Drools integration, support for PDF and email templates, Excel generation, and so on. These extensions (and potentially others built by third party vendors) can be run in any environment which supports JSR-299 including any Java EE 6 environment. According to the CDI spec:

A portable extension may integrate with the container by:
• Providing its own beans, interceptors and decorators to the container
• Injecting dependencies into its own objects using the dependency injection service
• Providing a context implementation for a custom scope
• Augmenting or overriding the annotation-based metadata with metadata from some other source

Gavin King told InfoQ:

The advent of CDI and JSF2 represents a new direction for Seam.

In Seam2, we wasted a huge amount of energy papering over the cracks in JSF, and the result was that we just didn't have time to work on integration with the full range of presentation technologies that interest us. JSF2 lets us focus our energies in other areas.

Most importantly, CDI now provides a core "engine" which is portable between all EE 6 application servers and is even available for Tomcat, Jetty and Resin. This core has no dependency to any particular presentation technology. What it has instead is a well-defined SPI for portable extension developers. This SPI serves as the foundation for an ecosystem. If you're a framework developer, you now know exactly what you need to do to integrate your framework with CDI and, by extension, with the EE environment. This is perhaps the most exciting feature of CDI.

So, Seam3 is going to be a set of CDI portable extensions, that work on any application server, and provide extensions to the programming model of CDI, and integration with other technologies that interest us.

Mark Little, CTO for JBoss, has stated that CDI and Seam are the future for all of their projects and platforms:

The team are already working closely with those projects and platforms, such as ESB and SOA-P, to ensure that new versions of Seam take into account their unique requirements. Importantly though, some of those projects had already decided that Seam was right for them even without any modifications to it, so it's likely you will see closer and quicker integration than some thought possible.

And King confirmed this, adding:

Seam has already been used successfully by quite a few projects at Red Hat. CDI puts the core functionality of Seam on a much more solid foundation, and our implementation of CDI, Weld, is a much more focused and much better tested piece of infrastructure. This means that we can start to use Weld for all kinds of things where Seam2 simply would not have been appropriate. Things that have nothing to do with building websites.

This is equally true outside of Red Hat and a number of other implementations of CDI are also springing up. Resin maker Caucho Technology have an implementation (CanDI) and the Resin container itself makes extensive use of CDI internally. Apache too are working on an implementation called OpenWebBeans, and Granite DS has an implementation allowing CDI to be used with Flex applications, writing:

Our feeling is that JCDI is a perfect fit for Flex RIAs with an event-driven architecture. JCDI applications look extremely clean and even [though] JBoss Seam provides a lot more features, they do not necessarily make sense with a RIA front-end.

JBoss should have taken the opportunity to build a great web framework and push that as a standard, instead of supporting the existing broken JSF technology. Seam makes JSF usable but JSF is just overblown technology. I work with JSF every day now and I wish I could just be using a simple mvc framework like stripes or spring mvc combined with an excellent javascript library like jquery.

I really don't believe that the world would have benefited that much from us creating yet another web framework. There are already so many vanity web frameworks out there, that the audience for another non-standard web framework is necessarily limited. (Well, unless you can up up with something truly unique.) And to try and take something we did from scratch on our own and push it through the JCP as a replacement for JSF would have been an almost impossible task.

On the other hand, there was a lot to be gained by improving the standard option that already existed as part of the platform. There are a lot of JSF shops out there, and they are all going to get a great boost out of JSF2.

And let's not forget that there are a significant number of people out there who are fans of JSF (including me, with several reservations). I've tried most of the leading Java web frameworks, and honestly, they are all very far from perfect. JSF has an overall architecture that I'm very comfortable with, so I've been willing to overlook some of the flaws. I personally do not want to go back to an action-oriented framework like struts2 or stripes. (Perhaps I am in the minority, but that's how I feel.)

Now, JSF2 is the real test. We've done most of what we realistically can to "fix" it. If that's not enough, then I'm prepared to throw in the towel on JSF and put our energy into a competitor like Wicket. But I do believe that 2.0 is a big improvement, especially when you are using it with CDI. There's no piece of JSF which has not been totally refreshed in 2.0:

model - CDI, which changes everything ;-)

view - facelets, which is awesome, is now baked in

controller - critical enhancements to navigation and lifecycle for GET requests

component development - huge improvements, including the great composite components stuff

OTOH, we're also hedging our bets a little. CDI is going to be a great option no matter what web framework you choose to use. So that's a significant change of strategy. (But it's not in any way a repudiation of JSF.)

JSF2 actually looks pretty decent. Take a look then maybe you can persuade your current project lead to adopt it in place of JSF1. It'll be easier to convince them to do that then drop everything in favour of insert framework here

I wish I could just be using a simple mvc framework like stripes or spring mvc combined with an excellent javascript library like jquery.

I could never go back to an action/mvc2 framework. They simply don't promote DRY programming, and become too difficult to manage page state and navigation as you add more and more capabilities to a page. As well, keeping the state of the page and any processing on the server instead of on the client (using javascript) is more secure and IMHO less error prone.

Javascript should just be hidden away at the component level never to be seen on the page template. I'm probably the only person who thinks that.

I work with JSF+Seam everyday, and that combination is definitely not broken. So there's no reason to think JSF 2 will be if it's incorporating all of the Seam JSF features. Of course there are still some issues I have with JSF 2, like its restrictive navigation model (still beats an action framework though), and it still seems difficult to create a real (as opposed to composite/compound) component when compared to a framework like Wicket, or an RIA.

JSF2 actually looks pretty decent. Take a look then maybe you can persuade your current project lead to adopt it in place of JSF1. It'll be easier to convince them to do that then drop everything in favour of insert framework here

And we decided to upgrade to JBoss 5.x. And we then decide to drop in JSF 2.0 RI (or if it's already included with the app server like it is in JBoss 4.x, then start using new tags, features, etc. in JSF 2). Is this possible and then slowly migrate to CDI/Weld or Seam3 in the future?

Is JSF 2.0 compatible with Seam 2.x and/or RichFaces 3.x? I'm thinking of the phased approach to upgrading the project.

btw, how come nobody talks about Tapestry, but mostly Flex, JSF and Wicket? Tapestry is a mature component-based MVC framework with a decent-sized following...

And we decided to upgrade to JBoss 5.x. And we then decide to drop in JSF 2.0 RI (or if it's already included with the app server like it is in JBoss 4.x

JSF 2 will be included in the next release of JBoss.

is this possible and then slowly migrate to CDI/Weld or Seam3 in the future?

Sure.

Is JSF 2.0 compatible with Seam 2.x and/or RichFaces 3.x? I'm thinking of the phased approach to upgrading the project

My understanding is that there are currently some minor issues with JSF2 and RichFaces, but they will be resolved soon. But it would be better to ask the RichFaces folks, since I'm sure they have a much better idea of the timeline.

thanks for the link and good luck with your project. It would be nice to have the option of an action framework on top of seam or jsr-299. Put a wrapper around it similar to grails and you would have a awesome stack.

thanks for the link and good luck with your project. It would be nice to have the option of an action framework on top of seam or jsr-299. Put a wrapper around it similar to grails and you would have a awesome stack.

"I wanted to get away from the awful 'front controller' pattern, where some big stupid stateless method is responsible for coordinating everything involved in processing the event, from state retrieval and storage, to service location, to orchestration."

GKing is not a fan of Struts (ActionServlet) or SpringMVC (DispatcherServlet) or most likely any other front controller-based web framework.

Reusability tends to be limited with action-based MVC vs. component-based MVC. Plus you get render kits with JSF as well as extension UI AJAX frameworks like RichFaces and ICEFaces. Flex is something worth looking into. Binary AMF3 transfer protocol and no more javascript cross-browser issues...