Java EE is a great framework and set of services for developing business applications. For framework developers though, Java EE can be very rigid and frustrating sometimes. I think that there are a bunch of things both simple and complex that we could do to really open up Java EE and get the open source framework community energized. This would make Java EE not just a framework for applications, but a framework for frameworks. If we can accomplish this, the Java EE specification can become a living, breathing document instead of a quickly outdateable piece of paper.
A real metamodel
The EJB metadata you can obtain at runtime through the SessionContext interface is incomplete. For example, you can't even get the EJB Name of the bean that's being invoked on. I don't know if you have ever looked at the Seam framework, but one of the things it allows you to do is use EJBs as a controller in an MVC environment and integrate them with page flows. One of the funniest things about this integration is that Seam requires you to annotate your EJBs with @Name because the EJB specification provides no way of obtaining the EJB Name of the bean. We need a real metamodel in all specifications that allows each component type access to an object model that represents its deployment descriptors, both standard and vendor specific. The standard metamodel needs vendor identifiers so that a thirdparty framework can trigger vendor specific code so that it can integrate cleanly where possible. You'll see later on in this blog, that if we have an object representation of a deployment descriptor, there's a lot of othe cool things we can do. For instance...
Expand JSR 88The JSR 88 specification was introduced to make it easier for IDEs to build Java EE components and deploy them portably. The problem with this specification is that the API is centered around files, input streams, and raw XML deployment descriptor fragments. This specification should be expanded to support deploying a metamodel such as what I described earlier in this blog. Why is this needed? Consider an ESB. An ESB glues together inbound connections, outbound connections, and message flow in a coherent view so that the application developer can do everything in one place. JCA inflow and MDBs are a perfect match for an ESB. The problem is that it is difficult to use JCA+MDB and continue to have a coherent, integrated view as you would have to package and deploy a specific, separate, MDB deployment instead of just embedding the MDB's definition right in the ESB's deployment description. Another example is that a web services framework might want to take advantage of the server's servlet container to deploy its own endpoints. An agent framework might want to use this new deployment API to deploy EJB agents at runtime as the agent bus receives requests from the network.
This expansion of the deployment API would create a plethora of innovation around deploying Java EE components. Framework developers, between releases of the official Java EE specifications, could have a free-for-all on refactoring various Java EE deployment descriptors. The best one could be incorporated into the next version of the specification. We could get a nice cycle of innovation and standardization.
Boottime ListenersThe ServletContextListener is an extremely useful component in the development of WARs. Spring users use this feature a lot to bootstrap their spring contexts. The question is, why don't other components have this feature? Shouldn't an EJB deployment be able to populate the 2nd level cache of a JPA persistence unit?
Separate metadata parsing from processingWhat would even be more cool, is to be able to integrate these boottime listeners into deployment. These listeners could be inserted in between the parsing of deployment descriptors and the processing of them. These listeners could receive the metamodel(see previous discussion) of a WAR before the application server deploys this metamodel and initializes its servlets. The listener could then augment and/or override the metamodel before the application server deployed a particular component.
Why is this useful? Again, back to the Seam framework. Seam has a bunch of annotations that can be applied to an EJB. To use the annotations, the application developer needs to add a specific Seam interceptor to be able to take advantage of the functionality tied to these annotations. Seam also requires you to add certain filter and taglib definitions to your web.xml file in order to take advantage various Seam features. Wouldn't it be cool if a Seam listener could intercept deployment and automatically augment the metamodel of your wars and ejbs so that you didn't have to define this metadata yourself? A Seam listener could scan the EJB class for Seam annotations, and if they exist, augment the EJB's metamodel to include the Seam interceptor. Same could be done with a WAR deployment. This would allow frameworks like Seam, that are built on top of Java EE, to more seamlessly integrate with Java EE implementations in a portable, vendor-independent, way.
Open up JCADeployment isn't the only thing we could open up in Java EE 6. There are some simple changes we can make to other specifications to make them more more. JCA is a very nice clean contract for defining inbound and outbound connections. It has some rigidity, though, that I'd like to open up in the next version of the spec. For instance, the JBoss EJB 3.0 implementation has a Message POJO extension. This abstraction allows you to interact through JMS through a user defined business interface. I thought about refactoring this extension as a JCA adapter so that these features could be usable and portable to any application server. The problem is that one minor JCA caveat got in the way. The adapter is required to specify the interfaces it supports, instead of allowing the MDB to specify what the interface is at activation. Many application servers use the MDB's interface to match it up to the appropriate resource adapter. If we could relax this restriction, frameworks like JBoss's Message POJOs could be written portably.
Another cool thing about JCA message inflow is that you don't have to have an MDB to take advantage of it. The JCA specification is EJB ignorant and has a clean API for publishing an activation. The problem is, there is no portable way to get access to a Resource Manager so that you can trigger an activation! Yes, JCA implementations like Jencks and JBoss's give you programmatic access to Resource Managers, but then you are locked into our implementations then, aren't you? This is another feature that would be more useful if we had the boottime listeners I talked about ealier.
Further componentize Java EEThe JMS specification can be implemented and distributed by any one vendor. This vendor is not required to implement the entire Java EE specification. The same goes with Java Persistence, and even the servlet spec. Let's expand this in Java EE 6 and provide SPIs so that individual vendors can solely implement and distribute specs like JCA and EJB.
To live beyond Java EE 5, I believe the specification needs to change to make it easier for framework developers to innovate within as well as around Java EE. If Java EE can move beyond just a framework for applications and turn into a framework of frameworks, we can keep Java EE alive and non-outdated between spec releases. By opening up Java EE, we can foster more innovation, and give the JCP more material to consider in future specification efforts.