If there's one thing that we really want to get right as Web Beans goes from Public Draft to Proposed Final draft, it's integration with the Java EE platform. Up to this point, most of the work we've been doing as an EG was focused on nailing down the programming model, the semantics of the Web Beans services, and the behavior of the Web Bean manager. We've been writing the spec to assume that Web Beans implementations should be pluggable between different Java EE containers, because this is a direction that a lot of folks in the Java EE community believe that the EE platform should move in, and because we would like Web Beans to help show the way for other specifications such as EJB, JTA and perhaps even Servlets (note that JPA and JSF already support this).
Since the release of the Public Draft, our main focus has shifted to the integration problem. Web Beans generated a bunch of controversy when the draft was circulated to the EE platform expert group and proposed by Sun for inclusion in the Web Profile. That's not surprising - Web Beans solves some very important problems that lots of people have strong opinions on. I've also had a number of more technical discussions with the EE and EJB spec leads and with the EJB expert group. A number of concerns have emerged, which we're now attempting to address.
Let me share my take on these issues, and some directions we might pursue. But first...
In the days of EJB 1.x and 2.x, a major complaint against EJB was that the programming model was too restrictive. The specification imposed many annoying, distracting and unnecessary requirements upon developers. EJB 3.0 changed all that. Gone were the most of these annoying coding restrictions. In place of verbose XML deployment descriptors, EJB 3.0 was the first Java component model to be based around the use of annotations. In place of JNDI lookups was a simple dependency injection model, which ended up being generalized at the EE 5 platform level. I was a member of the EJB 3.0 expert group, and remain proud of what we accomplished.
However, the Java EE 5 dependency injection model was criticized from the outset. Many folks, including Rod Johnson of SpringSource, argued that the lack of support for injection of Java classes which were not EJBs was a fatal flaw. (At the time I did not agree, but I've changed my mind since.) On the other hand, I was dissatisfied with the lack of a contextual lifecycle model - though, in fairness, some other DI solutions of the time, including Spring, also lacked a contextual model. I was also unhappy with the mismatch between the JSF (XML-based, contextual) dependency injection model and the platform-level (annotation-based, non-contextual) model. This mismatch made it difficult to integrate EJB components with JSF.
Most of the changes introduced in EJB 3.0 and JPA 1.0 have stood the test of time remarkably well. The EE 5 dependency injection model has not. Contextual lifecycle management is now a standard feature of dependency injection solutions including Seam, Spring and Guice. Most importantly, Guice showed us the folly of using string-based names to identify implementations of an API. And Seam showed how to simplify application development by unifying dependency management in the web and EJB tiers.
Web Beans was initiated to address these problems. The original JSR proposal complained that:
EJB components are not aware of the web-tier request, session and application contexts and do not have access to state associated with those contexts. Nor may the lifecycle of a stateful EJB component be scoped to a web-tier context.
The JSF component model is not consistent with Java EE ... dependency injection...
The JSR promised to
unif[y] the two component models and enabl[e] a considerable simplification to the programming model.
A new dependency injection model was needed: a model that provided contextual lifecycle management to transactional EE components.
In the Web Beans Early Draft, we characterized Web Beans as a component model. The specification defined two things:
- a set of restrictions that a Java class or EJB session bean must satisfy in order to be a Web Bean (principally, but not only, that it must explicitly specify @Component or another deployment type), and
- the services that would then be available to the Web Bean.
I viewed this as a unifying component model: a unification that would solve a major problem that has existed since J2EE - that the Java EE web tier has a completely different component model (actually, component models plural) to the transactional tier. It promised to
tear down the wall between the two tiers, allowing transactional components to be aware of state related to the Web request. It promised a truly uniform programming model for components concerned with orchestration of the Web request, and components concerned with managing data access (at least when JSF was used).
This turned out to be the wrong approach. The strong feedback from the EE group was that Web Beans shouldn't define a new component model. The feedback from the EE spec leads at Sun was that the services defined by Web Beans should be available to all kinds of Java EE components - not just those which satisfied our definition of a
At Sun's urging, we made two changes to the specification. The first was primarily a language change. We repositioned Web Beans as a set of services, provided by a Manager analogous to the JTA TransactionManager, instead of a
component model with a Container. But this also implied two more technical changes:
- we dramatically loosened the restrictions on what objects are Web Beans, so that every EJB session bean and every JavaBean is now a Web Bean, without any requirement for explicit declaration, and
- we provided a set of SPIs to allow objects which are not JavaBeans or EJB session beans to take advantage of the services provided by the Web Bean manager.
In particular, we provided injection into Servlets and message-driven beans (objects which by nature are not injectable) and an SPI that allowed other EE technologies and thirdparty frameworks to offer their components up for injection by Web Beans, and take advantage of the Web Beans services.
This was certainly the right thing to do, and the Web Beans specification is now more powerful and less intrusive. It still promises a more uniform programming model, but a side effect of these changes was that the model became even more generally useful, and even less specific to JSF and EJB. This isn't the first time I've seen something like that happen: the EJB 3.0 expert group also produced some technology (JPA, EE 5 dependency injection) that ended up being applied more generally than was originally envisaged.
Unfortunately, some people are still not satisfied. A number of members of the platform expert group believe that the notion of a simple Web Bean still specifies a new component model. So what, exactly, is a simple Web Bean, and why do we need them?
A simple Web Bean is nothing new. It's just a Java class. You've already written hundreds or even thousands of simple Web Beans. Every JavaBean is a simple Web Bean. All we're trying to do is allow objects which were not specifically written as EJBs to be injectable and take advantage of the Web Beans services.
A simple Web Bean has the following
advantages over an EJB session bean:
- it does not need to be explicitly declared as an EJB using a component-defining annotation or XML
- its interfaces do not need to be explicitly declared using @Local or @LocalBean
- it can be final, or have final methods
- it has a more
natural lifecycle and concurrency model - the normal lifecycle for a Java class, instead of the
enhanced lifecycle/concurrency semantics defined by EJB
- if it's a stateful object, it does not require a @Remove method
- it can take advantage of constructor injection
You can use preexisting JavaBeans and many other Java classes as simple Web Beans. As a side effect, simple Web Beans reduce the mental
gap for new Java EE users who might be, initially, scared off by the unfamiliar EJB semantics - and the rather painful requirements to explicitly designate business interfaces and add empty @Remove methods - and let these new users get started with container-managed objects more easily.
On the other hand, unlike session beans, simple Web Beans, as currently defined:
- don't have method-level transaction demarcation or security
- can't have timeouts or asynchronous methods
- can't have remote interfaces or be web service endpoints
- don't have container-managed concurrency (locks)
- don't support instance-level passivation or pooling
Therefore, in my opinion (an opinion shared the current and previous EJB spec leads), simple Web Beans don't compete with EJB as a solution for the transactional tier of the application. In fact, simple Web Beans aren't really anything new - Java EE developers already use EJBs and JavaBeans side by side. Web Beans just makes their life a little easier.
But some folks disagree. For example, one expert is worried that by providing something called a
simple Web Bean, we're encouraging people to use them instead of EJB. The risk is that developers will be guided away from the use of
non-simple EJBs. This has become a real sticking point in the EE group, and threatens to derail the whole Web Beans effort.
Of course, we're trying to work through this. One possibility is that we could move the definition of a simple Web Bean to the EJB specification, as a new EJB component type. Another possibility is to simply drop simple Web Beans from the specification, and ask everyone to write all their objects as EJBs.
Personally, I can't imagine releasing Java EE 6 with a dependency injection solution that doesn't support JavaBeans. All the other solutions in the space support both JavaBeans and EJB. EE 5 missed this boat - I don't want EE 6 to repeat the mistake. And I think that this is a case where users want to make the decision about when to use EJB. They don't want us to force a decision down their throats.
A second issue raised by the EE experts is that the Web Beans specification does not currently define support for injection of all the various Java EE resource types. Specifically, Web Beans does not explicitly define injection of JDBC datasources, connections, web service endpoints, remote EJBs or persistence contexts. Of course, you can still use the existing Java EE 5 @Resource and @PersistenceContext annotations to inject Java EE resources, but then you'll miss out on the advantages of the more flexible and more typesafe model defined by Web Beans.
Well, the true situation is that injection of EE resources (or anything else at all) is already supported by Web Beans, assuming that the Java EE container calls an appropriate Web Beans SPI at initialization time. But neither the EE specification nor the Web Beans specification requires it to do so. So this is an issue that should be easy to fix.
We put a fair amount of effort into defining the interaction between the EE container and the Web Bean manager, for the purpose of supporting pluggable Web Bean managers. However, nothing that is currently defined imposes any new requirement upon the EE container. Unfortunately, at this point, there remain a number of open issues in the specification that can only be resolved by either:
- dropping the requirement for pluggability or
- imposing new requirements upon the EE container.
Open issue in the Public Draft if you're interested in knowing exactly what new requirements would be imposed upon the Java EE container.)
Either of these paths is technically feasible, but one of them is a lot more work and involves a lot more coordination between the various expert groups, some of which are already struggling to meet tight deadlines. If Web Beans is required in Java EE 6, it's not clear that pluggability is truly of great value to users. Does anyone really need to switch out their Web Bean manager?
I'd love to hear from the community whether pluggability is really worth pursuing.
Quite a number of people hate the name
Web Beans, which they see as obscuring the generality of the model we've defined. I view the name as more of a catchy brand than a definition of what Web Beans does. Think of Microsoft and
.net. I don't mind changing the name, but nobody has yet suggested a great alternative. For one thing, I hate acronyms, and something descriptive like Java Dependency Injection wouldn't really capture all that Web Beans does.
Independently of this objection, quite a number of people think that it would be better to package our annotations by concern rather than putting them all in the package javax.webbeans. For example, the following package layout might make better sense:
- javax.dependency - DI-related annotations: binding types, deployment types, @Initializer, @Produces, etc.
- javax.contexts - scope-related annotations, Context interface
- javax.interceptor (which already exists) - interceptor and decorator related annotations
- javax.events - @Observes, event bus interfaces
I see repackaging as a great idea.
The good news is that there's very little debate about the actual technical details of the (Guice and Seam inspired) dependency injection model in Web Beans. The feedback I'm getting from spec reviewers is uniformly positive. This gives me a lot of confidence that the more
political issues are also solvable.
The issues I've discussed in this post are important to all members of the Java EE community and to the future direction of the Java EE platform. I don't believe that we should be making these decisions
behind closed doors, without the involvement of users. Please speak up and let us know what you want us to do. And please take the time to learn more about Web Beans.