Alex Miller lives in St. Louis. He writes code for a living and currently work for Terracotta Tech on the Terracotta open-source Java clustering product. Prior to Terracotta he worked at BEA Systems and was Chief Architect at MetaMatrix. His main language for the last decade has been Java, although Alex have been paid to program in several languages over the years (C++, Python, Pascal, etc). Alex has posted 43 posts at DZone. You can read more from them at their website. View Full User Profile

Bob Lee on dependency injection frameworks and collections

01.29.2008
| 6983 views |
  • submit to reddit

There is a JavaPosse interview with "Crazy" Bob Lee from JavaPolis that went up recently that is very interesting [audio, video]. The first big chunk of the interview is about Guice and that's good stuff, but not what caught my ear. At about the 21:00 mark (or section 9 in the video), they start talking about a standard framework for injection annotations that could be used with a number of injection-based frameworks like Guice, EJB, JPA, Spring, etc.

Apparently Bob has been kicking around the idea of proposing such a thing as a JSR for inclusion into Java SE and Java EE. I think this would be a fantastic addition to the Java platform. Now that we've moved (you have moved, haven't you?) out of the old school EJB container model and into a new world of lighter-weight annotation-based frameworks, I think we are finding (as a community) the sweet spot for annotations and dependency injection.

In this way, you could have your Spring bean and eat your EJB too, if you get my drift. It would almost be sort of a new standard for lightweight composition. I can certainly envision ways I would want to leverage this myself. Certainly I could imagine using annotations to indicate Terracotta clustering behavior on a Spring bean or an EJB. You can do that now, but I imagine it could be even more seamless (and maybe use some common annotation infrastructure) if it was part of the platform.

Unrelated to the topic of injection, Bob also talks about some of the pieces he supplied for the Google Collections API, which was pretty interesting. Bob created a ReferenceMap that lets you choose whether to use strong, weak, or soft references on either key or value and uses == for Weak and Soft keys instead of equals() like WeakHashMap. He gives a good overview of the differences between strong, weak, and soft references and mentions that Doug Lea is working on a new kind of map reference for Java 7 that would allow the value to have a strong reference back to the key but not prevent the whole key/value entry from being GC'ed.

He also talks a bit about where the ReferenceMap came from, which was a thing called ReferenceCache which is a cache that knows how to create an item if it's absent. He refers to it as "supplyIfAbsent" in comparison to "putIfAbsent" in ConcurrentMap. Your options for doing this in existing Maps are to either check for existence (while holding a lock), then create and put the object if missing OR to preemptively create the object and call putIfAbsent() on ConcurrentHashMap. In the former, you are introducing a lock while creating the object and in the latter you have to pay the object creation cost regardless of whether you need it. So, having a Map implementation that could take a factory would be a nice side-step as it could avoid locking until it's known whether the object creation is needed, then invoke the factory while causing other callers to block and wait. You can imagine an even better implementation if we had closures - just pass the block to create the object if needed rather than using a factory - just invoke if necessary.

Published at DZone with permission of its author, Alex Miller.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Geert Bevin replied on Tue, 2008/01/29 - 2:20pm

Actually, in this case I wouldn't use closure but find interfaces much clearer to specify the API for factories. Using closures can really generate too much side-effects if they refer to local variables in the outer scope and are kept for a longer time. Hmm, actually if they're simply used for one supplyIfAbsent call, then it could be ok, but it seems weird to me. I'm more inclined to think into a Supplier that is registered for a map instance and that automatically faults in (supplied) when an entry is absent.

Alex Miller replied on Tue, 2008/01/29 - 3:44pm

@gbevin, my impression is that this is basically what Bob did in ReferenceCache.  I've run into scenarios where there isn't just one strategy for constructing the instances in the map and/or it is unknown at map creation time.  In that case, you want to say I need this value, but if you don't have it, run this chunk of code to get it.

Rick Hightower replied on Wed, 2008/01/30 - 2:01am

At about the 21:00 mark (or section 9 in the video), they start talking about a standard framework for injection annotations that could be used with a number of injection-based frameworks like Guice, EJB, JPA, Spring, etc.

I think it would be great to have a standard, powerful dependency injection framework that ships with Java. The IoC  framework should have the power of Spring 2.5/Guice style injection.

Why not add a standard AOP lib/framework as well?

rick hightowercto of arcMindbloglinkedin

Jakob Jenkov replied on Wed, 2008/01/30 - 5:11am

A powerful DI container shipping with Java would be nice, but not at all costs. Too much substandard stuff has already crept into Java. What I am saying is that the same problem can be solved in many different ways. The most "popular" solution is not always the most elegant. For instance, there is a subtle though important difference in the ways that Spring and Guice uses annotations. Guice requires the annoations directly in the components to wire up, whereas Spring uses annotations above some configuration classes instead. These configuration classes are external from the components to wire up. Thus, Spring's use of annotations is a lot less intrusive than Guice's, and in my eyes more elegant.

Still, both annotation approaches requires reflection at instantiation time unless I'm mistaken.

I too have developed a DI container, Butterfly Container, which has a different approach to DI configuration. Butterfly Container supports ordinary adding plain Java factories to the container, meaning they require no reflection when called. Butterfly Container also supports a much less verbose configuration mechanism -  a DI specific configuration language. This language is currently parsed at runtime and turned into factories and put into the container, so these factories require reflection to work. But in the future this script language will be used to generate Java code at build time. The resulting factories will again be pure Java factories requiring no reflection when called.

The point is not to say that Butterfly's approach is smarter than Spring or Guice's. The point is, that it is different. I did take a close look at both Spring, Pico and Guice before designing Butterfly. Still I chose a different approach. If the community is to add a DI framework to Java, it shouldn't just adapt the most popular approach uncritically. I mean, did the JavaDB guys actually look at HSQLDB or H2? Or was Derby just chosen because it came from Apache? Personally I still use H2 even if Java ships with JavaDB. I just don't feel they chose the "right solution". Just like EJB turned out not to be the right solution either. The situation was the same. Remote objects were all the fuss back then. Only now people learned that they aren't all they were promised to be. 

 

Frederic Simon replied on Thu, 2008/01/31 - 1:05am

For the JSR of DI part of the platform I’m confused. He is working on JSR-299 (WebBeans) with Gavin King, and it’s exactly that.
So, he did not mention WebBeans put he described it when he talk about all the new cool stuff he wants in Guice!
What’s going on?

For having DI at ground level (the JDK), I think what's needed is a flexible and strong properties (easily injected by ANY dependency framework implementation) implementation in the language/JDK. This should be also with good events and easy usage of javax.interceptors. And all standard annotations should be "meta" so any user/framework can extend from them.

I agree that the DI implementation should not be part of the JDK. Te JDK is already bloated like it is.

I think there should be a JSR: Packages that will be removed from the JDK and provided on demand.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.