My foray into blog land 2 weeks ago has been thwarted. The "Angry Bill" blog I created on blogspot has been blocked. So, I moved to wordpress. To find out why I was banned and see my new site, click here.
How can you slowly migrate existing Hibernate apps to JPA? How can you use Hibernate features and unique mapping capabilities with a JPA deployment? How can you take advantage of EJB3 injection and persistence context management with Hibernate? Click here for more...
In the spirit of the old Embeddable EJB3 project comes Embedded JBoss. Embedded JBoss allows users to run the JBoss 5 Kernel and any JBoss project or component within non-application server environments, or rather within a non-JBoss-controlled classloader. The focus of this Beta 2 Release of Embedded JBoss was to create some deep integration into Tomcat as well as streamline the process of running embedded within JUnit tests.
Goals of the project
Ability to run JBoss within plain Java application
To run embedded within JUnit tests
To be usable within standalone Tomcat
To be usable within application servers
To run streamlined and stripped down with a fast boot speed (JNDI, JBoss TS, connection pooling, JMS, EJB boot up in < 6.5 seconds on a 2.4 Core 2 system)
Why is this important?
Allows JBoss and JEMS products to be more lightweight
Allows people to use JBoss/JEMS that can't switch containers that easily
Unifies what other projects at JBoss are already doing to be able to run in non-JBoss-application-server environments
Gives ISVs better integration possibilities
How is this possible?
There are a couple of cool features in the new JBoss 5 Kernel that enpowered us to build Embedded JBoss. The first is that classloading is now an aspect of the JBoss 5 kernel. Classloading behavior, although flexible, was hardcoded in older versions of the JBoss Kernel. In JBoss 5, classloading behavior can be plugged in. What we did for Embedded JBoss was to pull out the default Unified ClassLoader behavior, and just use the Thread's context classloader for deploying and running components.
The 2nd cool feature of the JBoss 5 Kernel is the new file abstraction we have called the Virtual File System (VFS). The VFS is an archive abstraction that hides from the deployment services whether the archive is an exploded directory, jar file, or regular text file. One of the features of the VFS is that it allows you to create virtual archives in memory based on classpath resources or even raw bytes. This is incredibly useful in unit testing within IDEs or when you want to ship applications that are not broken up into individual Java EE packages.
We still have a lot of fine tuning to do on the user experience and really need some advice specifically on how you want to use Embedded JBoss with unit testing and how we can make the process of going from unit testing to production deployment easier on developers. Please see our Wiki page for more information on where our forums are and such.
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 88
The 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.
The 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 processing
What 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 JCA
Deployment 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 EE
The 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.
I few minor changes since RC7 came out. The @EJB annotation was in the wrong package. It was in javax.annotation, it should be in javax.ejb. Also, the InvocationContext.getBean() method should be InvocationContext.getTarget(). That's all the changes.