October 10, 2005
JavaEE 5 injection issues
I've been studying the public drafts of the JavaEE 5 injection. I now think that the injection part of the new spec has some big limitations which will hamper its adoption. The spec only looked at IoC as a way of eliminating a few lines of code that looked up dependancies in JNDI. They never looked at using injection as a generic Java application wiring framework which was the whole reason this pattern became popular. By severely constraining it in this manner I think quite a few customers will find it a very poor replacement for their current IoC frameworks and I think it may actually be inappropriate for many server applications as a result.
Problem #1: Assumes a heavy environment, i.e. an application server
It assumes it's in an application server, a JavaEE 5 server. There are no APIs like Springs XmlBeanFactory that let the application programmatically look up a IoC configured/instanciated Pojo. So, it's not ideal for backporting in to a standalone library that customers on older versions of application servers (or even didn't have an application server) could also use it.
Problem #2: It's not about POJOs, it's about JavaEE 5 components
You can only add injection annotations to a JavaEE 5 component (i.e. a servlet or EJB), you can't use it with normal Java Objects. I guess some people will say but JavaEE 5 components are now just POJOs, right? Not really. Suppose the POJO I want to make is abstract and constructed with a static factory method? How do I wire this in? Thats right, it's the wrong kind of POJO, the spec only works with SPEC POJOs, i.e. JavaEE 5 components. No third party libraries use this specific type of POJO. They use real ones, normal plain old Java objects (POJO).
Problem #3: It's closed, limited wiring opportunities.
- You can only inject JavaEE 5 artifacts in to JavaEE 4 components.
- You can't inject arbitrary POJOs and wire them to POJOs.
- You can't wire a reference to an IoC configured Java object to another Java object.
- You can't construct Java objects using factory methods etc.
- You can't construct a list of IoC beans and then inject the list to a POJO.
It's only about JavaEE 5 components and wiring them and JavaEE 5 resources like ejb-refs, connection factories, very simple attributes and data sources together. So basically, you can't configure and wire in your favorite rules engine/cache/third party library with any of the spec injection stuff because those libraries are POJO based and not JavaEE 5 component based. You'll still need a 3rd party IoC framework and the question then is why do I need two? Lose the one with the problems...
Customers use third party components with their applications. More and more Java components are being written to run on as many J2SE and J2EE environments as vendors can manage. Nobody wants to make components that only work with the latest spec. You can't wire ANY of these to a J2EE application with the injection in the JavaEE 5 spec. You can only wire J2EE artifacts like DataSources and other EJBs. This is absolutely not the case with mature IoC frameworks such as Spring/PicoContainer/JBoss's microcontainer. Now, of course, we could make a JCA resource adapter for these. We could then wire them to the EJBs but hang on, I don't want to go through that pain. This was supposed to be lightweight, no? Why can't I use the jars I was using before unchanged? I can with the mature IoC frameworks...
It's a shame that this is the case for the many customers already using IoC containers. They may have thought that the new JavaEE 5 application servers meant that they get all this builtin with the new spec. They do not. They will still need a 'proper' IoC container to construct those applications. I don't see EJB (or sorry, JavaEE 5 components, man thats a mouth full!) usage rising as a result. I expect customers to stick with a true POJO model using a mature IoC container using persistent managers. So, we'll still see applications written using servlets + IoC POJOs + POJO persistence mapper, i.e. pretty much what people do today.
So, my prediction is that the JavaEE 5 component injection stuff will not be heavily used in applications as it's just not capable or flexible enough to replace existing IoC function in widespread use right now. Given many people are using the mature IoC frameworks in their pre JavaEE 5 applications, I see little reason in them porting those applications to use the JavaEE 5 injection framework as they are just going to be frustrated when they discover it's many limitations and besides who wants two frameworks! They may as well stick with what they have, it's better and is probably based on or is a defacto mature standard anyway.
So, while the JavaEE 5 changes make writing EJBs/components better, I think that because it is artificially limited to EJB/component only applications, it has also limited the adoption of the technology and missed the whole point as to why IoC containers became popular. These containers need to be just about Java objects and must not constrain or limit the flexibility of the developer using them at all. Constraining the JavaEE 5 injection to just JavaEE components and JavaEE resources will severely limit their adoption. Thus the role of official standards becomes undermined with defacto standards being the important ones because they work.
Now, if all you do is EJBs/JavaEE components, DataSources and maybe a Connection factory then it does fulfill a simpler model for exactly that kind of application. And you can argue it's a great job in that role. The trouble is thats only one aspect of why IoC framework became popular. The fact thats it's a closed system will stifle its usage and it's role will be secondary to a real IoC framework if its used at all as a result. If you're writing the more normal applications using third party libraries etc, lower your expections when you finally upgrade to JavaEE 5.
The lesson here is that J2EE needs to start evolving in a similar manner to how the market place is developing these technologies. Standalone pieces that are loosely coupled together. IoC and POJO persistence didn't evolve together, they evolved along side each other, theres an important difference there. They both play together well because they are loosely coupled and both can be used independantly of each other. This kind of goes back to my blog on invasive middleware and unfortunately J2EE is a pretty good example of invasive middleware where as the open source projects are ultimate examples of the opposite. The challenge here to the J2EE community is not to copy whats working from an API pattern from the market, it's to copy how the market is working.
October 10, 2005 | Permalink Sphere
TrackBack URL for this entry:
Listed below are links to weblogs that reference JavaEE 5 injection issues:
Great post, thanks! I didn't realize the JEE5 injection stuff was so limited. At least you saved me from wasting time on it...
Back to my Spring POJOs.
Posted by: Jason Carreira | Oct 12, 2005 12:59:40 PM
Yes, a good eye-opener for me too.
Posted by: Mats Henricson | Oct 13, 2005 4:56:20 AM
This posting is quite a bite off. EJB3 actually does allow you to inject arbitrary objects into EJB3 components. In fact, I'm willing to bet I could write a spring integration component in 100 or so lines of code or so that would let you inject any spring component into EJB3s. I'll try and post on this myself, if you really don't know how to accomplish it. (feel free to email me) Likewise, Spring could easily be extended to inject EJB3 components. I'd be quite surprised if that doesn't exist already.
Also, if you are curious, EJB3 doesn't require a "heavy environment", unless, of course, your definition of "heavy" is "anything that has anything to do with EJB in any way shape or form". Take a look out our (JBoss) embeddable EJB3 container as one example.
Posted by: Norman Richards | Oct 13, 2005 8:30:38 AM
I'd like to see it. I'm looking at the spec and 15.4 says attribute injection is limited to simple types. No lists/connections and no arbitrary objects. An EJB is not an arbitrary object given the injection framework assumes it always manages construction of the object and can't be made to delegate construction to another part like a factory.
EJB injection always assumes an interface. It doesn't appear that you can inject an Object rather than an interface even for an EJB.
The only injections allowed are simple attributes (15.4), EJB references (15.5) and web services, transactions, resource refs.
Where is the injection for arbitrary POJOs or lists of them etc?
Now, I believe that you've got proprietary extensions in your JBoss stuff to do this, but it isn't in the spec and hence isn't standard which was kind of the point of the post. Opportunity missed.
Posted by: Billy | Oct 13, 2005 9:55:05 AM
I blogged about EJB3/Spring integration a while back: http://chris-richardson.blog-city.com/the_ejb_cult_part_3__integrating_spring_and_ejb_30_dependency_injection.htm
Its certainly possible to inject POJOs but I think its far more dificult than it should be. e.g. some kind of API that lets you plug in Spring more directly would be nice.
Posted by: Chris Richardson | Oct 13, 2005 11:17:46 AM
"Its certainly possible to inject POJOs"
Eh? Your blog says exactly the opposite:
"EJB 3.0 dependency injection has two big limitations. First, it can only inject dependencies into session and message-driven beans - not arbitrary POJOs"
Billy, your observations are spot on. But Rod Johnson and others raised these exact concerns one year ago:
I didn't realize this was coming as news to the general community. There are going to be some disappointed users...
Posted by: Corby Page | Oct 13, 2005 1:33:34 PM
I agree but I think JBOSS-SEAM will solve most of the problem you are pointing...
I would bet on thet fact that SEAM (or it's futur name) will become for JEE5 what struts is for J2EE: necessary...then integrated into JEE6...
SEAM used with EJB3 and JSF's propose a real and complete programing model...and introduce the concept of "dependency bijection"...
So I'm really happy all that JEE5 stuff and addons are at last implemented...and the imperfections will be corrected by comunity and integrated into JEE6...
Good job Community and SUN fot his great JEE5!!
Posted by: Stephane DUCAS | Mar 13, 2006 12:41:30 PM
Hello, I like to know if I can develop the ejb3 with websphere.
Posted by: sallami | Jun 23, 2006 7:40:11 AM
Oh, where to begin....
"a way of eliminating a few lines of code that looked up dependancies in JNDI"
Since JNDI is the central store for distributed applications, this makes perfect sense. You inject from some local repository (spring config) then your system state will not be maintained in a distributed environment.
"So, it's not ideal for backporting in to a standalone library that customers on older versions of application servers (or even didn't have an application server) could also use it"
It's called J_EE_ for a reason, I you want to write libraries, go write them, but JEE is about JEE components.
"You can only add injection annotations to a JavaEE 5 component (i.e. a servlet or EJB)"
Quite true, only first class objects can participate in injection...so yes, only servlets, and ejbs...and filters...and listeners...and jsf managed beans...and intercepters...and message driven beans...and timed beans...and stateless session beans...and stateful session beans...and ejb 3 listeners...etc.etc.etc. Often engineers throw up their hands and go to something like spring without being aware of the full range of core spec technology. If you need something beyond the core spec for an EE app, then I'd probably tell you to go read the spec a bit more.
"t's closed, limited wiring opportunities"
That seems to be the same as the previous point, so I won't go ther e again.
"You can't wire ANY of these to a J2EE application with the injection in the JavaEE 5 spec"
Go back, read the part of the spec on 2.1/3.0 interroperability
"The lesson here is that J2EE needs to start evolving in a similar manner to how the market place is developing these technologies"
The JCP is made up _of_ the market place (yes, even interface21 is there). JEE5 is a bunch more than just injection -- and the fact that injection works primarily with first class types is, in my view, a good thing. It will force developers to learn the specification before throwing up their hands and saying "this is boring, lets go use this cool new IoC container".
EE programming is about $$. Time to market and maintainability. If you're writing banking and insurance software and arguing the architectural beauty of pojo IoC vs spec Ioc then you're kind of missing the point. JEE5 was never about replacing things like spring, it was about making enteprise programming (real enterprise programming, not some little servlet app) easier, and it's done that to a spectacular degree. IoC is a great concept, where it can be used to advantage...but it's not EE programming...spring is only barely starting to catch up to EE with the more advanced needs of large enterprise like integrated security, sso, distribution and scalability, xa, etc etc
In the last 12 months I have architected and coded on 2 spring projects and 1 EE5 project. Cost of delivery and maintainance is significantly lower with EE5 and you get all the enterprise concepts I discussed above thrown in for free. Along with that, you get webservice annotations, security annotations, webstart client delivery...I could go on and on and on.
Anyone reading this post and giving up on JEE5 (and staying with something like spring)...I would say go download netbeans, knock up a quick little multi tier hello world (make sure it's got stateless session beans and message driven beans, jsf and a webservice to ensure you're across the whole spec) and judge for yourself. It think you'll be pleasantly suprised.
SCJP(5.0), SCWCD, SCBCD(EE5), SCEA
Posted by: Adam | May 20, 2007 3:42:57 PM