Google and Spring are proposing a JSR to standardize a set of dependency injection related annotations. I've been asked by several people to comment on this and how it relates to JSR-299.
First, the proposed JSR would define a strict subset of the functionality that already exists in 299, so there would be no difficulty in having 299 containers support the proposed annotations. And, of course, any implementation of 299 has functionality that goes well beyond what is being proposed here. So this new JSR proposal is not in competition with 299.
Second, the annotations proposed in this JSR proposal are more or less equivalent to a subset of the annotations defined in 299, modulo naming:
- @Qualifier is equivalent to @BindingType,
- @Scope is equivalent to @ScopeType,
- @Singleton is equivalent to @ApplicationScoped,
- @Named is just a built-in binding type, and
- the Provider<X> interface is equivalent to Instance<X>.
Furthermore,
- @Inject is more or less similar to @Initializer.
Now, I think it would be a huge mistake to introduce a second set of annotations which are semantically identical to those in 299 and address the exactly the same problem. So I interpret this JSR proposal as saying: let's take a subset of the annotations that are already defined in 299, split them out into a different package, and make them consumable to other containers that do dependency injection. This is certainly doable, and quite appealing on some level, but I'm still waiting to be convinced that it's really worth doing.
The problem is that the new JSR proposal has been carefully scoped so that it includes only the things that the folks proposing the JSR (i.e. Spring and Guice) already agree on, and leaves out all possible areas of divergence between existing dependency injection solutions. It's as if the folks proposing the JSR recognize that they're simply unable to reach agreement on all the hard stuff, and want to keep doing that stuff in their own incompatible, proprietary ways.
For example, the proposal leaves out of scope the following interesting issues:
- how do I interact with the dependency injection container?
- what kinds of objects are injectable?
- how do I indicate to the container that something is injectable, and declare its qualifiers?
- what is the lifecycle of the injected objects?
- how do I define different deployment scenarios, with different implementations of injected types?
- what restrictions exist when I have circular dependencies, serialized scopes, etc?
- what SPIs exist to allow third-party frameworks to integrate with the container?
- what are the standard set of scopes that exist in a web environment?
(This is by no means an exhaustive list.)
But from the point of view of the application developer, without a specification that addresses all these questions, there's just no possibility to build portable applications using these annotations. And portability is the usual goal of a JSR, right?
By contrast, JSR-299 does nail down all this stuff, and more: it's a complete specification for containers that do dependency injection, and for portable applications that run on those containers. To my mind, that's much more useful.
(UPDATED to correct interpretation of Provider interface.)
What are the chances of ratifying either of the two standards? I totally agree with you that covering a larger part of the problem is more useful - but if the very nature of JSR-299 is such that it covers greater functionality - and almost by definition then is more difficult to ratify - does not the time at which we Java developers can start using one proposal or the other with full confidence that it is a standard not also become part of the equation when determining utility?
Well, obviously JSR-299 is much closer to ratification, since:
This new JSR has not yet been officially reviewed by the EC, no EG has been formed, and there is no actual written spec (just some JavaDoc). Assuming that this is not an effort to rubberstamp work that has already been done by Spring/Google, I therefore assume it will take at least 2 years to write the proposed specification and get it through the various JCP process stages.
My feeling as well. This proposal gives a false sense of portability. Reality is that too much is left un/underspecified. I fear that such an approach would do more harm than good wrt portability:
JPA is already very well specified (semantic wise, not implementation detail wise: a hard boundary to maintain). But despite that, people are still having some portability issues. I can't even imagine if we had left more unspecified.
Yeah, I mean, I'm thinking of it this way:
I would say that the answer is maybe 5%.
Whereas Java EE with JSR-299 does let you write truly portable applications that take full advantage of the container and its services, there's no way that Java SE with (this new proposal) is going achieve the same thing. Applications that use a DI container are dependent upon a whole lot more than just the dependency injection annotations! And in a sense, the actual dependency injection is the least interesting thing that a container like Spring, Seam, Web Beans, etc does.
This is AOP Alliance all over again...
Hi Bill,
This was my immediate thought. It is unfortunate because I have a lot of respect for Bob and really admire his work which always strives for simplicity and elegance.
I can understand the attraction for the proposers as creating a set of annotations is pretty easy work - no reference implementation or detailed behavioral specifications.
I do not know Bob personally but I do not believe him to be a politically driven. Now for Rodney, , it is a completely different matter. SS has never created standards it only uses () and abuses () them when it needs them.
I would have liked to see Bob try to address this within the current specification and maybe this is a failing on the part of the committee.
William
Gavin,
First, as I told you when you brought this up over a week ago, Provider and @Produces aren't the same at all. See the example in the Javadocs.
Second, I don't intend to provide anything beyond Javadocs. Javadocs are a fine way to present a specification, better than PDF I would argue. High level topics simply go in the package description. Given its small size and lack of controversy, our specification should sail through the JCP in about five months, less time if we run it under the EE 6 umbrella.
Third, you only seem to care about EE, but the Java world is much bigger than EE. My company doesn't use EE at all. I personally work on Android. Luckily, 299 can continue to standardize everything you say this proposal lacks, and you can have 100% portable applications in the EE world. No one is stopping you. On the other hand, having only 299 without our proposal would preclude everyone outside of EE from using standardized dependency injection annotations, or at least it would force them to depend on . No thanks.
While 299 may be fine for small scale EE applications and cute examples, its global configuration and lack of explicitness makes it unsuitable for the multi-million line applications like we have at Google. We can easily support 299-style configuration on top of Guice, but we can't do everything we do with Guice using 299. We have no reason to switch. Personally, I think you've far too much in 299 and don't fully understand the implications on maintainability of users' code.
I believe that the best general-purpose dependency injection configuration will build on the Java modules work we're doing in JSR-294. I'm content to specify the annotations for now and wait for Java 7 instead of trying to work around the lack of Java modules. I know this doesn't help EE 6 which can't wait for Java 7, but that's where 299 comes in I suppose. We shouldn't build a workaround into SE though because we'll be stuck with it forever.
I understand that EE specifies the whole kit and kaboodle whether the time is right or not and quite possibly replaces it wholesale later, but the SE world has to be more conservative and incremental. For example, the scope of our proposal is almost identical to that of JSR-294. 294 specifies the Java syntax for modules but leaves most of the semantics including module resolution completely up to an external module system.
Bill, the AOP Alliance has been very successful.
William, this specification will have an RI, TCK, and even a (an annotation processor that validates injectable classes). Thank you for the kind comments.
Bob
The question of how much a spec should cover is a really good one. Cover too little and the spec is useless wrt portability. Cover too much and some of the complicated edge cases end up wrong, I think JPA is an example of walking this line very well. It covered 80% and you were encouraged to go outside the spec for the remaining 20%. JPA2 is now nailing down some of the more complex areas after everyone knows more. I'm having trouble seeing how Bob's spec is useful at 5%. This seems far too little to be useful. In my opinion, JCDI is a much better spec and I hope it ends up in JSE some day (as well as JEE6).
No, Bob's a friend and I hope nobody reads me as implying that.
Definitely. Our technical disagreements are orthogonal to our personal relationship. :-)
If JSR-299 could probably support the annotations and interface being introduced by Google and Spring, and there is a need for people to have using these annotations NOT in EE, why are there going to be two sets of annotations? Isn't that going to be somewhat confusing and redundant to Joe User? Couldn't one JSR define the annotations that will live in SE and have JSR-299 use them and fill out all of the other EE things?
As an outsider, the split-purpose and duplication of these annotations seems rather silly.
Yes.
OK, so it's like a combination of @Produces and Instance<X>.
I don't agree with this at all. It certainly wouldn't be practical to try and write the JPA specification as a set of JavaDocs, for example. Perhaps for some extremely simple systems it's possible.
Sorry Bob, but 5 months is just not reasonable. It will take you a month to get the JSR accepted, a month for voting on the public draft, a month for voting on the final draft. That leaves you what, 2 months to form an expert group, take input from the experts and the community, write the specification, seek community feedback? Are you kidding me?
Certainly we would never vote to approve a JSR proposal with a 5 month timeframe. That's not a , it's a rubberstamp. Totally contrary to the goals of the JCP. So I hope when you submit the JSR proposal, it proposes a much more realistic timeframe!
That's not true. As you know, I'm very keen to see a subset of 299 be generalized to support other environments in future. That wasn't possible in 1.0 due to the many very difficult political issues involved.
That's silly:
Bob, that starts to sound like SpringSource FUD, not like the kind of stuff I would expect from you!
Blah blah blah. Bob, when you have a real technical point to make, I'll be happy to explain to you exactly why you're wrong :-)
(And of course it's not true that 299 configuration is global, please stop saying that, since you know better.)
LOL, that's why SE is so great!! For example, why it's 2009 and I still have to use java.util.Date in my code, and explain to people that for some reason java.lang.Object is a semaphore! Geez, the SE guys havn't even managed to figure out how to do properties in Java! C'mon Bob, the SE SDK is now a steaming putrid pile of kaka full of errors that never get fixed, whereas EE has gone through a whole lot of great incremental improvements over the past few years. In my opinion, the biggest problem with EE today is SE :-)
Yes, in theory, the main problem is the timeline. The timeframe for 299 is a proposed final draft in 6-8 weeks from now, so that it can make it into the Java EE 6 release.
A new JSR normally takes 2 years or more to get to proposed final draft, if it ever gets there! (I'm disappointed to see Bob talking about 5 months, since it implies a rubberstamp of proprietary technology, which would be very unlikely to be approved by the EC.)
So if we wanted to have a single common set of annotations used by both SE and EE6, they would need to be defined now, as part of JSR-299. It would certainly be possible to take some of the annotations in 299 and (after discussing their names), move them to a special package (javax.inject or whatever). Then a new JSR could make use of these annotations.
Since there is really very little difference (aside from naming) between the annotations proposed by this JSR, and the annotations that already exist in 299, this is actually quite doable.
By the way Bob, if you're truly seeking our support on this JSR, rather than ranting, it would be better to actually address the concerns that have been raised with respect to portability...
Can you elaborate on why you think JCDI doesn't scale as far as maintainability? What specific features of Guice enable this maintainability? Also, what do you mean by global configuration in JCDI?
If you are waiting for 294 to build the real DI system on top of, what is the purpose of specifying these annotations now if it only covers 5% of the DI space? How does this improve portability in SE for anyone? I'm not arguing here, I'm more trying to understand your perspective and motivations for introducing this spec now. (Guice is awesome, btw. Thanks!)
innovated
Sorry for just dropping in but I think you are misunderstanding the point of standardization completly. Why would Google care about standardization of the software used in their projects? There are dozens to hundreds of top rank developers working on Android and other Google apps. They have their own style of coding their own frameworks etc. - in short they follow their own standards. If someone leaves and a new one joins it is easy to get him on board.
But the smaller companies care for small scale EE applications. I work as an architect for a company with around two hundred developers - some excellent, some good and some not so good. Currently I am involved with five projects in various stages. And it is here that standardization comes in. If I had to use five different technolgies at the same time I would simply go nuts. I need to be able to look at a project and it immediately. The same is true for the Joe Developer in my company: A standard technology enables us to shift resoource between projects more easily. So the excellent programers can focus on the complicated highly sophisticated stuff, while the sub-average guy understands enough to fix a simple bug or add an input field to JSF page. And if anybody leaves he may take away some of the domain knowledge but at least it is easy to find somebody who can take over technically. So a standard technology makes it easy to shift resources.
This - and only this - is why portability is relevant to me: Some of our customers use JBoss, others use Glassfish, Websphere, Weblogic, plain Tomcat etc., this number has to be multplied by the usual suspects of RDBMs, messaging systems etc. and you have an incredible number of possible combinations. We would simply not be able to cater for all our customers. I would just go insane! We desperately need one target plattform and then be able to deploy it at all our customers.
Of course, there is a huge disadvantage in the JEE standards: Most of them are very complex and the learning curve is steep. But the investment into learning (and teaching) these technologies usually pays off in the long run because these standards technologies are used over and over again. Take JPA for example: To develop a nice JPA base data model you will need specialists that know not only Java very well but laso the underlying RDBMS. But once the ORM job is done I can pass the development of the busness logi and the GUI on to someone else without any knowledge of underlying data bases at all. They only need to know how to use the EntityManager and some EJBQL - that's it!
So to sum his up: For us smaller companies doing it is not standardization vs. maintainability of users' code; it is rather standardization equals maintainability.
Felix
Right, c'mon Bob, I want to hear this too, man up! :-)
This isn't Guice's Provider. javax.inject.Provider is only like Instance<X>.
Like this specification?
Hopefully we won't need RedHat's vote then. This specification has already undergone review from key community members who will likely make up the EG. You should know. I sent the spec to you a week before the public announcement. The spec has the support of Guice, Spring, PicoContainer, Tapestry IoC, and even Simject, not to mention James Strachan and other prominent users.
I'm sorry I'm not an expert on 299. The 299 public draft spec required EJB Lite at a minimum last I checked. The fact remains that EE-isms like programming model restrictions and magic proxies permeate 299. For example, 299-style class proxies require no-argument constructors which get in the way of supporting immutability, something I know you don't care much about, but many others do.
I'm not a 299 expert, but the configuration looks global to me. It builds on the global type namespace. Do you need to use class loaders to break down your 299 application? How do I bind the interface Executor to different implementations in different parts of my system? (all running as part of the same application instance)
Is picking on a 15-year-old API the best you can do? How long did EJB 1.0 last? The worst parts of SE were pushed in from the enterprise world: CORBA, JNDI, web services.
Bob
See the question in my reply to Gavin above.
Gavin said that these annotations only standardize 5% of Spring, which is much more than DI. These annotations cover more than 90% of users' code (I sure hope external DI configuration doesn't account for 95%!). This spec also addresses one of the biggest complaints about annotation-based dependency injection. Users don't want to import vendor-specific annotations into their core classes. It's simply too early to set external DI configuration in stone, and users don't care nearly as much if their configuration is vendor-specific anyway.
Bigger companies need standards even more than smaller companies. That's why we have to make sure we base these standards on proven technologies and get them right the first time (EE doesn't have a great track record here). When I say applications, I mean applications with few lines of code, not applications from small companies. In a 299 application, changes ripple across your entire application, so it gets unwieldy once it reaches a certain size. You need compartmentalized configuration like we support in Guice 2 so you can safely make isolated changes.
Bob
Ah, interesting, then your proposal is even more consistent with 299 than I thought. That's good to know.
In it's current, under-specified, unportable form, perhaps. But to define anything reasonably portable, I believe you're going to have to write a real specification document. Not throw out a bunch of JavaDocs and ask the community to rubberstamp them.
Look, it really depends what you want from this. If you want to produce a common set of APIs (a la AOP alliance) that will be implemented by various open source projects (including the 299 RI, potentially), then go the AOP alliance route, and just release your APIs as an open source project and we can all implement them. I don't see what is to be gained by going through the whole JCP process.
But if you want a JCP standard, then I think it needs to
And yes, you're going to need the votes of EC members like Red Hat. And for us, a 5 month time frame is going to be a deal-breaker. Sorry.
The spec says:
If you're not using these EE services, where's the dependency to EJB Lite?
What provides transaction management and persistence in your JSR proposal? Oh, that's right: totally proprietary code in Spring.
This is only true for objects with a normal scope, like @SessionScoped, @ConversationScoped, @RequestScoped, etc. Objects with @Dependent scope (the default) are not subject to these restrictions. This restrictions exist to ensure well-defined, portable behavior of components which belong to serializable scopes like the session or conversation scope, or which have circular references, etc. i.e. all the things that your proposal leaves unportable and out of scope!
It's not. In an EE environment it is scoped to the EE application (which is not a global scope) and we've been discussing the possibility of EE module scope. In the SE environment it's scoped to whatever is responsible for bootstrapping 299.
What's the scope of a configuration in your JSR? Oh. It's undefined.
Well, for 95% of usecases, deployment types are the solution.
For the remaining 5% (mainly third-party framework integration), we did have an XML-based configuration format. After much soul searching, it looks like we're making the decision to remove the XML format and instead provide an API for this.
How do I bind different implementations of Executor in your JSR? Oh. It's undefined.
FYI, I don't buy that, and neither do most of the other folks I've asked about this.
When I say 299 lacks the necessary explicitness, imagine that you have programmers switching between projects and maintaining code. How do these programmers know where the injection points are? Hopefully they have a tool to tell them, because 299 often only requires a binding annotation which can be project-specific.
Back to scalability (in terms of lines of code), once they've identified an injection point in an unfamiliar 299-based application, how does this programmer know what is going to be injected? The process is quite complicated:
1) Find the set of all that implement the injection point's type T. You have to search your classpath for classes that implement T, no matter how indirectly. Remember that a bean in 299 can also be implemented as a producer method which can pretty much appear anywhere.
2) Take this set of and filter out a subset of beans that have a superset of the injection point's set binding annotations.
3) Find the bean in this set with the highest deployment type precedence (a global setting). Hopefully there's just one!
If more than one match is found, The 299 spec requires implementations to . Of course, Guice wouldn't throw an exception. It collects all errors until it can proceed no further and then reports them all at once.
Contrast 299's resolution algorithm with Guice's:
1) Find the binding in your local configuration that matches your type exactly (no need to even search for sub types). There will only ever be one possible match. Guice's configuration is centralized (including provider methods) to make this process as easy as possible.
Bob
You should take Guice for a spin. :-)
JCP is Java Contradiction Process
Don't spread FUD. The spec isn't done but it won't take long given its small scope. If you think we should widen the scope, please provide specific suggestions.
Unlike 299, our mailing list is already publicly readable and the latest spec will be available from source control at any time. Our EG will represent the vast majority of the DI community (you're welcome to participate!). There's nothing proprietary about it.
So, my object can be immutable unless it's scoped or part of a circular dependency?
Our proposal addresses circular dependencies: it says to inject Provider<T>. Like I told you last week, if session scope requires an object to be serializable, those semantics should be specified on the session scope annotation.
Ah, class loaders, like I suspected. I can tell you from experience that users need finer granularity and more control than that.
Yes. We'll have to live with Guice and Spring for now. No standard is better than a bad standard.
And deployment types are global, with respect to an application/class loader.
Like Guice? :-)
i.e. F4 or Open Type Hierarchy in Eclipse.
i.e. look in the resulting type hierarchy for a class with the same binding types as the injection point.
In almost all cases this is incredibly straightforward. In most cases there is exactly one implementation of the type of the injection point. When there are multiple implementations, you need to compare the binding types, just like you do in Guice.
And, in fact, this process is completely toolable, since everything is available at compile time, in total contrast to Guice, where information about your dependencies are hidden from tools in a piece of procedural code which is not amenable to static analysis!
This is one of the main selling points of 299 compared to Guice: that dependency injection resolution uses only compile time metadata and can therefore be resolved by tools, whereas dependencies in Guice can only be resolved at runtime.
Not a global setting. A deployment-specific setting. Of course there's just one, or the 299 implementation / tooling would tell you about the error and exactly where it is.
An implementation of 299 can certainly collect all errors and report them at once. The old language about throwing a typed exception was removed. All the spec says now is that .
Now you're being ridiculous. Guice's central configuration in procedural Java code (which is totally unnecessary in 299) is going to be much more difficult to search for a matching type/binding type combination than the result set of Open Type Hierarchy.
In this respect, Guice is far inferior to 299: untoolable, and requiring a single central piece of procedural code that lists all components in the system.
In a 299 world, we're going to have a little eclipse plugin that automatically takes you to the component that matches the injection point. It's impossible to implement such a plugin for Guice.
Nothing to do with class loaders actually.
No.
The spec doesn't say anything at all about class loaders.
This stuff is specified in an XML document.
Honestly Bob, you're loosing this argument spectacularly.
Why don't we talk about your JSR instead?
That covers subclasses but not producer methods. It also doesn't help me when I'm looking at code on the web or in a diff tool.
You may only have one implementation in a small application (I guess we aren't counting mocks), but that's not typical of the scale of application Guice addresses. Your approach isn't just like Guice's. With Guice, you look at the local configuration, not every implementation of a given type that happens to be in the classpath.
We've had this discussion before, but let me try to explain it again. Guice Modules are like JSR-269 annotation processors or the module system in JSR-294; all can be executed from tools like IDEs at build time. Like 269, Guice even provides a full mirror API: http://is.gd/xAnq Like annotation processors and module systems, Guice Modules can be abused (they are Turing complete afterall), but they're also extremely powerful. You can implement a 299-style configuration on top of Guice, but it doesn't work the other way around.
For example, here's a tool that generates graphs of Guice-based applications. You can run it at built time without starting your application, instantiating your singletons, etc.
The deployment type precedence applies across my entire application deployment? That's pretty global.
Oh, I wouldn't know that. Your spec isn't public, or at least I haven't seen anything since the public draft. Did you just do a search/replace in response to my comment? ;-)
Bob
Well, aside from deployment types (which aren't sufficient), given that 299 searches the classpath for implementations, I'm not sure how I would compartmentalize my SE application without using class loaders...
Please do.
Bob
P.S. This commenting system is terribly user unfriendly.
Yay! Now we're going to go and execute the user's application bootstrap code as part of the build process! Awesome. Why didn't I think of that?
Bob, if you're honestly trying to argue that Guice - which relies upon procedural Java code to specify dependency-related metadata - is as inherently toolable as a system that allows all dependency-related metadata to be specified using annotations (or XML for that matter), I'm just going to leave this discussion now, because that's absurd.
Of course, your JSR proposal does not have any way to specify dependency-related metadata: neither in procedural Java code, annotations, nor XML.
Right. We don't require a that contains an explicit list of every object in the system. We don't require that because it's awful.
At this time there is no notion of hierarchical modules, because we're simply not convinced that they're very useful. It is an area of current discussion, however. I doubt that it will make it into 1.0. Of course, your JSR proposal also does not have hierarchical modules.
By the way, we're now waaaaaay off topic, since we're now discussing issues which are certainly not addressed in your JSR proposal. The fact that you think these issues are quite important is very interesting. The fact that in order to justify the existence of your JSR you felt you needed to attack 299 (however unconvincingly), instead of addressing the very clear concerns that have been raised is also interesting.
No, this change was suggested by IBM a couple of months ago.
Hello Bob,
Here are some comments around the JSR proposal, and the current discussion: - It is a bit unclear to me what is the problem that is being solved by this JSR: Configuration Interop between Guice and Spring, if so then as suggested above, the AOP Aliance route could be good enough, if it is more about making dependency injection a first class citizen in Java SE, then I feel more should be brought in, at least a minimal but fully functional DI container. - Overlap concerns with JSR 299 won't go away with bashing 299, actually the bashing only strethen these concerns. - A spec is definitly needed, putting on paper the problem that the JSR is adressing, the requirements, scope and deliverables, goes a long way in insuring a successful JSR. One of the big strength of java is the level of detail and attention that went into specs like the JLS or the JVM spec, in the broader sense the implementation is the spec is at odds with multiple implementations, of course most JSR do produce javadocs. - The five month lead time estimation seems a bit rushed, I would expect at least the expert group to have their say so on the timeline. - Finally the Joshua Block has evangelized, would point out that you are short of a third implemntation ;-) Cheers, Khalil
Is GWT based on any standard? No. Is the Python in AppEngine standard? No. Is Android a standard Java platform? No.
Don't get me wrong: I think Google is making great software. They are releasing innovative and useful products and the deviations in the aforementioned products may be very well justified from a purely technically point of view. But having said that I do not see much effort to make things standard. And I think this is the right decision: If you are the market leader (or apsiring to become it) why would you waste time in commitees and with JCPy to let your competitors catch up if you can .
I find it surprising that you do not see the irony here: You blame JEE for not getting things right the first time and recommend to switch to Guice TWO?
Felix
With Guice, you don't execute application bootstrap code in your modules. If you had tried it, you might know that.
Goodbye.
Like I said, I promise to tackle this once JSR-294 is a little further along. Until then, anything else is a workaround.
Neither does Guice. I seem to know a lot more about 299 than you know about Guice.
Just because you play political games doesn't mean that I do. I'm not here to . Our JSR has nothing to do with 299. It stands on its own. You took the conversation down this path. I'm not trying to distract from our JSR by discussing 299. I'm just trying to answer your questions. If 299 wants to adopt the annotations, great. If it doesn't, I don't mind. Like I said,
I don't understand why you're so threatened by our proposal. You say you want end-to-end portability, but doesn't 299 give you that?
Dude, that was a joke.
Bob
Khalil,
Have you read our early draft spec or JSR proposal?
I'm concurrently working on several new Java language features and API extensions, and I was on the 269 EG, so I understand better than most the attention to detail that goes into these things. For example, the @Inject spec uses JLS-style grammar notation to precisely specify injectable members. In contrast, the 299 public draft fails to say anything about the accessibility of public constructors. I'm not trying to bash 299. I'm just highlighting the attention to detail in our spec.
It's interesting you should quote Josh Bloch because he wrote most of the JSR proposal and closely reviewed the spec.
Thanks, Bob
Hmmm... it seems that my response appeared above your message even though the correct message was quoted. See above. :-)
Bob, in the JSR proposal you've linked to above, it states the following:
However, JSR-299 clearly does not require EJB nor are the annotations incompatible with existing injectors (at least semantically). Does this change the goals or purpose for this JSR?
Even though this thread has gone off topic, covering general DI techniques and opinions, it has been very informative. However, the original purpose of this post was questioning the level of portability this new spec. will actually provide. This question does not yet appear to be adequately resolved.
No. Even if you could partially implement 299 (the JCP doesn't allow that), regardless of what the annotations in 299 look like, the annotations in the @Inject proposal look exactly how the supporters of the @Inject proposal want them to look. If you were to change the annotations in 299 to look exactly like our annotations (details matter), you might be getting somewhere, but there's still the little matter of using a subset of an EE specification on a mobile device, in a Swing application, etc. Yuck!
The @Inject proposal has support from Guice (and GIN), Spring, PicoContainer, Plexus, Tapestry IoC, and even Simject, not to mention users like Tim Peierls and James Strachan and well respected library designers like Doug Lea and Josh Bloch. The only people I hear giving us a hard time are 299 implementors, and I'm not even sure why--the two specs don't compete. 299 is a hundred some odd pages (as of the public draft). The @Inject proposal consists of six types.
The spec enables as much portability as it should. Several configuration approaches (like 299) can be specified independently and add to the overall portability. If you don't agree that this spec specifies everything it should, please make specific suggestions for things to add.
I have an idea! Assuming means , try porting Grapher to support 299 and we'll compare the two approaches,
P.S. While Java itself is a procedural language, Guice's configuration is declarative (ordering doesn't matter, you can override elements, etc.).
Totally missed the spec my apologies, I read too much in "I don't intend to provide anything beyond Javadocs. Javadocs are a fine way to present a specification".
Wasn't my intention to be patronizing when refering to spec detail, I know that you are contributing to project Coin, in addition to your stellar track record in the java community, again I just read too much in the statement above.
I stand corrected "bashing" is a bit too strong, though some of your wording almost sounded denigrating to the work gone into Java EE.
As for Joshua Block I know for instance that you and Kevin Bourillon are of the very few lucky pepole whom have access to him on a daily basis.
From section 2.3 of the spec "JSR 299 is defining a dependency injection framework for Java EE, and might support these annotations." It is a bit unfortunate that you are not, nor Spring Source on 299 EG, so that you could steer things from the inside, and it would be unfortunate to have two sets of annotations semantically very close. Timing is also a bit unlucky, while 299 is nearing completion, the new JSR is in its inception steps.
From section 2.1.1 scope "This JSR aims only to standardize a proven, non-controversial set of annotations that enable injectable classes to be used portably across injectors." wouldn't JSR 299, as the DI EE standard qualify as such an injector?
Cheers,
Khalil
No need to apologize. I figured this was the case. We're just getting started, but I believe the spec is in a ready-to-ship state, so the EG will hit the ground running.
It's not my intention to denigrate Java EE. I simply don't use it because I'm the Android core library lead, and I don't get paid to work on enterprise specs.
I do feel very lucky. Josh is on my team and sits right next to me. :-)
Don't worry. If people want a spec badly enough (they do), timing won't be an issue.
Absolutely! I've read the 299 public draft and believe they should have no problem using our annotations. Our specification says that only one qualifier can be used at an injection point, but this is only the case if you want your object to be portable across all injectors. 299 is certainly free to inject members with more than one qualifier (but that code will be 299-specific). This is certainly something we could say explicitly in the spec.
Bob
GWT supports the Java Programming Language. I think it would be technically infeasible for it to support all of Java SE, but does this mean it shouldn't exist? AppEngine for Java supports several standards. Python is a standard. AppEngine support Django which is an industry standard. Android supports the Java Programming Language, and it's also a standard itself (specified through the OHA which unlike the JCP is an open organization). Google supports (and drives) all sorts of web standards. I personally work on the Java Programming Language and the APIs via several JSRs, though the JCP doesn't have a monopoly on standards.
A bad standard is worse than no standard at all, especially if it precludes a future better standard.
In your mind, what makes a standard so much better than an Apache licensed project with a very stable and well-defined API like Guice?
Bob
For starters, how about the part of DI.
Very clever, but the specification is called so that's out of scope. :-)
We do specify how you define your dependencies if not how they are resolved, much like JSR-294 which you probably also won't like. Sorry!
That is a great question. This is going off topic, but in my opinion, there are several things that make it better (at least in theory):
However, I think you are right: When we are talking about a very popular, stable, well-designed, well-defined API with a healthy community around it like Guice, it's almost as good as a standard. But a standard is still better :)
Thoughts?
Hi!
1.) Sorry Bob, but annotations are pretty worthless without defining the exact way they should work!
2.) I also didn't understand so far why you didn't took the few mentioned annotations from JSR-299 as basis for your work.
3.) 5 month for a SE JSR? heh, are you kidding me? EE JSRs usually are way faster than SE ones. How long are they for example discussing about Closures? 4 years? 5 years?
4.) Gavin, I can clearly see the worlds need for a SE standard for DI. I'm completely with Bob on this argument. And the fact that RI and OWB (don't know that status of resins Implementation) may run without EJB and stuff does back this argument. On the other hand, I also see your point that for EE things like JPA, JMS, JSF, EJB, etc have to be defined. But why not split the JSR-299 Spec into core and application? JSR-313 will surely need the full JSR-299 while others don't have to carry all the burden if they don't need to. I know, the time left for JSR-299 is pretty short, but this would be doable. Having the Spec modularised would also help us to incorporate later specifications more easily!
LieGrue, strub
Here is the point of view of Joe Programmer...
Bob, I really don't get the purpose behind the annotations spec, it seems to me like it exists to serve the needs of a very small part of the C in JCP, and it also seems slightly political.
Could the annotations not be defined at part of 299, what is the problem with going that route? I've tried to figure it out from the comments but it seems like the only reason this is not been done is because the naming of the annotations is a problem, hence my comment about it seeming political.
I would really love to see proper DI in java SE. It seems like 299 is far more likely to provide me with the tools to do that.
To qualify the above statement, Yeah I could use spring, but I like writing code not XML. I sometimes have a hard time just getting DI into the heads of some developers you can hire off the street, but getting Guice into their heads is exponentially harder. That is not a fault on the part of Guice Bob, but just that the entry barrier to programming is significantly lower these days, except maybe at Google, so 299 is much closer to DI for the masses in this respect.
So its great you're giving us some annotations, but they are meaningless because there is no definition of implementation so who knows how it will behave if you plug in a different provider. I think Gavin raises very valid problems.
And honestly I am not sure that 299 is the right thing for DI in SE. But its far closer to the truth than what you are proposing. I think a proper effort at spec'ing DI for SE would be the winner here, I would fully appreciate Google directing their efforts there, rather than a pretty obvious effort at political rubber stamping (sorry that is unfortunately just how I see it, I have a large distrust of anything with Spring written on it, guilty until proven innocent I'm afraid).
You raise problems with 299 saying it won't help you with your multi million line applications, but it will help the millions of us (more than Guice, or heaven forbid Spring) with the ten thousand line applications.
Ok so you've provide a recipe, but depend if you use a plain old oven, a convention oven, or maybe a wood fired oven the outcome of making it will be different.
So yes I do not like, maybe Google is okay with their code been unpredictable, or just maybe Google intends to forever use their own implementation (Guice), while the rest of us suffer the worse for it.
Sorry, in the most polite way possible I'm going to have to call BULLSHIT on this one.
...http://publicobject.com/2009/05/my-perspective-on-atinject.html
Read my full reply
cough JSR-250... enough said
This new spec proposal, on the other hand, have the approval of all major DI container authors. It is just like JSR-250, which standardized common annotations, which are usable in both EE (Java EE 5) and SE (Spring, maybe others) environments.
I like the 'standardize only what is proven' spirit of the JSR proposal, because when you try to standardize too much, you end up effectively killing innovation instead of fostering it. EJB is an example. It didn't standardized a common component model, it standardized exactly how a container should work. This doesn't let much space for inovation, or inovation can be attained only in very subtle and unexpected ways. The only way to evolve and inovate in the technology is to create a new version of the spec. And, just like you said, for big specs the time frame to do this is not months, but years.
It would be best if only one set of injection annotations should be used. If JSR-299 ones could address what this proposal do (@Qualifier), and could be deployed as a separate jar, other containers/specs could use them. Maybe it could even span into another JSR in the future (just like JPA). I don't think naming is an issue, and BobRod could live with 'Instance' instead of 'Provider'.
Thanks Jesse, my concern is people using just those 5 annotations in the spec, may expect to swap out IoC containers like you swap out persistence providers and have everything run along just fine, I mean if its in the javax namespace it should right? I am very much doubt that switching out containers will be painless process. Especially if we add a year of innovation to each container.
And even then swapping persistence providers is far more difficult than advertised, and that is a pretty well spec'd JSR.
Look I know the spec is not claiming to provide any portability guarantee's but then it begs the question why the JSR, other than to get the annotations into the javax namespace? If its in that namespace it is implying portability to the millions of java developers in the world.
Since JSR 299 is recognized as relevant stakeholder, I am feeling a bit cheeky bringing a bit of Josh's Mantra . Public discussions can heat up pretty quickly, but I would suggest a more inclusive relationship with JSR 299, as the new comer, I feel you would have to do the big part of the convincing, and to go in great lengths in showing patience and making you point more appealing, In some cultures beguinning the first day by loosing a vote would be plain bad Karma :-)
Cheers, Khalil
Click HELP for text formatting instructions. Then edit this text and check the preview.
I can understand the desire to shorten the delivery time for other smaller vendors not necessarily interested in tackling the need of every application type and requirement in the enterprise space.
Small can be beautiful if versatile and extensible but I think if the problem domain is reduced for sake of speed and consensus amongst all then the reduction in time is basically pushed elsewhere leading to constant re-invention (not innovation) on a grand scale across every project and framework that needs to address a concern not in any way handled within a limited specification.
Are we sure that in the end this will really add value other than making some feel somewhat easier in importing a annotation from a javax... namespace rather than org.spring... In this regard I do not agree. I think the vendors gain more here than the actually users and frankly I am not sure the users of such proprietary frameworks really care unless it can be used to rubber stamp an application as being when in fact this might not be the case at all in terms of execution behavior and portability.
I am sure that the proposal has technical merit. Its the scope and requirements I am still unsure as well as the motives of some of the parties how have shown very little regard for other standards including JSR-299.
I'm not sure whose whispers you've been listening to but this sounds like second-hand FUD - I suggest you take things people are telling you with much more salt. FYI:
Look, it's all very well for folks like Spring to now turn round and complain that they weren't involved in JSR-299, but when they had the opportunity (well, multiple opportunities) to get involved, they chose not to. That's their right, and nothing I can really do about it, especially not now, in hindsight, when the 299 Final Draft is almost ready.
Have you actually read the specification?
Well, you see, there's the problem. I, and many others, see JSR-250 as one of the most problematic specs in EE today, and don't want to repeat that experience.
Along with portability issues.
While you can't possibly get locked into an Apache-licensed project, you can get locked in by a JCP standard.
Different vendors are free to change and redistribute the Apache-licensed code however they see fit (even closed source). Having a full codebase to start with gives them a leg up so they can innovate further instead of writing the same code over and over.
Good leadership is orthogonal. I've certainly seen better, more well-specified APIs come out of some Apache-licensed projects than many JSRs. It helps that Apache projects are meritocracies and more immune to politics.
It is nice to have in your package name. ;-)
The important thing is that people understand the differences and don't just blindly use JSR standards. For example, if you built your application on EJB 1.0, the fact that it's a standard didn't help you much.
Bob
Another Joe-the-Software-Engineer opinion on the new JSR:
The whole point of this new proposed JSR in my mind concerns the following issue: During the dark ages of EJB, where on had to write code very specific to the containing environment,Back then Spring introduced a new way of writing applications. This new way was less intrusive, because the written code did not have anything to do with the container, it was just plain Java code, that was way easier to execute and test. Because of these experiences a fear towards 'putting framework-specific-stuff-in-my-code' rised in the heads of Java developers. This same fear was again and again stated when people tried Guice. They said . The Guice-reply was , which is very reasonable, because currently there is no shared way for those DI-frameworks to do their work without relying on framework-specific ways of configuration.
This JSR can not only provide such a method for DI-frameworks, but also free the developer of his fear regarding . One can decide for an DI-Framework and have his classes only contain imports to .
Another Joe-the-Software-Engineer opinion on the JSR-299:
After reading JSR-299-documentation and watching presentations about it, my general gut feeling (yes, gut-feeling) is the same as when I was working with Seam some time ago. It was always advertised as but when working with it, even the most basic things (some of the Javascript-Remoting stuff used JMS... ) required a to be installed on my Tomcat. It always felt like the framework was a way to attract me to using JBoss and not having to deal with installing Microcontainers on this that was downgraded to a all the time.
It is exactly this gut feeling that is strengthened by sentences like the following:
Transaction Management and Persistence as JEE Servicies? Oh come on this runs on plain tomcat without a bloated Java EE container and now I even need some thing to run it in plain SE? No thank you, my problems are already solved without requiring some type of EJB-Container for every basic thing.
Forgot to edit one sentence, which I could not do after submitting the form, so I chose to use .
Of course this requires Spring, but a Tocmat without any .
On the issue of portability it appears to me that 299 and the annotations proposal are attempting to tackle portability from two different angles. 299 appears to approach the issue of portability from an entire application standpoint where the annotations proposal appears to be attacking it from the class standpoint.
Both have their advantages.
The annotations proposal acknowledges the vast number of DI containers on the market and provides me with some security to know that if I code to these annotations my class can be used in another DI container though not without some pain. A model that seems conducive the the SE model of development as DI continues to evolve, where application server vendor independence is less of an issue, and specific common development use cases are more varied or harder to nail down.
299 gives me entire application and class level portability at the cost of forcing my application to be developed according to 299's development models and use case assumptions. A model that seems more conducive to the EE development landscape where vendor independence and the need for vendors to provide customers with more defined development models that cater to common small to medium sized enterprise use cases is more important.
It is unfortunate that the timelines of 299 and the injection annotations proposal are off. I personally would like to see both passed and the next rev of JEE to provide support for these annotations. There is a place for both.
Mike
Bob, can you at least retract your statement of submitting a specification? The introduction of your spec will create an order of magnitude more controversy and disruption in the Java EE space than the entire 299 specification ever did.
I don't understand why you think Apache-licensed projects are immune to the effects of lock-in. Maybe we have different definitions of what lock-in means? All projects are usually locked-in to something (eg: Java, a JSR standard, Guice, Spring, etc.). The question is how risky is it to be locked into those technologies. The risk being that whatever you are locked into changes in some way that impedes your projects ability to go forward. This can be severe (ie: Vendor X changes their licensing price from $10 to $1000000) to less severe (ie: an open source project becomes irrelevant and dies). Ultimately these cases result in costly migrations being required. Apache-licensed projects usually have less-severe consequences here but the lock-in still exists none-the-less.
I am certainly not advocating blindly following JSR standards. Similarly, we shouldn't blinding follow Apache licensed projects. These are complicated decisions. (It gets even more complicated when you lock into cloud solutions (eg: EC2, GAE, etc.). Sure, there are examples of bad JSR's, but there are also examples of bad Apache projects. I am simply saying that in my opinion, JSR standards typically provide a little bit more safety. Interestingly, even in the case where the JSR sucked (eg: EJB 1.0) there are clear, well understood migration paths available. In this case to EJB3 which turned out to be a really great spec.
Again I do not think this is Bob malice intention but I think he has to truthfully acknowledge that this action (1) is a kick in the teeth for those who have worked a number of years on the current somewhat overlapping JSR and (2) creates further confusion and disagreement within the community, (3) and will once again allow the fanboys to continue to mock anything that has enterprise in it and does not come from their own largely proprietary stables. I think that further delays will see this specification die on arrival which would be terrible for the Java enterprise space which one of the submitters is clearly trying to kill off while at the same time taking root in the decay and aftermath.
I suggest you actually try 299 out, rather than basing your assumptions on where Seam was 2 years ago :-)
If you want to use just the servlet features of 299 (contextual dependency injection, events etc.) e.g. with Web Beans on Tomcat, you need three things:
thats it. No JBoss MC or something else (of course, you might want this...). If you want JMS, or EJB, or JPA, then add those libraries and away you go.
Please tell me how it is Ok when something requires the Spring container to run on Tomcat, but it is not Ok when it requires the JBoss MicroContainer ?
They are both containers and they are both from some specific vendor/community ? That argument does not hold water at all.
And as Pete demonstrates JSR-299 does not require any of it since...it's a standard that actually can be used for something directly...
--max
No, because that isn't our statement. The explicit goal of the specification is to standardize a non-controversial set of annotations. The annotations as currently defined are already compatible with 299 not to mention Spring and Guice.
I won't be answering any more questions here because Gavin deleted one of my comments. If anyone has further questions for me, please post them on my blog, and I'll happily answer them there.
Thanks, Bob
I agree that both are , but one is just a library and the other required me to enhance my server into some kind of ;) This statemenet is not about whether something is a container or not but what kind of runtime-dependency-baggage it requires.
So does it allow me to write a unit test that instantiates one of my Repositories/Daos which utilizes EntityManager WITHOUT bootstraping an EJB-Container and if so how fast is it and where can I find code samples demonstrating it?
If anyone has any doubts about how easy it is to run 299 in SE, have a look at the Web Beans ref docs, Chapter 16.4. Obviously this is a vendor-specific extension, but it wasn't hard to implement, and usage-wise it's not a million miles away from the original spec. You still get:
... and maybe event interceptors and decorators, depending on how they're implemented. The only runtime dependencies you'll have are:
So unit testing using only Web Beans and JPA is totally possible. The spec doesn't explicitly make that a requirement, but I guess it's down to the quality of the implementation as to whether or not they think this kind of thing is important.
I would have thought it obvious that if the community decided they wanted standard injection in SE as well as EE that it would be achieved by breaking off the non-EE parts of 299 into a separate (complimentary) spec. It's not like that kind of thing hasn't already been discussed. A major benefit would be that JSR-299-compatible modules/plugins/libraries which have no particular EE dependency could be used in both SE and EE (Logging is a good example).
However if there are separate annotations for SE versus EE, then those modules written for SE can't and won't work in EE. That seems like a waste to me.
Keep on fighting....That's the reason why i am now programming in erlang.
LOL, good luck with that :-D
I'm not sure that I would want to live in a world where people don't have passionate debates about technology.
As another Joe Developer,
I remember when Gavin first announced Web Beans and said it'll be based on the ideas of Seam and Guice. And i remember myself saying finally we have a standardized DI in Java world just like JPA, fantastic. Since that time i've been following 299 as it approaches to completion. And now this? I was stupidly assuming DI providers including Bob was contributing in 299. I am suprised.
Anyway, now, i am wondering why Bob and the other people supportive of his proposal didn't join the EG and have all the debate there rather than waiting for its completion and coming up with something new? Is this because Web Beans started as a EE proposal and when it drops dependency on all this it was too late? Was there a timing problem? Or was it a political decision? Or am i making stupid assumptions again?
Yes it does; Web Beans typically takes 1-3s to start a simple app; I don't have a code sample for your exact use case yet, but watch this space https://jira.jboss.org/jira/browse/JBSEAM-4184
However great 299 is as an injector, people will still want the option of using something else, e.g., Spring/Guice, esp. in SE. Technically the solution is clear: extract the annotations into a separate JSR (like Bob's), settle on the names, and have 299 use them. You all know this is how it should be, so just do what you have to do to get around whatever historical, procedural, political or indeed personal barriers have arisen and get 'er done.
BTW, the commenters should pay more respect to Spring; the technology, the company and the people. Bloatware my ass. Spring brought DI to the mainstream, and is the only reason technologies like Guice and 299 even exist. (One stat) says 73% of orgs surveyed use Spring or plan to within the next 2 yrs, and I still believe it's currently the best DI container offering.
The vote for JSR-330 appears to have passed
It seems they've done what I had hoped: 299 adopted the 330 annotations.
My Link
Isn't it the contrary ? I mean 330 adopted 299 annotations... I'm not sure but that is what I understand from what I read..
I generally try not to point a JSR by its number, I find it rather cryptic, and most people don't even now these codes... But, now this is a proof, that I might be right, I even you, Gavin, have minor problems with it... :-)
Quote from InfoQ
But, if I download the JavaDoc from JSR-299, I see @Inject, @Qualifier and @Scope (original JSR-330), instead of @Initializer, @BindingType and @ScopeType (original JSR-299).
So what is the truth ?
I like @Inject better. It is explicit about injection points, and is more consistent for setter based injection, on the one hand, and constructor based injection, on the other hand.
@BindingType and @ScopeType introduced a better naming pattern, with the Type suffix, that is explicit about the meta-annotation nature of these annotations. That is to say, these annotations are annotating other annotations.
And also @Qualifier is such a generic, non-specific name...