For several years, web application developers have been trapped between too much and too little. A servlet container like Tomcat doesn't provide all the infrastructure they need, missing critical items like transaction management, persistence and container managed beans. But many teams also feel that Java EE containers like JBoss have been forcing stuff down their throats that they simply don't need or want to know about. They don't need or want a CORBA ORB, support for EJB 2.x, a web service stack, EARs, remote EJBs, etc.

Meanwhile, vendors like JBoss have also been trapped. The EE brand is important to us since it signals to our customers that code written for our platform is portable to other implementations of Java EE, and that existing applications that were written for our competitors' products can easily be ported to run on our platform. Unsurprisingly, we share the opinion of many developers regarding the usefulness of certain technologies that were required by Java EE. For example, most of us were shaking our heads in astonished despair while the lemmings were following each other off the WS-WXYZ cliff a couple of years ago. What we've had to do is quietly implement these bits and then hope that our users don't actually use them for anything.

Other vendors, such as Caucho, chose a different path. A small company, the cost of implementing everything that was required by Java EE, including many technologies that just weren't interesting to their customers, was simply too great a burden. So they provided a servlet container, with a partial implementation of certain EE APIs. Of course, potential customers could never be certain about portability between Resin and other servers.

In this confusing environment, many developers rejected EE, and cobbled together their own stack of technologies based upon a plain servlet container like Tomcat. Since integrating these technologies was difficult - servlet containers have never provided much support for framework integration - solutions like the Spring framework popped up, with pre-built integration for a wide variety of technologies. Spring eventually involved into a proprietary container that competes with the EE platform. Unfortunately, the proprietary nature of Spring has resulted in vendor lock-in and slower innovation. Innovation in Spring has been so slow that Spring itself now looks decidedly creaky and old-fashioned compared to technologies like CDI that arrived much later.

Java web development is now so fractured that it's very difficult for framework developers like me to write code that works in all these environments. For example, transaction management, for which a complete, standard, solution has been available since 2002, is now a total mess.

Here's how Java EE 6 changes all this.

The Java EE Web Profile defines a smaller container, with just the technologies that most developers really need: servlets, JPA, JTA, CDI, EJB Lite. That makes EE easier to implement, which might result in a more vibrant market, with more implementations, and shorter release cycles. It definitely removes the main reason many developers give for not adopting Java EE.

Even better, the CDI portable extension SPI makes it much easier to integrate technologies into the Java EE environment. And, since some CDI implementations also run in a plain servlet container like Tomcat, CDI can also serve as a foundation for integrating technologies into these environments.

Thus, we've laid the technical foundation for a new ecosystem. A platform developers can be comfortable with, that lets vendors focus on things their customers actually care about, that framework developers can easily integrate with. The only missing ingredient is for the community to get excited about this stuff. :-)

The only missing ingredient is for the community to get excited about this stuff.

Oh i think we are - i certainly am. At the same time my head spins from the amount of change that the Java EE space has seen with version 6 in such comparatively short time. every time i see CDI example code i'm gobsmacked at how different it is from the old-style dependency injection i know (from Spring and Java EE 5).

with Java EE 5 i've started implementing when the only supporting container was JBoss with preview-level EJB3 support and no JAX-WS implementation. that has taught me to wait a bit longer: i won't recommend Java EE 6 for a real-world development project before at least 2 containers are certified for it. that may be not to far off, and that's just perfect. the time until then is easily spent on learning the details of how the new Java EE world works exactly.

i must say i'm also a bit stopped in my tracks by IBMs approval ballot comments:

The current lack of portability between JSR 330 and JSR 299 applications will create significant difficulties for the community. Application developers who use patterns based on JSR 330 injection annotations and proprietary injection mechanisms will experience integration issues when taking advantage of JSR 299 contexts associated with JSF. Insufficient attention has been paid to these details in the development of these specifications and this will reflect poorly on the Java EE platform as a whole. Although IBM previously voted in support of both JSR 299 and 330 with the clear expectation that the SE/EE injection programming model must be aligned into a single extensible programming model that defines a core set of functionality for SE and extends that with EE functionality, this has not yet been achieved.

my unease with this statement stems from the fact that it sounds serious yet i currently don't have enough insight to understand exactly what they are alluding to. i'll postpone my personal judgement until i do, but i remain wary.

I would add - where we make decisions, with or against standards, in the interest of simplicity and less complexity, that's warranted. Where we make decisions in the interest of laziness, that's a horse of a different color.

One other thing that I think you touched on briefly but I wanted to call out: standards aren't just about portability. I'm tired of learning 50 different APIs, frameworks, etc. that do the same thing, only because the ecosystem is so splintered/fractured. And one-integration-framework-to-rule-them all doesn't appeal to me.

i must say i'm also a bit stopped in my tracks by IBMs approval ballot comments:
The current lack of portability between JSR 330 and JSR 299 applications will create significant difficulties for the community. Application developers who use patterns based on JSR 330 injection annotations and proprietary injection mechanisms will experience integration issues

Well, while I share some of IBM's concerns about the unportable nature of applications written to use JSR-330 annotations and proprietary dependency injection solutions like Guice and Spring, I'm disappointed that they decided to vote against JSR-299, and I think they've mischaracterized the problem.

The problem is not that applications written for Guice or Spring using JSR-330 annotations don't run without change on CDI - though that is certainly true. The problem is bigger than that. It is that an application written for any JSR-330 container will not run without change on any other JSR-330 container. As I've been saying, JSR-330 is woefully underspecified and does not provide application portability. (The folks who proposed 330 did not actually have application portability as a goal!)

You simply can't write code that works using only the annotations in javax.inject. You also need a bunch of additional metadata, either in Guice java-based configuration, Spring XML, or CDI annotations.

Now, the good news is, that this issue does not affect portability between different implementations of CDI! JSR-299 does nail down everything that JSR-330 leaves unspecified. So, in a sense, 299 is the fix for the problems IBM sees in 330.

When I last spoke with IBM, what most concerned them was the scenario that a user who had written an application for Guice or Spring, using javax.inject, together with proprietary Spring XML, or com.google.guice configuration, would be surprised when their code did not run without change on a CDI container. Personally, I think this is a bit of a silly concern. Developers who import com.google.guice into their code realize that their code is not going to work on a container other than Guice. Spring users know their code isn't going to run without change on a different container. They are already well-aware of the proprietary nature of these technologies.

One other thing that I think you touched on briefly but I wanted to call out: standards aren't just about portability. I'm tired of learning 50 different APIs, frameworks, etc. that do the same thing, only because the ecosystem is so splintered/fractured.

Exactly. Transaction management is the perfect example. How many different flavors of Transaction do we have in enterprise Java? All with the same 3 methods. It's a disgrace. It makes life much more difficult for framework developers and even for ordinary users. And that's just the tip of the iceberg. Another good example is JPA persistence context management.

So many folks are burying their heads in the sand on this issue, thinking it doesn't matter as long as they know which flavor they, personally are using. What they don't realize is that it holds back development of higher level technologies and frameworks. That's the purpose of having an ecosystem, instead of just a single-vendor platform.

You simply can't write code that works using only the annotations in javax.inject. You also need a bunch of additional metadata, either in Guice java-based configuration, Spring XML, or CDI annotations.

...and a few months away I guess, proprietary Seam 3 annotations.

Application portability between containers... who cares, really? If I have to bundle x.jar in my war, or if it's included in the container is not what is important. What is important is that the programming model between releases, even major, is stable. And this is where Spring, and not JEE, has been successful. It's been really easy to go from Spring 1.2 - 2.5 - 3.0 during the past 5 years or so. You have been able to pick and choose new techniques along the way really easy too, if you wanted to.

You simply can't write code that works using only the annotations in javax.inject. You also need a bunch of additional metadata, either in Guice java-based configuration, Spring XML, or CDI annotations.

...and a few months away I guess, proprietary Seam 3 annotations.

So it seems to me that there is a massive difference here:

Seam3 will be a package of portable extensions that run on any implementation of JSR-299 (including Weld, Apache Open Web Beans and CanDI),

created by folks who have a proven track record of taking their most successful ideas and bringing them back into the standards via the JCP.

Spring XML, on the other hand, only works with Spring, and the Spring folks have a proven record of indifference (and sometimes outright hostility) toward standards. You can see this clearly with 299 vs 330. One spec gives you portability, one doesn't.

Look, trying to paint my team as using Seam to force you into a vendor lock-in scenario is just laughable. We're the guys who have spent countless hours working on the design of EJB 3, JPA, CDI, Bean Validation and JSF 2, and a huge amount of emotional energy helping navigate those specs through the treacherous waters of JCP politics. Everything we have worked on for the past 6 years has been used to improve the EE standards.

And, of course, if you're really worried, nobody is forcing you to use Seam. You don't need its portable extensions to do basic stuff. CDI is a complete solution for injection, interception, eventing and lifecycle management. With 330, you need to use proprietary APIs just to define a bean.

So, frankly, you're way off base here.

Application portability between containers... who cares, really?

Lots and lots of people. Don't project your desires onto others.

What is important is that the programming model between releases, even major, is stable. And this is where Spring, and not JEE, has been successful. It's been really easy to go from Spring 1.2 - 2.5 - 3.0 during the past 5 years or so.

By my count, Java EE has been through one major redesign, when EJB3 and JPA were introduced in Java EE 5. Java EE 6 doesn't redesign or repudiate any of the programming model that was introduced in EE 5, because the stuff in EE 5 was done right. And I don't imagine that EE 7 will need to redesign or repudiate anything in EE 6, which has also been done right.

Yes, since the changes in EE 5 were major changes, you're correct to say that Spring has changed less in 5 years. But that's not a good thing. Spring looks five years old. The fact that Spring has not had a proper ground-up redesign for 5 years is why it now looks so outmoded.

Spring does, truly, embody many of the best practices of 2004. Meanwhile, Java EE has moved on.