Tuesday, May 05, 2009

Announcing @javax.inject.Inject

I'm proud to announce a new dependency injection specification backed by both Google Guice and Spring. You can catch the official announcement over on the Google Code Blog:

Five years ago, Spring 1.0 brought Java dependency injection into the mainstream. Three years later, Google Guice 1.0 introduced annotation-based dependency injection and made Java programming a little easier. Since then, developers have had to choose between a) writing external configuration or b) importing vendor-specific annotations.

Today, we hope to give developers the best of both worlds. Google Guice and SpringSource have partnered to standardize a proven, non-controversial set of annotations that make injectable classes portable across frameworks. At the moment, the set of specified annotations consists of:

  • @Inject - Identifies injectable constructors, methods, and fields
  • @Qualifier - Identifies qualifier annotations
  • @Scope - Identifies scope annotations
  • @Named - String-based qualifier
  • @Singleton - Identifies a type that the injector only instantiates once
One additional interface is specified for use in conjunction with these annotations:
  • Provider - Provides instances of a type T. For any type T that can be injected, you can also inject Provider.
You can check out an early draft of the specification. We deliberately left external dependency configuration out, so as not to quash ongoing innovation. We haven't formally submitted this standard to the JCP yet, but we plan to do so shortly. Standards wonks can read a draft of our JSR proposal.

The expert group will be inclusive and will work in the open. For example, our mailing list is publicly readable, and we host the specification at Google Code. Several industry players have already expressed interest in supporting this effort. Contact us if you'd like to help out.

This specification will address the last shortcoming of annotation-based dependency injection. You no longer have to import vendor-specific annotations.

Our hope is that this specification will not only improve interoperability between existing dependency injection frameworks and unify the Java community, but it will also lower the barrier to entry for new injector implementations and foster even more innovation in this space.

I'd like to thank Paul Hammant, Doug Lea, Tim Peierls, James Strachan, Hani Suleiman, and Jason van Zyl for their early reviews and official support. Special thanks goes to our partner in this endeavor SpringSource, especially Rod Johnson, and my fellow Googlers and Guicers Josh Bloch, Jesse Wilson, Kevin Bourrillion, and Dhanji Prasanna.

27 Comments:

Blogger Spiff said...

That's good news - but what is the relationship of this project with JSR 299?

11:05 AM  
Blogger Bob said...

299 is an EE specification and it specifies its own approach to configuration. In contrast, our specification's only requirement is the Java Programming Language v5, and configuration is left up to the injector implementation. 299 could be one such compatible injector implementation if the EG decides to adopt these annotations.

11:11 AM  
Blogger mcculls said...

+1 this news really made my day!

Thanks to everyone involved in this effort and looking forward to using this API in practice :)

One quick question - will Guice's Provider interface extend the javax one in the future, or will it simply be removed and replaced by the javax standard? Just wondering what will happen to existing extensions that currently code to com.google.inject.Provider

11:16 AM  
Blogger Bob said...

Guice will support both indefinitely. Guice's Provider will probably extend the Provider from the spec.

11:29 AM  
Blogger Kartik said...

Hi Bob,

I worked with Guice 1.0 and am migrating to Guice 2.0. Is this part of Guice 2.0 version or do I have to download a patch separately for this?

Sorry for digressing, but have you had a chance to work on DebuggingObjectOutputStream class that you had posted about earlier. I really hope this goes into JDK 7

11:39 AM  
Blogger Bob said...

Kartik, we'll support this in Guice 2 after it gets a little further along.

Unsure about ObjectOutputStream. I think Sun's VM already has a system property you can set, but I can't seem to find it.

12:39 PM  
Blogger Gabriel Kastenbaum said...

Great news!! Thanks!
Too bad for the 299 = the JSR-formely-known-as-webbeans

3:51 PM  
Blogger Shawn Vincent said...

Exciting news! One minor comment, FWIW:

The draft spec, as it sits, requires that "injectable methods" return void.

What is the reason for this? Basically, it prevents injectable classes from being used in builder patterns. Folks that treat the bean setter specification too seriously have this issue also.

Is there a good reason for this that I'm missing?

5:19 PM  
Blogger Bob said...

Shawn, we could definitely relax that restriction.

5:47 PM  
Blogger grandfatha said...

Testable code, here I come.

11:41 PM  
Blogger Brad Cupit said...

This comment has been removed by the author.

5:31 AM  
Blogger Brad Cupit said...

Any chance these annotations will be in JDK 7 (much like @Resource, @PostConstruct, etc.) were included in Java SE 6?

8:01 AM  
Blogger Jordan Zimmerman said...

I'd be very disappointed if this makes it into Java. There are a lot of developers who dislike IoC. If people want to use it, let them. But, putting it into the language/library is a mistake.

This JSR does not solve any problem it only makes life easier for developers using dependency injection. This is not a sufficient reason to bloat Java.

11:25 AM  
Blogger Thiago H. de Paula Figueiredo said...

I think you can add Tapestry-IoC to the list of current IoC and DI containers that can serve as inspiration for this JSR.

11:30 AM  
Blogger Bob said...

Brad, we do intend for this to go into JDK 7, and we also intend for it to be usable on its own with any platform that supports the Java Programming Language version 5 or later.

Jordan, you're in the minority, but don't worry; annotations take up very little space.

Will do. Thanks, Thiago!

11:36 AM  
Blogger Jordan Zimmerman said...

>Jordan, you're in the minority
Come on now - this is an obviously unsubstantiated statement.

1:45 PM  
Blogger Thiago H. de Paula Figueiredo said...

@Bob: You're welcome! Tapestry-IoC can be used without Tapestry (the Web framework) and draw some inspiration from Guice, but has some nice additional features, specially distributed configuration.

By the way, there's a discussion in the Tapestry mailing list about taking part in the JSR. If Howard, the framework creator, doesn't step up, I'll do it. ;)

2:18 PM  
Blogger Bob said...

Thiago, I added your name to the JSR. Thanks for the support.

9:06 PM  
Blogger Martin said...

The @Documented is quite useful for these annotations. Someone should add this to the Guice 2 if this not already done.

1:21 AM  
Blogger Kartik said...

Hi Bob,

I have another question for you. It is a simplistic example but never theless

public class EntityService {

private final Foo foo;

private final Bar bar;

@Inject
public EntityService(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
}

If I want to inject either Foo or Bar only, how do you think the single Inject annotation can do this? Guice has assistedinject but do you think such a provision can be incorporated in this JSR?

1:06 AM  
Blogger Elias Ross said...

I essentially wrote the same comments on "The Server Side", but they bear repeating here.

What adding @Inject to Java SE seems to suggest, is that all your important service objects "should" have these annotations in them to be interoperable with other components. In many ways, it's suggesting: We have this new standard and for the past 10 years of Java you've been writing code one way. But now you should add @Inject to all your application code for IoC interoperability, and use an IoC container for deployment.

I don't really like the idea of retrofitting existing classes with @Inject or people asking me to add them to my new classes even though I don't need @Inject myself. Java was designed with traditional constructors and static build methods or locator methods and now Joe Programmer has to then wrap his brain around @Inject? And I don't see the burning need in standardizing this, even though I do find IoC pretty useful in specifying an application deployment configuration, I don't want or need it in third-party libraries. Thus, I'm perfectly happy using a specific set of non-standard annotations in my application, since it really just lives at the outermost deployment level.

I just don't see much use in adding in annotations if you don't have a way to actually use IoC. That is, write a complete application that uses them, in plain Java. Without a deployment framework, you may very well end up with a lot of annotated code but no way to assemble it into a deployment, without going to a third-party vendor. What subsystems in Java SE work this way? Existing subsystems, like XML parsing, are at least pluggable, ship with a default version, and share the same standard API.

3:18 PM  
Blogger gerferra said...

Guice could easily be the default implementation. You should try it, it really imposes a very small overhead to "traditional" java

The big advantage is that you can use the goodness of Guice DI style with any framework, including Spring. That's it. Guice found an incredibly good way to specify DI and the people in SpringSource know it and want to use it. It's great for all of us.

Greetings

6:49 PM  
Blogger Epikuruz said...

Hey Bob!

Few comments to "your" proposal:

1.
I am not a fan of the idea that all beans are equal.
I am proponent of distinction between Service Beans (that which has some business logic) and Configuration Beans a.k.a Model/Entity Bean those which provide configuration.
This is what is aspect is completely missing in this proposal.


2.
We need sooner or later tackle the need of configuration changes at the runtime. This means that immutable beans might be not a way to go, but synchronization logic
must be upon the framework (container). This requires special consideration. I personally hate JMX but the question what are the requirements to "marry" say JMX with IoC containers.

3.

Good IoC contract API should be scalable
You should cover equally well the case like Spring, EJBs, Servlet, Swing application and so on. I believe that common ground for all of those technologies may be found
It is would very bad idea that each of those technologies are rolling they own special IoC annotations and all of them.
What I mean is that if this API is well designed "extensions" like WebBeans, EJBs, Servlets etc should be built on top of it.
It would be even nice to answer the questions like; if next versions of OSGi are going to support Dependency Injection - what will be needed from some API.
But this requires careful investigation of use cases brought by all those standard technologies.
It will be no good for Java to have proliferation of DI APIs for specific domains which are very similar.



4.

There are some overlaps between this API and JSR-250?
What is a difference between (except a name) - javax.inject.Inject javax.annotation.Resource?
Why we could not "amend/deprecate" Resources API?
There are some extras in JSR-250 which are in fact required by IoC container - e..g annotation for lifecycle methods (they are poor but enough for simple cases)? What we do with them?
Take them as they are/drop/ignore?

-

michal

5:53 AM  
Blogger Sony Mathew said...

Wrong assumption at the start - we've been using Context IoC for a very long time. Don't need Guice, Spring, XML files or Injection Annotations scattered about and it is pure J2SE. Context IoC Bindings are straight up Java and fully configurable at anytime. The concept works for any language (in fact I've noticed adoption of the concept in Scala and C++) and now as we move to GWT it works great there as well while Guice & Spring will Not. I will admit Spring & Guice come loaded with a lot of other goodies beyond IoC (they have to, an IoC container by itself is just pointless). It is also false that you need an IoC Container for decoration & cross-cutting. We specify cross-cutting behavior in Context IoC Bindings just the same as you would in Spring XML files.

11:27 AM  
Blogger Bob said...

Sony, with Context IoC, every time you inject something, you have to declare an interface method which you have to implement for each dependency implementation. With Guice, you just annotate the injection point with @Inject. Also, Guice does work on GWT. See GIN.

11:36 AM  
Blogger Robey said...

There are tons and tons of things in the JDK that many people don't use so I don't understand the argument that some people won't use the @Inject annotation so it should be kept out of J2SE.
The fact is, that there is a large community out there that is using annotation based injection and we're all using annotations tied to a specific container, which means that swapping out implementations would be very difficult. By adding some simple annotations to J2SE we can address this. It's the same concept as coding to an interface rather than an implementation.

3:50 PM  
Blogger Mikkel Petersen said...

Lol at Jordan "alot of devs dont like Ioc" Yeah i know that but WHY ? its like saying "alot of devs dont like streams, so they should be excluded from the jdk". just lol

10:44 AM  

Post a Comment

<< Home