New Article: Dependency Injection in Java EE 6

Discussions

News: New Article: Dependency Injection in Java EE 6

  1. New Article: Dependency Injection in Java EE 6 (58 messages)

    Contexts and Dependency Injection for Java EE (CDI), a key part of the soon to be finalized Java EE 6 platform. Standardized via JSR 299, CDI is the de-facto API for comprehensive next-generation type-safe dependency injection for Java EE. JSR 299 aims to synthesize the best-of-breed dependency injection features from solutions like Seam, Guice and Spring while adding many useful innovations of its own. Reza Rahman takes a multi-part look at CDI and explains its features for TheServerSide. Read Article

    Threaded Messages (58)

  2. DI is an Anti-Pattern![ Go to top ]

    I cannot stand those DI myths any more. Maybe some kind, well-informed person will do all serverside Java developers a favor and debunk them. Injecting 'DAOs' into 'Services' clearly is something that couldn't stand the test of time. A DAO usually returns 'navigable models', i.e. you can navigate from one model to all other models ('parents' and 'children'). IOW, each DAO creates a dependency to the whole database. DI gives you the illusion of managing dependencies but the opposite is true. You merely 'inject' dependencies that already exist in your code. So what are the advantages of DI? Improved testability? You must be joking. Creating usable and maintainable mock objects is prohibitively difficult so it's often neglected. What else? Well, umm ... .
  3. Re: DI is an Anti-Pattern![ Go to top ]

    I cannot stand those DI myths any more. Maybe some kind, well-informed person will do all serverside Java developers a favor and debunk them. Injecting 'DAOs' into 'Services' clearly is something that couldn't stand the test of time. A DAO usually returns 'navigable models', i.e. you can navigate from one model to all other models ('parents' and 'children'). IOW, each DAO creates a dependency to the whole database. DI gives you the illusion of managing dependencies but the opposite is true. You merely 'inject' dependencies that already exist in your code. So what are the advantages of DI? Improved testability? You must be joking. Creating usable and maintainable mock objects is prohibitively difficult so it's often neglected. What else? Well, umm ... .
    If by 2009 you don't get it, why bother to explain? I like it. It has made my code better. Since you don't understand it and years after its introduction can't seem to get it, how about cutting the rest of us dummies a break and finding a new topic?
  4. Why JEE 6[ Go to top ]

    Why JEE 6 .. why not Java SE.. ?
  5. See JSR 300[ Go to top ]

    Why JEE 6 .. why not Java SE.. ?
    Covered by JSR 330, see: http://jcp.org/en/jsr/detail?id=330
  6. Re: See JSR 300[ Go to top ]

    JSR-330 came much later and is basically a subset of 299. Most of the JSR-299 containers are able to run in a pure Java SE, e.g. without the need of any EJB container, JTA, JPA, JSF, etc. Speaking for OpenWebBeans, our owb-core has no EE dependency but pulls in all this functionality via plugins. JSR-299 now even provides a standard Extension mechanism so you can simply drop your e.g. jms-299-plugin.jar into the classpath, and JMS functionality gets picked up automatically (based on the standard java.util.ServiceLoader pattern). And the best thing of this approach: this jms-299-plugin.jar will work on any JSR-299 container! Next argument: JSR-330 defines only the annotation e.g. @javax.inject.Scope but says nothing about how to implement the lifecycle for that scope! Au contraire in 299 where you have a well defined set of SPI interfaces to implement e.g. a Context for a scope in a portable manner. An example: A company has an internal toolset for creating workflow applications and we like to build a @WorkflowScoped + all the logic and 'backend functionality' needed for it. A workflow usually may last a few days to even months, will be persisted to the database, etc. It would not be possible to implement such things with pure JSR-330, but one would have to implement this scope logic for Spring, guice, Seam, etc over and over again. Otoh with JSR-299 you are able to deploy your application on any such DI. Don't get me wrong. I think JSR-330 is very good in getting a least common denominator for the 'established' DIs. But I think it doesn't go far enough. LieGrue, strub
  7. Figure 1 is wrong?[ Go to top ]

    @Reza: "Figure 1: CDI and Java EE" seems to be wrong. Isn't JAX-RS about REST, not SOAP?
  8. Re: Figure 1 is wrong?[ Go to top ]

    @Reza:

    "Figure 1: CDI and Java EE" seems to be wrong. Isn't JAX-RS about REST, not SOAP?
    Andrew, Good catch, it's a typo. I'll get it fixed ASAP. Many thanks, Reza
  9. Re: DI is an Anti-Pattern![ Go to top ]

    Maybe some kind, well-informed person will do all serverside Java developers a favor and debunk them.
    This is actually a very interesting point, albeit obviously a little iconoclastic. The simple answer is that I agree your application probably would not be so terrible without DI if you don't care about rigorous unit testing or loose-coupling and your object construction is relatively simple to begin with... That being said, even in such a very strictly "minimalistic" case, DI is still a very effective mechanism for container services delivery (@PersistenceContext/@PersistenceUnit) as well as third-party/in-house API integration, not to mention the services that build on basic DI, some of which we will cover in later articles... Hope it helps, Reza
  10. Re: DI is an Anti-Pattern![ Go to top ]

    I cannot stand those DI myths any more. Maybe some kind, well-informed person will do all serverside Java developers a favor and debunk them.
    I agree with you 100%. But you got to remember there are many consulting companies, technology sites like serverside.com and at least 1 million shallow blogers who need a topic to bang. Until they find another topic, DI would be cure for every thing:-) In the mean time I suggest people like you and me should concentrate on building the products that will be paid and used by real world.
  11. DI is not the problem[ Go to top ]

    In my opinion, DI is not the problem, but the people that use it. I think it is a good tool in the arsenal of a java developer. And like every tool, you need to decide if it adds to the project, or is a hindrance. Personally. I do not like coding singletons and factories like we did 10 years ago (*overstated*), so I use some kind of DI tool to achieve the same. I have a simple rule, use Libraries instead of hand coding (mostly they have already seen all problems and hopefully fixed them), but use them wisely. Anyone ranting not to use this, or that is narrow minded in my opinion. Kind regards, Marc
  12. Re: DI is an Anti-Pattern![ Go to top ]

    IMHO It took a long journey, from spagetti-code over functional and object oriented programming, in order to realize the necessity of even a higher level of de-coupling, modularization, flexibility and replaceability in an application. One (and probably the most important) approach to achieve this goal is the factory pattern. So please let me state that Dependency Injection isn't found by some consulting companies or community websites. It is not discussed, because there are no other issues to talk about. It isn't a myth, and it definitely isn't an ANTI PATTERN! To underline Marc's answer one more time: seeing DI (amongst others) as an implementation of the factory pattern, might open some eyes. And yes, if a proper framework is provided, rather use it.
  13. Re: DI is an Anti-Pattern![ Go to top ]

    there are many consulting companies, technology sites like serverside.com and at least 1 million shallow blogers who need a topic to bang.
    I hoped Agile would do the job of replacing DI. But you should never rely on Agile ...
  14. Re: DI is an Anti-Pattern![ Go to top ]

    I've resisted using DI because I haven't had a real need for it - although the system I work on does use Spring DI comprehensively. My colleague who is in charge of that part of the system maintains that it is the best solution to the problem of using mock objects in unit testing without having to write a whole load of factory methods. The problem is that it takes spring such a long time to wire up all of the code on startup that when you issue a simple command-line command, it takes 5 seconds before it does something really simple like list the users in the system - which is really just a simple SQL command that spits out the results to STDOUT. HOWEVER, if you are using a JEE container, it is absurd to suppose that DI is pointless. The whole point about using a container is the "don't call us, we'll call you" idea. A natural extension of this is the ability to write to an interface to ensure loose coupling. Having the container wire together the concrete implementations actually makes a lot of sense, especially as there can be a lot of time saved using higher-order JEE annotations so that they are not just injecting, but automatically doing a whole load of otherwise boilerplate code. Really, though, it seems to me that a lot of the fuss around DI and all architectural patterns all tend to enforce one design principle: splitting code into manageable areas that have few interdependencies. It still amazes me how many seasoned developers don't get the idea that code that is too interdependent (or coupled) is harder to maintain and tends to have more bugs. This is true even if you don't use unit tests to test each individual piece of the jigsaw because it is hard for the developer to get a good sense of how objects behave in collaboration when that collaboration is extremely complicated. So, I suppose the answer is to use it if it solves a problem for you. If it doesn't, then don't! (Sorry if that's really obvious!).
  15. What a load of rubbish[ Go to top ]

    I don't know where all this rubbish came from but I am also sick of it. DI, as a pattern, is something that all engineers have been using for about the past two decades. So your class uses a certain type and you want to pass different variants of that type into your class so that it can be used in different scenarios... genius. Wow. That needs a name. Let's call it "Dependency Injection". That sounds really cool and geeky. And let's also keep saying "The Hollywood Principle" because that makes us look less geeky and much cooler. And why on earth do you need annotations for this? It's completely pointless. class App { public App(Service service) { this.service = service; } public void doSomething() { ... } private Service service; } interface Service { ... } class LiveService implements Service { ... } class TestService implements Service { ... } // The live app public static void main(String[] args) { App app = new App(new LiveService()); app.doSomething(); } // A unit test @Test void testApp() { App app = new App(new TestService()); app.doSomething(); } Simple. No annotations (apart from @Test). I can actually follow the code instead of trying to trace around a maze of implied dependency annotations (or even worse, xml context files [Spring]). What is the big deal about this, really? Just get over it please and then we can all just move on and do something useful.
  16. Hear hear[ Go to top ]

    Honestly I'm inclined to agree. Always thought that dependency injection in and of itself was more or less pretty boring. But JSR-299 is *so* much more than dependency injection! The reason I resisted the rename for a while was I didn't want people to take this as just a DI solution. It's not. Rather, it's a set of interlocking functionality (contextual lifecycle management, dependency injection, interceptors, decorators, events) all based around the philosophy of "loose coupling with strong typing". It's a way to structure your code to reduce coupling, without falling down into the rabbit hole of replacing Java code with external metadata.
  17. Re: Hear hear[ Go to top ]

    all based around the philosophy of "loose coupling with strong typing".
    How can injection of DAOs into services be regarded as "loose coupling"?
  18. Re: Hear hear[ Go to top ]

    How can injection of DAOs into services be regarded as "loose coupling"?
    If you are actually arguing against layered architectures in general, that's a much weaker argument IMHO. It might be worthwhile to review the value of layered architectures here: http://en.wikipedia.org/wiki/Multitier_architecture. I think layering has value for most applications that would use Java EE, whether using DI or not. Cheers, Reza
  19. Re: Hear hear[ Go to top ]

    all based around the philosophy of "loose coupling with strong typing".

    How can injection of DAOs into services be regarded as "loose coupling"?
    Did you actually read what I wrote? Where, precisely, did I mention anything about "DAO"s or "services", or say that dependency injection on its own results in loose coupling? In fact, what I said was precisely the opposite. Oh and anyone who's paid any attention to advice coming out of our camp for the last 3-4 years knows that I am neither a fan of the DAO pattern, not of stateless services. Perhaps you got me confused with a Spring fanboy. Please no.
  20. Re: Hear hear[ Go to top ]

    Oh and anyone who's paid any attention to advice coming out of our camp for the last 3-4 years knows that I am neither a fan of the DAO pattern, not of stateless services
    Should read: I am neither a fan of the DAO pattern, nor of stateless services
  21. Re: What a load of rubbish[ Go to top ]

    See your live application:
    // The live app

    public static void main(String[] args)
    {
    App app = new App(new LiveService());
    app.doSomething();
    }
    I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application. (by separated dependency definition from the application code) I am sure, some might still find all this rubish. Therefore, make your project successfull, the way you consider it best.
  22. But really...[ Go to top ]

    I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application.
    Well, "hot module-swapping" as it were is a nice feature in principle, but come on, when has anybody ever really tried to use this? I certainly wouldn't like to take a live application and start dynamically swapping in testing stubs, not to mention the amount of extra complexity this would add to your application as it tries to handle the fact that one minute it's running against a live system and the next against testing stubs. I'm sure that if you try hard enough you can think of a situation for this and you can make it work, but for the vast majority of applications it's just unrealistic. In reality, all that actually happens is that developers start to "wire together" (another daft phrase) in xml, or now in annotations, simple objects that could have very easily been composed in standard Java. They seem to do this not out of any rational design decision, but rather because SpringSource or Guice has told them that it's a good thing. The result is something that's extremely difficult to comprehend and debug, and provides zero extra benefits.
  23. Re: But really...[ Go to top ]

    They seem to do this not out of any rational design decision, but rather because SpringSource or Guice has told them that it's a good thing. The result is something that's extremely difficult to comprehend and debug, and provides zero extra benefits.
    We're slowly finding our way to component orientation and DI is obviously a somewhat problematic (*your points*) but necessary step in that direction. At some point, you will not be (yet again) rewriting application pattern xyz for your domain but simply using off the shelf components. And a clean demarcation between container and context and the (reused) components is absolutely necessary to get there and that is precisely what DI and the spec of this thread are addressing.
  24. Re: But really...[ Go to top ]

    > I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application.

    Well, "hot module-swapping" as it were is a nice feature in principle, but come on, when has anybody ever really tried to use this?

    I certainly wouldn't like to take a live application and start dynamically swapping in testing stubs, not to mention the amount of extra complexity this would add to your application as it tries to handle the fact that one minute it's running against a live system and the next against testing stubs.
    Agreed. This is one of the main reasons why I advocate in-container testing whenever possible/practical. A test is there to validate your code, not the other way around. If you ever find yourself making your code more "testable" you have done something wrong. You have made your application more complex and less maintainable. Stan Silvert www.jsfunit.org In-container testing for JSF applications
  25. Re: But really...[ Go to top ]

    > I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application.

    Well, "hot module-swapping" as it were is a nice feature in principle, but come on, when has anybody ever really tried to use this?

    I certainly wouldn't like to take a live application and start dynamically swapping in testing stubs, not to mention the amount of extra complexity this would add to your application as it tries to handle the fact that one minute it's running against a live system and the next against testing stubs.
    With all due respect, it's not "hot-swapping" - it's integration with known components at known phases. Dude, this is the CORE of testing, if testing doesn't consist of throwing crap at the wall to see if it sticks. You have an interface, you provide something that follows that interface, and you can now test what uses that interface with great detail - and confidence. I can tell you that in every project I've started and been part of in the last six years - probably more - has depended on this, because I don't trust code that hasn't been tested, and I test my freakin' code. And my code runs in environments where failures have real impact. Nobody swaps in TESTING STUBS in live runs; that'd be stupid. What we do is we "swap in" testing stubs at TESTING TIME, when TESTING STUBS might be appropriate.
  26. Re: What a load of rubbish[ Go to top ]

    I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application.
    It hardly ever happens. Stubbing DAOs is tedious and of little use. DI is mostly used for the wrong level of abstraction! Services should never query DAOs for (massive amounts of) data because this creates dependencies on the data structures returned from the DAOs. DI fosters bad designs and architectures.
  27. Re: What a load of rubbish[ Go to top ]

    I am sure you see the advantage of stubing in various development and testing phases, or even replacing underlying modules - which follow the same templating strategy - at runtime, by just re-testing the application.

    It hardly ever happens. Stubbing DAOs is tedious and of little use. DI is mostly used for the wrong level of abstraction! Services should never query DAOs for (massive amounts of) data because this creates dependencies on the data structures returned from the DAOs. DI fosters bad designs and architectures.
    Is the problem DI or DAOs?
  28. Re: What a load of rubbish[ Go to top ]

    Is the problem DI or DAOs?
    Injecting DAOs into Services is a commonly used example to motivate DI. The problem is the overall design.
  29. Re: What a load of rubbish[ Go to top ]

    Services should never query DAOs for (massive amounts of) data because this creates dependencies on the data structures returned from the DAOs.
    Hold on son. Services may not query DAOs since they depend on the data structures returned from them??? So, what ARE services allowed to query then and why wouldn't they then be dependent on whatever that something else returns? Isn't this like saying the following: 'Services should never call a method because this creates dependencies on the data type returned by that method'. I'm not sure, but somehow I don't think what you say makes a lot of sense really, but feel free to explain yourself.
  30. Re: What a load of rubbish[ Go to top ]

    It hardly ever happens. Stubbing DAOs is tedious and of little use. DI is mostly used for the wrong level of abstraction! Services should never query DAOs for (massive amounts of) data because this creates dependencies on the data structures returned from the DAOs. DI fosters bad designs and architectures.
    Um... what? Stubbing DAOs is very useful, because it means your injected service has EXACT CONTROL over what's returned. If you have a dependency on your DAO-returned data structure, it's because you don't know how to return neutral data structures. Try returning a List - even a Foo[]. Your real DAO can manage that, I'm sure, and your testing DAO can manage it even better. I'm not following your logic here at all. You start with a straw man, and finish with a completely different straw... dog.
  31. Re: What a load of rubbish[ Go to top ]

    Um... what? Stubbing DAOs is very useful, because it means your injected service has EXACT CONTROL over what's returned.

    If you have a dependency on your DAO-returned data structure, it's because you don't know how to return neutral data structures. Try returning a List - even a Foo[]. Your real DAO can manage that, I'm sure, and your testing DAO can manage it even better.
    I think you might be right that DOAs are somewhat useful for testing, but people advocate their use for a much bigger reason than that. People think that using a layer of DAOs is going to make it easier to change persistence mechanisms later. But in this case the DAO is providing a "false sense of abstraction". There are really too many semantic differences between different persistence approaches to be able to paper over all of them with a DAO.
  32. Re: What a load of rubbish[ Go to top ]

    . People think that using a layer of DAOs is going to make it easier to change persistence mechanisms later. But in this case the DAO is providing a "false sense of abstraction". There are really too many semantic differences between different persistence approaches to be able to paper over all of them with a DAO.
    Please enlighten me: I've had success swapping out persistence mechanisms with DAOs based around CRUD operations. It's probably easier if you don't bother, sure, and the use of expendable test datastores means you don't have to use them to swap out persistence mechanisms... but I don't think the DAO pattern itself is necessarily to blame here. So what semantic differences creep in such that what you said is a pervasive problem? (Note: I'm not saying it's NOT a pervasive problem, only that it hasn't been for me, and since I'm not NOT me, I'm not sure what the actual problems are.) Are the problems generally solveable?
  33. Re: What a load of rubbish[ Go to top ]

    Joe,
    Please enlighten me: I've had success swapping out persistence mechanisms with DAOs based around CRUD operations.
    I have to say I've had similar successes and do see layered architectures as being valuable and time-tested. On the other hand, I am unsure about the actual practical benefits of overzealous unit testing as opposed to simply developing a "good enough" set of integration/regression tests using something like DBUnit to get persistence stores to a known state. Cheers, Reza
  34. Re: What a load of rubbish[ Go to top ]

    >On the other hand, I am unsure about the actual practical benefits of overzealous unit testing as opposed to simply developing a "good enough" set of integration/regression tests using something like DBUnit to get persistence stores to a known state.
    In some industries - flight control, medical stuff - there's no such thing as "overzealous testing."
  35. Re: What a load of rubbish[ Go to top ]

    >On the other hand, I am unsure about the actual practical benefits of overzealous unit testing as opposed to simply developing a "good enough" set of integration/regression tests using something like DBUnit to get persistence stores to a known state.
    In some industries - flight control, medical stuff - there's no such thing as "overzealous testing."
    In fairness, Reza said "overzealous unit testing". Not "overzealous testing". Those of us who are skeptical of class-level unit tests are not skeptical of automated testing in general. We like automated testing, we just think it should test the actual requirements of the system, not the details of a particular implementation. The problem is that class-level unit testing makes code *more* difficult to refactor, not, as advertised, less difficult.
  36. Re: What a load of rubbish[ Go to top ]

    In fairness, Reza said "overzealous unit testing". Not "overzealous testing". Those of us who are skeptical of class-level unit tests are not skeptical of automated testing in general. We like automated testing, we just think it should test the actual requirements of the system, not the details of a particular implementation.

    The problem is that class-level unit testing makes code *more* difficult to refactor, not, as advertised, less difficult.
    Fair point on "testing" vs. "unit testing." I don't know if I really agree that unit-testing classes makes them harder to refactor apart from the fact that there are more dependencies between classes (the test classes and the classes being tested.) I mean, of course the test classes are more tightly bound in most cases; they're working on white-box principles! Black-box testing is workable too but isn't likely to give you the code coverage you really need. Part of the problem is that you STILL can't really make a blanket statement about testing requirements. For me, I may need 100% code coverage. For you, 80% might be enough - or maybe even all you care about is meeting your functional requirements, focusing on methodology or what-have-you, as you sort of said. In some industries, that means people expire. In most industries, it doesn't.
  37. Re: What a load of rubbish[ Go to top ]

    Joe,
    Part of the problem is that you STILL can't really make a blanket statement about testing requirements. For me, I may need 100% code coverage. For you, 80% might be enough - or maybe even all you care about is meeting your functional requirements, focusing on methodology or what-have-you, as you sort of said.
    Well said and I think that is what we are all saying, just in slightly different ways. In my personal experience, I see a lot of people obsessing about code coverage that they do not really need. On the other hand, I see a lot of people focusing on integration testing and still getting very good results. Nonetheless, as you can see, Java EE 6 will allow you to have 100% code coverage if you need it. Cheers, Reza
  38. Re: What a load of rubbish[ Go to top ]

    . People think that using a layer of DAOs is going to make it easier to change persistence mechanisms later. But in this case the DAO is providing a "false sense of abstraction". There are really too many semantic differences between different persistence approaches to be able to paper over all of them with a DAO.
    Please enlighten me: I've had success swapping out persistence mechanisms with DAOs based around CRUD operations.
    Well, for example, if you're using something like Hibernate/JPA, you have transitive persistence (operations which cascade along associations). It's quite hard to finesse that kind of behavior out of a DAO layer. Another thing that's hard to reproduce is join association fetching. (Hand-written DAO layers are horrible producers of n+1 association fetching.) Now, you might argue that this is a pure internal performance consideration of the DAO layer. But I think it's the kind of performance consideration that leaks into the way you make use of the API. Now, for simple CRUD apps, I can see that these issues perhaps don't come up as much. But in applications with more sophisticated data access needs, I think they will make it difficult to just "swap out" your persistence layer.
  39. Re: What a load of rubbish[ Go to top ]

    DI, as a pattern, is something that all engineers have been using for about the past two decades. So your class uses a certain type and you want to pass different variants of that type into your class so that it can be used in different scenarios... genius. Wow. That needs a name. Let's call it "Dependency Injection". That sounds really cool and geeky. And let's also keep saying "The Hollywood Principle" because that makes us look less geeky and much cooler.
    The rest of the world calls them callbacks. But those people are not "really cool and geeky".
    And why on earth do you need annotations for this? It's completely pointless.
    Why did you need XML ( http://www.theserverside.com/tt/articles/article.tss?l=SpringFramework ) for this? It never made sense.
  40. Re: What a load of rubbish[ Go to top ]

    Chris, I agree (to some degree) I wrote an article regarding a pure DI pattern i.e. Context IoC a long-long time now and have been using with great success for just as long. I stopped talking about it cause people seemed to be more interested in pimping their favorite open-sore magic potion cure for this (no-existent) DI disease. I recently brushed up this old concept in a new article. Check out http://sonymathew.blogspot.com/2009/11/context-ioc-revisited-i-wrote-about.html. In the end DI is about a power-struggle to "control" the core essence of object creation in every application - you are from then on reliant on that framework for all things integration and cross-cutting which is a space that folks have been trying to carve out for a long time now and control it. I would rather see DI be part of the language itself.
  41. Well, "hot module-swapping" as it were is a nice feature in principle, but come on, when has anybody ever really tried to use this?
    Well, I don't know that hot swapping is the biggest benefit, but I can tell you from a very recent situation that warm swapping was great, implemented via DI. We changed the entire implementation of an API because of a requirements change. It went from a filesystem backed to database backed implementation. What did it take? 1) Reimplementing a relatively small class, and 2) Changing the Spring XML file that created the bean. Given that it's a phased in approach to replacing the old class/implementation, we can do this on an application by application basis without touching all the code that *would* have been instantiating the old class and having it instantiate the new one. No testing of all the code, just the new implementation. When you're in a SOX and/or PCI environment, that turns into a lot of time and money.
    I'm sure that if you try hard enough you can think of a situation for this and you can make it work, but for the vast majority of applications it's just unrealistic.
    No, it wasn't hard. It fits nicely with the way I loosely couple things and not depend on specific implementations.
    In reality, all that actually happens is that developers start to "wire together" (another daft phrase) in xml, or now in annotations, simple objects that could have very easily been composed in standard Java.
    Well, I wire together different implementations so that the "standard Java" doesn't have to rely on a particular implementation. If I want to change *how* something does its work without change *what* it's doing, DI is a great way. Maybe you never have to change out implementations with the projects you're on. I do. Daily? No, but when it has to be done, I bet using DI way is shorter, quicker, and easier. There will be a lot less source code to change. You want to use the factory pattern because you don't like DI? Fine, use that. But at that point you're using an alternative code reducing, dependency alleviating pattern than DI and it's just a choice at that point. That doesn't mean DI is crap. Beyond that, if you don't like Spring because of its "massive" config files or you don't like DI because you can't find any benefits - DON'T USE IT. Is someone pointing a gun at your head forcing you to use it? No? Then move on. Yes? Find an employment situation where you're more comfortable. I'm just tired of the "I don't understand it or don't see its benefits so it must be nothing more than hyperbole and all you guys that do use must be sooooo stupid because you've been hood-winked." It's like drinking way too much alcohol and complaining about the hangover when everyone else had only a couple of drinks. Used properly, it's a good thing. Used wrongly, it can be a real headache.
  42. Would the new features allow injecting resources into POJOs instead of EJBs/JSF beans/servlets? One of the problems I have seen in Java EE 5 projects is people use EJBs even when there is no need to simply because injecting resources into EJBs has become trivially easy and then we are back to dealing with all that unnecessary remoting, container interception, deployment complexity and so on.
  43. Satadru,
    Would the new features allow injecting resources into POJOs instead of EJBs/JSF beans/servlets?
    Yes, as the article discusses, you may use injection in non-EJB POJOs. Injecting non-thread-safe resources does require some precautions however, as the article also discusses.
    One of the problems I have seen in Java EE 5 projects is people use EJBs even when there is no need to simply because injecting resources into EJBs has become trivially easy and then we are back to dealing with all that unnecessary remoting, container interception, deployment complexity and so on.
    I think you may have some misconceptions here. Local EJBs are the default for all EJB 3 session beans. Remoting was the "default choice" way back in the EJB 1.x days. Container interception is a necessary part of any DI instrumentation, there isn't anything EJB/Java EE specific about that. If by deployment complexity you mean EAR files, you can use EJB 3.1 components in a WAR as covered in my series on EJB 3.1: http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31 (indeed, you can do this in many Java EE 5 containers today). The only real container services you get by default with an EJB 3 bean that you would not get in a Java SE object is thread-safety, transactions, life-cycle callbacks and injection (as the article mentions). If anyone else had led you to believe otherwise, they were ill-informed. Hope it helps, Reza
  44. Reza, I should hae clarified my post - my point was not to bash the EJBs (it's not fashionable anymore ;-)) but to point out that this limited injection feature in Java EE 5 led to poor design and programming practices. Yes, I know, by default EJBs are local in Java EE 5 but lazy programmers find a way out and build remote EJBs even when there is no real need for remoting, distributed transactions and declarative security - a POJO works just fine. But because there was no way for a POJO to get injected with datasources or JMS connection factories we ended up with EJBs and all the overhead from the remoting, container's transaction handling and yes, unnecessary deployment complexity of dealing with EARs and EJB-jars (not all production grade app servers support EJB 3.1). Poor programmers will find ways to abuse even best of technologies but in this case, the limited injection features in Java EE 5 only made it easier to do so. Good to see Java EE 6 is taking steps to expand the DI coverage. Thanks for the nice article, btw :-)
  45. Thanks for the nice article, btw :-)
    Satadru, No problems and thanks for the kind words. You should give the EJB 3.1 series a read, though. A lot of the EJB 3.1 features are actually already available in EJB 3.0 containers and Seam. I do agree folks tend to engage in lesser recycled EJB bashing than a few years ago. Indeed, I do see more and more EJB 3/Java E 5 projects as folks are gradually upgrading application servers. From my own (former) customer base, I have only really heard good feedback on EJB 3.0 and the major complaint is mostly a desire to be able to inject non-EJB POJOs into EJBs and vice-versa... Cheers, Reza
  46. Poor programmers will find ways to abuse even best of technologies but in this case, the limited injection features in Java EE 5 only made it easier to do so.
    I think we can all agree that Java EE 5 injection turned out to be only somewhat useful :-) That's one reason why JSR-299 exists.
  47. Would the new features allow injecting resources into POJOs instead of EJBs/JSF beans/servlets?
    Yes. 299 lets you make a resource available for typesafe injection like this: @Produces @Resource(lookup="java:global/env/jdbc/CustomerDatasource") @CustomerDatabase Datasource customerDatabase; And then inject it into any a "POJO" like this: public class Bean { private Datasource customerDatabase; @Inject public Bean(@CustomerDatabase Datasource ds) { customerDatabase = ds; } ... }
    One of the problems I have seen in Java EE 5 projects is people use EJBs even when there is no need to simply because injecting resources into EJBs has become trivially easy and then we are back to dealing with all that unnecessary remoting, container interception, deployment complexity and so on.
    A couple of points here: 1. local EJBs don't have any "remoting" associated with them 2. container interception is a pretty common technique in any kind of DI 3. the new Java EE 6 spec lets you deploy EJBs in a war, so the "deployment complexity" is finally gone Nevertheless, EJBs do have a special lifecycle and concurrency model, which is not always appropriate for every bean, so Red Hat fought very hard to get support for beans which are not EJBs into the EE 6 platform. You'll be pleased to know that you don't need to make your bean an EJB to make use of the CDI services.
  48. Oh and I suppose some folks are concerned about the "hardcoded" global JNDI name in that code sample. (I'm not, since a JNDI name is just a logical name of something that could vary depending upon the deployment). Well, here's how you can define a deployment-specific resource: class CustomerDatasources { @Produces @CustomerDatabase @Resource(lookup="java:global/env/jdbc/CustomerDatasource") Datasource customerDatabase; @Produces @Test @CustomerDatabase @Resource(lookup="java:global/env/jdbc/TestDatasource") Datasource testCustomerDatabase; @Produces @Mock @CustomerDatabase Datasource mockCustomerDatabase = new MockDatasource(); } Now, the default is customerDatabase. To select testCustomerDatabase instead, use this beans.xml file: org.mycompany.deployment.Test
  49. J2EE DI[ Go to top ]

    The problem with J2EE DI is that its very difficult to use any DI in unit tests because you have to run the container or something that emulates it (and as someone already mentioned, testing in the real environment is preferable to emulation). Spring still has the drop here because you can selectively load only parts of your DI config and because it follows the library model i.e. it doesn't take away control over execution of code. Even when your only using partial configs in this way you are still testing very much against the "real thing" so behavior is very unlikely to change when you come to run your code in a web server. So in a nutshell the practical annoyances with J2EE are more to do with the whole "container" idea than the semantics of the DI spec. Its all very well being able to inject POJOS but it isn't a great help if you cant do it in your junit tests IMO.
  50. Re: J2EE DI[ Go to top ]

    Paul,
    Spring still has the drop here because you can selectively load only parts of your DI config and because it follows the library model i.e. it doesn't take away control over execution of code.
    You should really take a look at the standardized EJB 3.1 embedded containers as well as good existing Java EE 5 testing tools like OpenEJB that allow alternative deployment descriptors. Both are specifically designed to address exactly what you are describing (not to mention the alternative bean facility Gavin already described). Specifically on Resin, we are planning to built support for JUnit and TestNG for our EJB 3.1 Lite embedded container and JSR 299 implementation. What you are saying was accurate for EJB 1.x and EJB 2.x, it just isn't the case past Java EE 5. However, the confusion is understandable if you have not taken a closer look at Java EE 5. Hope it helps, Reza
  51. Reza I see a definite lack of real-simple-use-enterprise expertise when you guys design a spec/technology like CDI, where you bring in new names, conventions, etc. for the same input/processing/output scenario which confuses even the expert level Java professionals of any grade. Because of these divertions frameworks like Spring, Hibernate (still with toomuch XML junks by them), jumps in and further confuses and de-stabilizes. Really struggling to under as how to INJECT the new concepts in the existing rock-solid Java applications which is really working great without all the new distractions. Honestly under Java EE, there are more confusions than ever, whether to use, EJB 3.0, JPA, Hibernate, C3P0, Spring, Seam, JSF, Facelet, CDI, etc. Finally we could see only the JARs are increasing...... Probably this is not a post to bash all other technologies but obviously one of them.
  52. Honestly under Java EE, there are more confusions than ever, whether to use, EJB 3.0, JPA, Hibernate, C3P0, Spring, Seam, JSF, Facelet, CDI, etc.

    I think it's not that bad. In Java EE 5, and certainly Java EE 6 using EJB is almost a no brainer. To some it may still have the 'heavy weight' feel to it, but that's certainly not the justified anymore. Nowadays I would say EJBs are really the default location to put your business logic, even if you're only using a .war deployment. JPA is pretty much a no brainer too. It's not really so that you have to choose between JPA and Hibernate at all. Hibernate is a strict superset of what JPA defines. So, you can always start with JPA and if the need arrises decide whether you want to take advantage of some of Hibernate's proprietary extensions. I'm not really sure that the existence of C3P0 is a major source of confusion either. As with JPA, just start with the connection pool offered by your Java EE implementation (they all offer a connection pool by default). If, and only if, you're having very specific connection pooling needs or run into exotic problems with the default pool, can you choose to swap in C3P0. For most people however, the default pool Just Works. Spring is more or less a complete alternative to Java EE, so it's not really something that should confuse you when you are using Java EE. You might almost just as well say that .NET is a 'confusing option under Java EE', since it's also another application server alternative. For Java EE 6, there's also not really any confusion regarding Seam. Seam inspired CDI and CDI is a part of Java EE 6. So just as with JPA v.s. Hibernate, CDI would simply be your default choice, if you need this kind of functionality. Although JSF had a little rough start, I'm seeing this too as a sensible default choice when starting a new web application using Java EE 6. What would be the confusing alternatives here? Pure servlets and out.write() style programming? Not really... JSP with scriptlets? Please... it's not the 90-ties anymore. JSP with JSTL tags? That doesn't really cut it either. Last of list, Facelets, is not really a concern either, as Facelets is a very clear winner for defining JSF views over JSP. So much even, that in Java EE 6 Facelets is the default view description technology for JSF instead of JSP. Personally I still have to see in what way I can leverage CDI though. Currently I'm pretty much in bed with the Facelets (JSF view) -> (slim) backing bean (JSF managed bean) -> (stateless) session bean (EJB) -> entity manager (JPA) chain. I'm quite happy with that, and currently don't feel the need to have my view tags bind directly to some service (something which I think CDI advocates or at least makes possible, but I might be wrong). So personally, for me there is a little confusion regarding the choice between backing beans/session beans vs CDI, but that has more to do with my own inexperience with CDI I think.
    Finally we could see only the JARs are increasing......
    I'm not sure why this would be a problem. The JARs implementing all of those Java EE technologies are internal to your Java EE implementation. I'm not sure about you, but I don't really care whether Tomcat's lib directory implements Tomcat with 10 jars or 1. Maybe Jboss AS chooses to use a 100 jars of 0.5MB internally, while Glassfish maybe consists of just one jar called javee6.jar weighing in at 50MB. Did you ever take a look at how many jars the Java SE JDK uses internally? If not, why would you care about this for Java EE?
  53. Personally I still have to see in what way I can leverage CDI though. Currently I'm pretty much in bed with the Facelets (JSF view) -> (slim) backing bean (JSF managed bean) -> (stateless) session bean (EJB) -> entity manager (JPA) chain. I'm quite happy with that, and currently don't feel the need to have my view tags bind directly to some service (something which I think CDI advocates or at least makes possible, but I might be wrong).

    So personally, for me there is a little confusion regarding the choice between backing beans/session beans vs CDI, but that has more to do with my own inexperience with CDI I think.
    CDI is more or less a much more powerful replacement for JSF managed beans. Even better, CDI is not tied to the JSF container, so you can use it with other presentation tiers (not really the case with the JSF managed beans facility). In EE6, or anywhere else you have CDI, there is no good reason to use the JSF-specific managed beans facility.
  54. Personally I still have to see in what way I can leverage CDI though.
    Augustientje, I am thinking you might change your mind when you see how CDI interacts with JSF for scope management, interceptors, decorators, stereotypes, etc as well as some of the other content in future articles of the series. That all being said, you can ignore CDI if you don't have use for it immediately as I mentioned in the article. I tried to avoid cramming too many things into this first article and establish a good, solid, familiar foundation first. Generally, that seems to work for the majority of readers... Cheers, Reza
  55. JPA is pretty much a no brainer too.
    Not at all. From mapping finesse to eager/lazy loading and other performance issues ... to CGLib and/or ASM bugs. Troubles all the way down.
    Spring is more or less a complete alternative to Java EE,
    Not at all. JEE is a 'full-stack' middleware specification and implementation. Spring are thin wrappers around some parts of JEE, esp. servlets, security, JDBC, ...
  56. Not at all.
    I think you are being a little unfair on the JPA comment. JPA is certainly not perfect (few technologies are) but there are just too many successful JPA/ORM projects to warrant too much negativity. As to the problems you allude to, I gave a fairly straightforward talk at JavaOne on how to avoid them: http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-3977&yr=2009&track=javaee. I do agree that Spring is not completely separated from Java EE. Indeed, we (the Resin team) are trying hard to figure out how it can be made highly complementary even in Java EE 6 (once we get our own house cleaned up in terms of getting Resin Java EE 6 Web Profile certified). Cheers, Reza
  57. JPA is pretty much a no brainer too.
    Not at all. From mapping finesse to eager/lazy loading and other performance issues ... to CGLib and/or ASM bugs. Troubles all the way down.
    Hrm ... do you remember persistence *before* Hibernate/JPA? Seriously, handwritten DAO layers usually evolved into nests of spaghetti code and massive n+1 selects problems, or into half-assed homegrown ORM solutions. Yes, from time to time, we still wrestle with some persistence issue, but today's persistence layers are by-and-large performant and maintainable. That was just not the case before ORM became more or less ubiquitous. Perhaps you're too young to remember ;-)
  58. Mansoor, Let's make this more of a two-way conversation please so I can try to help the best I can :-). I agree Java EE fragmentation is getting a little out of hand. We should all really take a good read at the book "The Paradox of Choice" which I happen to be a big fan of. However, there is little that anyone can do about that. Honestly, there are also some good things that come out of hyper-competition, as long as it is carried out fairly and without malice. In my mind, it is a little bit like team sports, especially at the international level. I think we can do better at competing with each other and still learn to be good friends with mutual respect "on and off the ball field". Now, can you be more specific about what you feel is lacking in the standardization process? Some specific examples would be extremely helpful. I don't claim to be better than anyone else, but I think it is fair to say I have more than an average amount of enterprise development experience and do try to make the technologies that I work on as "jargon/religious zeal" free as I can make it. However, feedback from folks like you are always most welcome... Cheers, Reza
  59. Honestly under Java EE, there are more confusions than ever, whether to use, EJB 3.0, JPA, Hibernate, C3P0, Spring, Seam, JSF, Facelet, CDI, etc.
    Hibernate is an implementation of, and precursor to, JPA. The Hibernate team recommends that you use JPA APIs with Hibernate. Seam is a precursor to CDI (and certain parts of JSF 2). The Seam team is developing the reference implementation, Weld, of CDI. Spring is a proprietary competitor to some Java EE technologies like EJB and CDI. Facelets is a standard part of JSF 2. C3P0 is a standalone connection pool. You never need it in Java EE. So, in Java EE 6, we boil down to the following: * JSF 2.0 (or other proprietary web framework like wicket) * CDI 1.0 * EJB 3.1 * JPA 2.0 If you're confused about how these four technologies relate to each other, I suggest you take a look at some simple CDI examples, which usually show how all four pieces fit together. I don't see much overlap between these things.