Discussions

News: Martin Fowler renames IoC: Dependency Injection

  1. Martin Fowler renames IoC: Dependency Injection (84 messages)

    Martin Fowler has released a paper on the Dependency Injection pattern. This is his rebranding of the Inversion of Control that we hear so much about in the recent wave of lightweight frameworks. Martin walks through an example, that shows the need for this pattern. He also comments on when to use Service Locator vs Dependency Injection.


    Article Introduction


    "In the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application. Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control". In this article I dig into how this pattern works, give it the more specific name of "Dependency Injection", and contrast it with the Service Locator alternative. The choice between them is less important than the principle of separating configuration from use."


    Read Martin Fowler on Inversion of Control Containers and the Dependency Injection pattern

    ----------

    Refactoring: Improving the Design of Existing Code ~ Martin Fowler (Author)
    UML Distilled: A Brief Guide to the Standard Object Modeling Language (3rd Edition) ~ Martin Fowler
    Analysis Patterns: Reusable Object Models ~ Martin Fowler

    Threaded Messages (84)

  2. Please stop renaming patterns![ Go to top ]

    I read and re-read all Martin Fowler's books, he has a gift for clarifying many software concepts. But he has a habit of renaming well known pattern names; such as Value Objects renamed to Data Transfer Objects. Even if it is more descriptive it dilutes the power of patterns. By sticking to the well known name a pattern's ubiquity becomes apparent and new technologies are easier to understand as an aggregation of known patterns. By quibbling over how accurate a pattern name is and renaming it, what's known and understood appears to be new and must be learned. This is the reason we have naming conventions for code. IoC is not only well known, to us at least, it's clever, original, and hard to forget. In other words a great name. Dependency Injection may be more accurate but it's lifeless technocrat-speak that sounds like countless other unmemorable terms, a lousy name.

    Now I'll go read his article.

    Gary
  3. Please stop renaming patterns![ Go to top ]

    In the case of Value Object... it was the J2EE Patterns group that messed up. The term Value Object had been in use for many years to describe immutable "primitive-type" objects. Fowler just pointed it out and pushed to have the J2EE Value Object pattern renamed to something more appropriate to avoid confusion. J2EE Patterns group eventually renamed the pattern to Transfer Object even though everybody refers to them as Data Transfer Objects... go figure.
  4. Please stop renaming patterns![ Go to top ]

    Gary,

    I wasn't too thrilled about Martin proposing to rename IoC either. However, the IoC name won't disappear: I met with Paul and Aslak from Pico last week, and we agreed on a classification of types of IoC. "Dependency injection" is a particular kind of IoC: the type of push IoC offered by Spring and Pico where the container resolves dependencies without any need for lookup in application code. (As opposed to the Avalon flavour of IoC where the container invokes a callback method to tell the component to look up its dependencies.)

    I think "dependency injection" is a fairly good name for this type of IoC. (I actually coined the "dependency" part of it, so I guess I would.) And I'm glad to see the end of "Type 2" and "Type 3".

    I was particularly pleased to get agreement on an IoC classification between Spring and Pico teams. We should each be publishing that soon.

    The really good thing is that I think this will help to ensure interoperability of components between Spring and Pico--and potentially, other containers. One of the key benefits of IoC is that it can avoid lockin by minimizing or eliminating dependencies on a specific container API.

    Regards,
    Rod
  5. Please stop renaming patterns![ Go to top ]

    Rod,

    so you're saying, instead of type 2, type 3 IoC types there is going to be meaningful names? That should be more easy to comprehand ;-)

    Btw, do you know who came up with "type numbers" for IoC originally?

    Regards,
    Dmitriy.
  6. Paul Hammant came up with the terms IoC 1,2,3 while we were talking about how to distinguish different kinds of IoC. We will try to avoid using the numbered terms in the future.

    While IoC is starting to become a well known pattern name, its purpose and strength not well understood.

    I first heard about IoC about a year and a half ago. It took me a while to understand what it was. As one of the creators of PicoContainer, I have also followed various discussion threads on the Internet, and seen how confused other people are too.

    Much of this confusion could have been avoided if someone had come up with a better name before. The pattern name "Dependency Injection" that Martin Fowler has coined in his article will hopefully lead to less confusion about the pattern and lead to more widespread adoption of the pattern.
  7. I've found out about the concepts of IoC a little more then a year ago from Rod's book - interface21 BeanFactory back then ;-)

    Dmitriy.
  8. Please stop renaming patterns![ Go to top ]

    Renaming is not something I do lightly, indeed coming up with pattern names is one of the hardest and most contentious parts of pattern writing.

    I suggested a new name for IoC for the reasons given in the article. The name 'dependency injection' was agreed in a discussion last week where I wasn't there, although I suspect it was influenced by the name 'service injector' which I'd used in an earlier draft of the article. With both springies and picoites agreeing on this name, I was happy to go with it. Using type numbers is really confusing and I will always look for names as an alternative.

    As Chris points out, the value object vs DTO was a more complicated issue, which I tried to explain in the book.

    The most difficult rename I did was DAO -> Table Data Gateway. The primary reason for this was due to the meaning DAO carries in the Microsoft community. Here a name that works well for the java community would not work so well in the Microsoft one.
  9. Please stop renaming patterns![ Go to top ]

    Dear Martin

    'Table Data Gateway'? That's just ludicrous! It sounds like some sort of milspec speak that's just emanated from the bowels of the Pentagon. Your technical ideas are really sound, but man, you're butchering the language. ;-)

    regards,
    Scot.
  10. Please stop renaming patterns![ Go to top ]

    'Table Data Gateway'? That's just ludicrous!


    Read the book - you will understand... there is a distinction between a number of "gateways".

    I personally found those names to be quite illuminating - even though I already understood the material. Often a different name for something - a different metaphor, a different angle - can lead to a better understanding - even to something you already think you know.

    -Nick
  11. Please stop renaming patterns![ Go to top ]

    Nick

    Still doesn't mean it doesn't sound like some Pentagon bureaucrat rambling on about 'colateral damage' at a press conference. Lots of technical jargon is like that, granted, and despite the need for jargon in any technical sphere, it doesn't mean that it _has_ to be like that. No matter how logical it might seem (nearly all jargon is logical from the position of the user of it).


    scot.
  12. Please stop renaming patterns![ Go to top ]

    |
    |Still doesn't mean it doesn't sound like some Pentagon bureaucrat rambling on
    |about 'colateral damage'
    |

    Its the exact opposite of your example.

    In your case, someone is using Jargon to obfuscate the (gory) details.

    In Martin's case, he is using a more verbose plain-english means to describe some Jargon (ioc).

    (Anyway, I always thought IOC was the International Olympic Committe... "..and the winner is ... Syn-deney!")

    Whatever.

    -Nick
  13. pattern jargon[ Go to top ]

    Also not to imply that Martin is the only, or even the worst, culprit in this area. it's just that the topic was already raised. ;-)
  14. DAO pattern rename[ Go to top ]

    The most difficult rename I did was DAO -> Table Data Gateway. The primary reason for this was due to the meaning DAO carries in the Microsoft community.


    Martin is absolutely right on this one. Sun appropriated the name of a well-known Microsoft API and used it for a completely different creature. I rememeber a few years ago, when I first explained the DAO pattern to some clients new to J2EE, many protested that we should not be using Microsoft names in a Java product!
  15. Rename was absolutely needed![ Go to top ]

    I completely agree with the need to rename the current use of IoC name, for those who already used IoC prior to these little containers coming around the term "IoC Container" itself is redundant (as no container can exist without some form of IoC). I completely agree with the "my car has wheels so it's special" example.

    Well done, and Dependency Injection is a good name.
  16. Craig,

    What tool(s) do you guys prefer to use to persist/restore JavaBean state? I've worked with several to read configuration state from config files -- Digester and Spring, for example - but less to write that state back out.

    Thanks,
    Keith
  17. Hi,
    I've used Castor in one project. It suited our team well. XStream looks good, too.
    Regards,
    Stefan
  18. Just went to a presentation of JDO, and SolarMetric's KDO - cool stuff, check see http://www.solarmetric.com/
  19. Craig,

    >
    > What tool(s) do you guys prefer to use to persist/restore JavaBean state? I've worked with several to read configuration state from config files -- Digester and Spring, for example - but less to write that state back out.
    >
    > Thanks,
    > Keith

    If you look at the Tomcat solution to this (for updating server.xml files in the Admin App) you're going to make me blush :-) ... it is a somewhat hacked together mishmash in Tomcat 4.1. Remembering a couple of things helps make it clear:

    * The object hierarchy inside Catalina pretty much
      exactly matches the nesting of XML elements in server.xml.

    * Because we used setter injection to configure all
      the beans, we could simply call all the property
      getters to find out how the object is *currently*
      configured.

    So, we've got a little gadget that walks the entire component tree inside Catalina, asks each bean for all it's properties, and writes them out to a corresponding XML element (minus a hard coded list of exceptions that are not configured from the server.xml file). It's not pretty, but it works.

    The Tomcat 5 folks have talked about delegating the responsibility of persisting this sort of thing to the JMX MBeans that are now a built-in capability (they were an optional add-on for Tomcat 4). I haven't been closely tracking what's going on here, since I haven't been active in Tomcat development for a while.

    One library that I would look at for persisting trees of JavaBeans is Betwixt, which is in Jakarta Commons. It focuses on JavaBean->XML transitions, and is sort of a mirror twin of Digester (which does the XML->JavaBean path). Indeed, the example scenario shipped with Betwixt uses the same RSS-based model beans that the Digester example app uses, so you can do round trip sorts of things with it.

    Many other libraries that aim at supporting either Bean->XML or Bean->XML->Bean exist as well. A relative newcomer in the open source space is XmlBeans, which is under Incubation at Apache.

    The Java standard approach to this sort of thing is the Java APIs for XML Binding (JAXB). Among other places, you can get a usable version of this in the Java Web Services Developer Pack (JWSDP) from Sun.

    I confess that I haven't had a recent need to do this sort of stuff myself, so I'm not really up to date on recent changes in what's available. But the above paragraphs point at where I'll start the next time I have such a need.

    Craig
  20. I don't see any problems in make things clear. The name "Dependency injection" makes me think about IoC from another point of view, where you pull objects dependecy in a decoupled form.
  21. Please stop renaming patterns![ Go to top ]

    I think his pattern names are accurate. and nothing is wrong with renaming if the change is for the better. maybe if you don't want the names to ever change we could generate a guid for the name ;)
  22. Dependancy Injection.

    You could argue that because an externally created Object is made available
    that that is a 'Dependancy Injection'

    You could also argue, that as you no longer are required to Construct the Object, that you are performing a 'Dependancy Extraction' (tm).

    Not clear at all.
  23. Dependency Injection & Plugins[ Go to top ]

    Hi,

    Couldn't the Plugins pattern achieve what you want out of Dependency Injection?
    What are the differences and what make one use Dependency Injection instead of Plugins?

    Thanks,
    Ed
  24. Push vs. Pull = EJB[ Go to top ]

    Thanks for the nice article. Especially for the comparison between the "pull" Service Locator and "push" Dependency Injection.

    After reading this article I'm more sure that J2EE with EJB is the way to go. Within EJB you have everything you need to realize both pull and push mechanism. And one biggest advantage of "EJB lightweight container" to compare with other "lightweight containers" is that the application developers, who use and combine those components/services in their application are also indpendent from the containers. This is not the case if you use those other lightweight containers (see the examples how to config and use the components). So, the components are implementation independent (MovieLister and MovieFinder) but the application depends on the way how each containers work. With EJB you have both independencies ;-)

    What I mean with "EJB lightweight container" if you just use local objects (stateless and stateful SB) and JDO for persistence.

    Cheers,
    Lofi.
    http://www.openuss.org
  25. Push vs. Pull = EJB[ Go to top ]

    Lofi,

    Frankly, I believe that you completely missed the point.

    > Within EJB you have everything you need to realize both pull and push mechanism.

    EJB with JNDI as service locator is pull-only - there are no means at all to realize a push mechanism. The best you can achieve is hosting a lightweight container within an EJB implementation class (which is what you can do with Spring's EJB support classes), but then you're essentially delegating to a POJO layer within your EJB rather than injecting dependencies into your EJB instance.

    > And one biggest advantage of "EJB lightweight container" to compare with other "lightweight containers" is that the application developers, who use and combine those components/services in their application are also indpendent from the containers.

    You're independent from the EJB container implementation, but you depend on an EJB container in the first place. The point of a "lightweight container" is that a component can be either managed by such a container or used as a plain manually configured POJO. Such a component does not implement any special interfaces, and does not have to be deployed to a server - it is just a plain Java object that needs some references to collaborating objects.

    > So, the components are implementation independent (MovieLister and MovieFinder) but the application depends on the way how each containers work. With EJB you have both independencies ;-)

    You are free to set such components up in a few lines of Java code, without any container involved. This allows you to reuse your components in *any* Java environment, not just a J2EE server. Even the containers themselves are so lightweight that they can easily be hosted in a standalone application or an applet. With EJB, you depend on an EJB container: The choice between multiple implementations is delusive here, as you're restricted to server environments.

    Juergen
  26. Push vs. Pull = EJB[ Go to top ]

    After reading this article I'm more sure that J2EE with EJB is the way to go. Within EJB you have everything you need to realize both pull and push mechanism.
    How do you do dependency injection with EJB? Each EJB has to look up other EJBs via JNDI. This is pull, via a complex lookup API.

    And one biggest advantage of "EJB lightweight container" to compare with other "lightweight containers" is that the application developers, who use and combine those components/services in their application are also indpendent from the containers. This is not the case if you use those other lightweight containers (see the examples how to config and use the components). So, the components are implementation independent (MovieLister and MovieFinder) but the application depends on the way how each containers work. With EJB you have both independencies ;-)
    Well it's the first time I've heard anyone refer to an EJB container as "lightweight." And your argument is wrong.

    IoC components seldom need to depend on the "way each container works". In fact, they're normally just POJOs, without anything special in them. The point of defining this as a pattern is that it's not product-specific. You can use a component with Setter Injection or Constructor Injection in Spring or Pico--probably HiveMind and some other products as well. You can easily use it outside any container, or in a JUnit test. This pattern minimizes or eliminates dependencies on a container.

    With EJB you have both dependence on a particularly invasive API and dependence on at least two far more complex config files: ejb-jar.xml and the proprietary descriptor. You can't use an EJB outside the container.

    E.g. an EJB looks up another EJB via a JNDI lookup that won't work outside an app server and is difficult to unit test. With Setter Injection, a dependency on another component is expressed via a simple method with a signature like void setCollaborator(Collaborator c). Where's the dependency on a particular container in that? As Craig pointed out in this thread, it uses a standard Java pattern. With Constructor Injection, the dependency is expressed in the constructor: also standard Java.

    Given the choice between a Java mechanism and an EJB/JNDI mechanism, I'll use Java every time.

    Also, true lightweight containers like Spring/Pico can be used in a wide variety of contexts, such as Swing standalone client. So they can't be directly compared to an EJB container. In some ways lightweight containers complement EJB also, making it easier to use EJB. Many Spring users use our convenience EJB implementations that use a Spring IoC container to manage finer-grained POJOs behind a coarser-grained EJB facade.

    Regards,
    Rod
  27. What is the definition of a container?[ Go to top ]

    Can somebody provide a definition of "Container". I understand all the EJB runtime environments are containers, because they manage bean instance pooling, lifecycle, transaction context, and security, but a singleton builder or factory class that dishes out instances of concrete classes based on a configure file is also a container? How "light-weight" can a container be?
  28. What is the definition of a container?[ Go to top ]

    Can somebody provide a definition of "Container". I understand all the EJB runtime environments are containers, because they manage bean instance pooling, lifecycle, transaction context, and security, but a singleton builder or factory class that dishes out instances of concrete classes based on a configure file is also a container? How "light-weight" can a container be?


    These containers do more than object creation. They both (I believe) also offer optional lifecycle Interfaces (a good spot for standardization!) to get lifecycle event callbacks. They also manage the objects they create, and can use them to fulfill dependencies on future objects. You can also nest these containers for fallback, for instance request scope -> session scope -> application, and will manage these lifecycles appropriately.
  29. What is the definition of a container?[ Go to top ]

    So, the light-weightness of these "containers" compared to EJB containers is that they don't manage TX and security, and they allow the use of POJO's. I would argue that in my app I do need the ability to do declarative TX management (although I don't care about security), and I don't mind creating the bean instance class and let XDoclet take care of the rest. Then what do I gain from these "light-weight containers"? I got both "push" and "pull" instead of just "pull"? What's the big deal about "push"? Does "push" make my app that much more losely coupled?
  30. What is the definition of a container?[ Go to top ]

    Spring does have declarative transaction management afaik
  31. What is the definition of a container?[ Go to top ]

    Spring does have declarative transaction management afaik

    If that's the case, is Spring still a "light-weight container"? Why do I have to deal with a proprietary "container" and its "deployment descriptor", i.e, the XML config file?
  32. What is the definition of a container?[ Go to top ]

    Spring does have declarative transaction management afaik

    >
    > If that's the case, is Spring still a "light-weight container"? Why do I have to deal with a proprietary "container" and its "deployment descriptor", i.e, the XML config file?


    It's light weight because of the component model. In Spring your components are just JavaBeans. In Pico they're POJOs with dependencies in the constructor. Just plain Java classes. The other services, such as transaction demarcation, can be added independently using AOP in Spring, WITHOUT HAVING TO MAKE YOUR CLASS ANYTHING MORE THAN A PLAIN JAVA OBJECT. This is the important part.

    When you go to unit test your components, you don't have to start up a container at all, you just Mock up the dependencies and set them into your component, then test that it does what it says it's going to do. These unit tests are FAST. Go and write a couple hundred Cactus tests to test your EJBs and tell me how fast THEY run.

    What's more, since there's no complex component spec to satisfy, you don't need the component Interface or Home Interface... You don't need XDoclet to create deployment descriptors for you. All of this improves productivity and makes your system simpler. These are cumulative benefits over the lifetime of your project that add up to big wins in terms of having more time to work on the actual code you're getting paid to write, rather than jumping through the hoops required by spec writers over at the JCP.

    None of the services provided by Local SLSBs are that complicated, and if they can be provided by another, faster to develop framework, then why wouldn't you use it?
  33. When you go to unit test your components, you don't have to start up a container at all, you just Mock up the dependencies and set them into your component, then test that it does what it says it's going to do.


    Or you could bootstrap the entire container in one single line of code in any Java environment (JUnit test case for instance), and it's pretty fast.

    Spring container:
    ApplicationContext ctx = new ClassPathXmlApplicationContex("/testContext.xml");

    To mee it's a pretty "lightweight container" ;-)

    Regards,
    Dmitriy.
  34. As Jason says, the lightweightness lies in hosting POJOs, and in the support for runtime AOP proxies - without explicit deployment steps like in the EJB Session Bean case. Developing such an application is straightforward: simply recompile and restart, instead of needing to redeploy components to a server. The difference is somewhat similar to POJO persistence with Hibernate/JDO versus Entity Beans, in this case concerning the service (Session Bean) level.

    For example, if you've got a loosely coupled POJO web app on Tomcat and need transactional services for a set of business objects, you don't have to refactor your entire middle tier into local EJBs and move to a full J2EE server: Instead, you can simply define a proxy per affected business object, leaving the rest of the application as-is. Clients simply go through the respective proxy instead of accessing the target business object directly.

    Many EJB usages are in fact about local SLSBs for declarative transaction management. It can be argued that this is not what EJB was originally intended for, as EJB was created as distributed component model with remote transaction propagation - this is what it remains good at. But for adding aspects like transactions to fine-grained local services, I consider an IoC plus AOP model for POJOs much more appropriate.

    It has already been said that you can develop truly distributed applications with remote EJBs and still leverage Spring for the fine-grained implementation layer behind your coarse-grained EJB facades, and for easy client access to EJBs. For simpler remoting means that do not involve remote transaction propagation or session state, Spring offers support for various remoting protocols like Hessian, Burlap, JAX-RPC, RMI invoker, and plain RMI.

    A very important point is that business logic implemented as POJOs, be it Spring-managed or not, can be reused in *any* Java environment: applets, standalone applications, custom server processes, EJB implementations, web applications - in sharp contrast to EJB's dependency on a J2EE server. A local DataSource and declarative transactions via the JDBC or Hibernate transaction strategy will work in any environment (that has access to a database).

    Note that you can still leverage J2EE services *if* deployed on J2EE: Combine the very same business object with a JNDI DataSource and the JTA transaction strategy there, without any need to change application code. And on Tomcat, combine it with the JDBC transaction strategy again - still with declarative transactions. This illustrates a major benefit of lightweight containers: They seamlessly adapt to any environment, allowing to scale up as well as down.

    Juergen
  35. As stated by jelmer, Spring does have declarative transaction management, however it depends on the implementation provided by for instance the server you're running in. First of all you don't have to use it. Also configuration files are suitable for use in different servers. Spring's TX managment can be used not in combination with some kind of special interface, but with any POJO.
  36. As stated by jelmer, Spring does have declarative transaction management, however it depends on the implementation provided by for instance the server you're running in. First of all you don't have to use it. Also configuration files are suitable for use in different servers. Spring's TX managment can be used not in combination with some kind of special interface, but with any POJO.



    Spring TX management does not depend on the App Server. It has multiple TX management strategies, including local tx's on a single JDBC connection, Hibernate tx's, and JTA. JTA is the only one which will use anything from the App Server, and it's a standard part of the spec, not App Server dependent.
  37. Spring TX management does not depend on the App Server. It has multiple TX management strategies, including local tx's on a single JDBC connection, Hibernate tx's, and JTA. JTA is the only one which will use anything from the App Server, and it's a standard part of the spec, not App Server dependent.


    Excuse me, that was exactly what I was trying to say...
  38. What is the definition of a container?[ Go to top ]

    You forget "remoteness" in addition to security and txn. mgmt.

    Does Spring or Pico enable the POJOs to be remotely invoked ?
  39. Remoting[ Go to top ]

    Spring provided remote access of POJOs with RMI, Hessian/Burlap and JAX-RPC, the latter since M4. The recently added JPetstore example show how to use those features.
  40. Remoting[ Go to top ]

    Man, not one of my best typing-days... provided should be provides, show should be shows...
  41. Remoting[ Go to top ]

    Spring provided remote access of POJOs with RMI, Hessian/Burlap and JAX-RPC, the latter since M4. The recently added JPetstore example show how to use those features.

    What's the impact of this feature on the easiness of Unit testing, which was cited as a big differentiator to EJB containers?

    At the end of the day, adding all the features an EJB container supports does not seem to make Spring any "lighter" weight. If in order to use JTA I have to use Spring with an app server, why bother with Spring? My biggest problem is that EJB is a standard, Spring and Pico are proprietary. When I deal with OSS proprietary stuff, I only want to see a dominant offering, like Hibernate in the O/R space.
  42. Remoting[ Go to top ]

    What's the impact of this feature on the easiness of Unit testing, which was cited as a big differentiator to EJB containers?

    There's no real impact here. Testing your POJO's can be done without actually doing remote calls (provide a app.context for testing purposes that doesn't have for instance the RmiProxyFactoryBean, or manually instantiate the beans). Also, you don't have to implement anything special to make it work.

    At the end of the day, adding all the features an EJB container supports does not seem to make Spring any "lighter" weight. If in order to use JTA I have to use Spring with an app server, why bother with Spring? My biggest problem is that EJB is a standard, Spring and Pico are proprietary.

    As Jason stated above, Spring does not need an application server in order to do transaction management. The thing is: you don't have to use everything. It's there, and if you don't use it, it won't make your application (and the framework) any more heavy-weight.
  43. Remoting[ Go to top ]

    At the end of the day, adding all the features an EJB container supports does not seem to make Spring any "lighter" weight. If in order to use JTA I have to use Spring with an app server, why bother with Spring?


    Because Spring allows your business objects to not *depend* on an app server but still be able to *leverage* J2EE services if they are available. Being able to test your business objects in standalone test suites and to reuse them in standalone applications is a major benefit. In particular, you can choose a simple development environment like Tomcat and JDBC transactions, still being able to seamlessly move to e.g. WebLogic and JTA transactions for production.

    Regarding JTA in particular: Many applications just access one database - why bother with JTA there in the first place? The JDBC transaction strategy works nicely in any environment, be it plain Tomcat or a standalone application. It even allows to set per-transaction isolation levels in a simple and straightforward way. And if your business object ever needs to participate in a JTA transactions, it can still seamlessly do so.

    Juergen
  44. Remoting[ Go to top ]

    Regarding JTA in particular: Many applications just access one database - why bother with JTA there in the first place?

    Well, unfortunately, we have legacy systems that need to be integrated together using JMS/MDB. To me JTA is a must.

    And if your business object ever needs to participate in a JTA transactions, it can still seamlessly do so.

    OK, I will take your word for it, but I still need to see some examples how this is done in Spring.
  45. Remoting[ Go to top ]

    Regarding JTA in particular: Many applications just access one database - why bother with JTA there in the first place?

    >
    > Well, unfortunately, we have legacy systems that need to be integrated together using JMS/MDB. To me JTA is a must.

    Then I recommend JTA as transaction strategy :-) I didn't intend to discredit JTA by any means; I just outlined that JTA is often applied to a single database, not requiring distributed transactions in the first place.

    I consider JTA as the most important service that a "full" J2EE server offers, alongside solid JMS messaging. That's where WebLogic and WebSphere really provide value, IMO. After all, EJB is just one way to access those services but by no means the only one. In such a scenario, I believe that Spring offers compelling alternatives for local access to your J2EE server's transaction subsystem, still leveraging the full power of its fundamental services.

    > And if your business object ever needs to participate in a JTA transactions, it can still seamlessly do so.
    >
    > OK, I will take your word for it, but I still need to see some examples how this is done in Spring.

    For a start, consider the article at http://www.hibernate.org/110.html (in particular sections 6 and 7). For a working example with full source code, have a look at our JPetStore (which features both a single database and a separate main/order database configuration), or Petclinic (illustrating single database access via Hibernate and JDBC). Both are included in the Spring distribution.

    Juergen
  46. Remoting[ Go to top ]

    Spring provided remote access of POJOs with RMI, Hessian/Burlap and JAX-RPC, the latter since M4. The recently added JPetstore example show how to use those features.

    >
    > What's the impact of this feature on the easiness of Unit testing, which was cited as a big differentiator to EJB containers?
    >
    > At the end of the day, adding all the features an EJB container supports does not seem to make Spring any "lighter" weight. If in order to use JTA I have to use Spring with an app server, why bother with Spring? My biggest problem is that EJB is a standard, Spring and Pico are proprietary. When I deal with OSS proprietary stuff, I only want to see a dominant offering, like Hibernate in the O/R space.



    The light weight comes from the limitations and requirements your component model places on your code. EJBs are heavy weight because of the 2 extra Interfaces, the 2 deployment descriptors, and the requirement to run in a container for testing.
  47. Remoting[ Go to top ]

    At the end of the day, adding all the features an EJB container supports does not seem to make Spring any "lighter" weight. If in order to use JTA I have to use Spring with an app server, why bother with Spring?
    The point is that EJB folds all these features into one great, inflexible, ball of functionality. Yet you typically don't want them all, and you don't want them to complicate the object model. Spring treats the provision of services such as tx mgt and remoting as largely distinct from the core object model: aspects, or (for remoting) facades. With Dependency Injection you can ensure that that core object model is clean and not full of lookup and other API specifics. So you apply just those services you want. E.g. you want declarative tx mgt without remoting: you don't need the Spring remoting packages.

    Btw, you can have JTA without EJB, in WebLogic Express or other products.

    My biggest problem is that EJB is a standard, Spring and Pico are proprietary. When I deal with OSS proprietary stuff, I only want to see a dominant offering, like Hibernate in the O/R space.
    The point is that components written for these containers can be entirely portable in many cases because with Dependency Injection they use Java language features, which always trump a specific API such as EJB.

    The point about domination is a little odd anyway. Wouldn't Microsoft argue that they can provide a dominant solution instead of all those different application servers in the "fragmented" J2EE space.

    Anyway, how do you think Hibernate became dominant? Overnight? I seem to remember Gavin getting attacked here a couple of years ago for coming up with "yet another persistence API". Yet I think there are a lot of people now grateful he persevered.
  48. You forget "remoteness" in addition to security and txn. mgmt.

    >
    > Does Spring or Pico enable the POJOs to be remotely invoked ?

    Spring allows you to separate the decisions to use declarative transactions and to make your components available for remote calls. It supports Axis, Hessian and Burlap as remote technologies with or without declarative transaction support. As mentioned earlier transactions can be managed by Spring, Hibernate or JTA without having to deal with the remotnes aspect. Spring also supports EJBs if you do decide to combine both. It just gives you more options.

    Thomas
  49. You forget "remoteness" in addition to security and txn. mgmt.

    >
    > Does Spring or Pico enable the POJOs to be remotely invoked ?

    Are you really remoting your SLSB's? Most people aren't, because it's terribly inefficient and there's not that many cases where it makes sense.

    If you have one of those (rare) cases, SLSBs are useful, but you still need something to organize your code behind the EJB (which should just be a facade, with no real code in it)...
  50. No, I am not.

    Since the thread was trying to compare lightweight containers like Spring and Pico to "heavyweight" servers, I was comparing the things heavy servers can do (distributed txns via IIOP, for example)
  51. Push vs. Pull = EJB[ Go to top ]

    <juergen>
    EJB with JNDI as service locator is pull-only - there are no means at all
    to realize a push mechanism. The best you can achieve is hosting a lightweight
    container within an EJB implementation class (which is what you can do with
    Spring's EJB support classes), but then you're essentially delegating to a
    POJO layer within your EJB rather than injecting dependencies into your EJB
    instance.
    </juergen>
    OK, let's make this straight. It was my mistake to compare apples and oranges ;-)

    The main problem is that to make MovieLister independent of the implementation
    of MovieFinder, right? The solution is to add an Assembler class which creates
    the MovieFinderImpl to decouple the implementation from the MovieLister class.

    In my understanding from the article the difference between push and pull is:
    - Push (Dependency Injection): I should never use the implementation class
      of MovieFinder within the MovieLister. Always use the interface. I have 2
      ways to reach this: pass the implementation through the "constructor" or
      through a "setter method". See fig. 2. Therefore the MovieLister only depends
      on the interface MovieFinder.
    - Pull (Service Locator): I should never use the implementation class
      of MovieFinder within the MovieLister. Always use the interface (the same as above).
      But in this case I use directly a Service Locator to get the implementation of the
      MovieFinder *within* the MovieLister. In this *abstraction level* it has nothing to
      do with JNDI direcly. See fig. 3. Therefore the MovieLister will depend
      on the interface MovieFinder and the ServiceLocator.

    The most interesting part is actually the Assembler class, in which the configuration
    will be done (What kind of implementation class should be used for the MovieFinder
    interface, etc.). You can use "code" or "XML" as the example showed us to achieve
    this. In my opinion both are general extended patterns and have at first nothing to do
    with all the products (all the containers). Both patterns are extended from
    "Interface" and "Factory" patterns. Just simple as that.

    The point now is how we can "assembly" and "deploy" those services/components?
    For this purpose we have the containers:
    - lightweigt containers (pico, avalon, spring) and
    - EJB containers
    They help you to handle the configuration (Assembler) part, to put all those
    services/components to work for you. And in both container types we use actually
    the same mechanism to find the correct implementation:
    - XML + ctx... in spring
    - XML + JNDI ctx in EJB container
    And surprisingly both are totally the same ;-)

    I won't mix the ServiceLocator pattern in general with JNDI lookup (different abstraction
    level). JNDI lookup is only *one* possible implementation of ServiceLocator and those
    lightweight containers also use the same mechanism. The dependency to the container
    does not come in both patterns above, but comes in the assembly part.

    Back to my opinion: you can surely implement your component and using
    push or pull *pattern* as I understand them above within an EJB container.

    <rod>
    Well it's the first time I've heard anyone refer to an EJB container as "lightweight."
    And your argument is wrong.
    Also, true lightweight containers like Spring/Pico can be used in a wide variety of
    contexts, such as Swing standalone client. So they can't be directly compared to an
    EJB container. In some ways lightweight containers complement EJB also, making it
    easier to use EJB. Many Spring users use our convenience EJB implementations that
    use a Spring IoC container to manage finer-grained POJOs behind a coarser-grained
    EJB facade.
    </rod>
    ;-) I said "lightweigt" because nowadays you can also use an EJB container and
    Servlet container in a wide variety contexts such as Swing standalone client.
    Example: Eclipse uses embedded Tomcat container to show the help files and
    some dialogs (OK, Eclipse is not a Swing application but a standalone SWT
    application ;-)). Have you seen - at least the main page of OpenEJB? Here
    you are:
    "OpenEJB comes with fast, lightweight EJB Servers for both Local and Remote access.
    That's right, deploy your EJBs into the container system, then just start the Remote
    EJB Server from the command line! Or, put OpenEJB in your class path and use it as
    an embedded library through the Local EJB Server."

    Nowadays I can also embedded JOnAS EJB container within my *standalone* Swing application
    without any problems and very easy. Just write a simple JOnAS service to run your
    Swing application automatically.

    I'm not saying that we don't need any lightweight containers like spring or pico, but
    I feel that it could be "dangerous" to let all the developers think that they should
    only use those lightweight containers for any purpose. IMO, if you want to write
    component-based infrastructure systems like Web container, EJB container, Mail container,
    Portal server you should use avalon, pico, etc. But if you want to write component-based
    business systems (domain oriented) you should use EJB container.

    Cheers,
    Lofi.
  52. Push vs. Pull = EJB[ Go to top ]

    Nowadays I can also embedded JOnAS EJB container within my *standalone* Swing application

    > without any problems and very easy. Just write a simple JOnAS service to run your
    > Swing application automatically.

    I consider embedding an EJB container in a standalone application a perversion: EJB was never intended to be used this way. This clearly shows an obsession with EJBs where POJOs are so much more appropriate. An IDE with integrated Tomcat is a totally misleading example. A standalone business application is a different matter in that it should not mess around with embedding *server* infrastructure that was not meant to be used in a client in the first place.

    Give it a try and compare developing a Swing application with a Spring-managed middle tier on the one hand and with an embedded EJB container on the other hand. Let's see if you'll come back and keep insisting that the EJB solution is equally clean and equally easy to develop with. Try the same with a typical web application, on the one hand with Tomcat and Spring and on the other with Jonas and EJB. It would be a fair comparison: after all, it's about similar services.

    (Note that I'm just talking about the use of local Session Beans above. Truly distributed applications with remote EJBs are a different matter, although they can still benefit from Spring, as has already been outlined before.)

    Juergen
  53. Push vs. Pull = EJB[ Go to top ]

    <quote>
    Give it a try and compare developing a Swing application with a Spring-managed middle tier on the one hand and with an embedded EJB container on the other hand. Let's see if you'll come back and keep insisting that the EJB solution is equally clean and equally easy to develop with. Try the same with a typical web application, on the one hand with Tomcat and Spring and on the other with Jonas and EJB. It would be a fair comparison: after all, it's about similar services.
    </quote>
    EJB especially the J2EE solution is surely very clean.

    Finding components and other stuffs:
    The main concept is very simple. You need something (components EJBs, datasources, mailservice, etc.)? Go and find it through JNDI. That's it, and this is just as the same as in Spring (without JNDI but it also uses context as the example shows this - correct me if I'm wrong).

    Creating components:
    Interface and Factory based patterns (see my last thread). Very clean, no doubt.

    Whether Tomcat + Spring are easier than JOnAS + EJB? This is difficult to answer ;-) since we need a person who doesn't know both technologies. One for sure, J2EE and EJB are not complicated and can be very easy if you want to learn...

    Cheers,
    Lofi.
  54. Push vs. Pull = EJB[ Go to top ]

    EJB especially the J2EE solution is surely very clean.

    >
    > Finding components and other stuffs:
    > The main concept is very simple. You need something (components EJBs, datasources, mailservice, etc.)? Go and find it through JNDI. That's it, and this is just as the same as in Spring (without JNDI but it also uses context as the example shows this - correct me if I'm wrong).
    >

    You are wrong. You have missed the point of the push vs. pull discussion. You're talking about pulling your dependencies from a registry. This is the service locator pattern discussed in the article. In Spring and Picocontainer, dependencies are resolved and provided to the component when the component is instantiated and is all done by the container with no code in your component.

    > Creating components:
    > Interface and Factory based patterns (see my last thread). Very clean, no doubt.
    >
    > Whether Tomcat + Spring are easier than JOnAS + EJB? This is difficult to answer ;-) since we need a person who doesn't know both technologies. One for sure, J2EE and EJB are not complicated and can be very easy if you want to learn...
    >

    Yes, well, I think we've all used EJB so there's nothing to learn there. We've been through enough pain with them to be looking for something better.

    > Cheers,
    > Lofi.
  55. Push vs. Pull = EJB[ Go to top ]


    > The point now is how we can "assembly" and "deploy" those services/components?
    > For this purpose we have the containers:
    > - lightweigt containers (pico, avalon, spring) and
    > - EJB containers
    > They help you to handle the configuration (Assembler) part, to put all those
    > services/components to work for you. And in both container types we use actually
    > the same mechanism to find the correct implementation:
    > - XML + ctx... in spring
    > - XML + JNDI ctx in EJB container
    > And surprisingly both are totally the same ;-)

    Not at all.. In the Spring / Pico case, you have no lookup code in your classes. No reference to any kind of ServiceLocator. In your tests for an EJB case you have to set up a container, in the lightweight case, you don't. Not the same at all.

    >
    > I won't mix the ServiceLocator pattern in general with JNDI lookup (different abstraction
    > level). JNDI lookup is only *one* possible implementation of ServiceLocator and those
    > lightweight containers also use the same mechanism. The dependency to the container
    > does not come in both patterns above, but comes in the assembly part.
    >
    > Back to my opinion: you can surely implement your component and using
    > push or pull *pattern* as I understand them above within an EJB container.
    >

    How exactly? If your component is an EJB, how do you push something into it? All of the lifecycle comes through the EJB itself, you don't get hooks into what the container should do while instantiating the instance.


    > ;-) I said "lightweigt" because nowadays you can also use an EJB container and
    > Servlet container in a wide variety contexts such as Swing standalone client.
    > Example: Eclipse uses embedded Tomcat container to show the help files and
    > some dialogs (OK, Eclipse is not a Swing application but a standalone SWT
    > application ;-)). Have you seen - at least the main page of OpenEJB? Here
    > you are:
    > "OpenEJB comes with fast, lightweight EJB Servers for both Local and Remote access.
    > That's right, deploy your EJBs into the container system, then just start the Remote
    > EJB Server from the command line! Or, put OpenEJB in your class path and use it as
    > an embedded library through the Local EJB Server."

    Riiight... and you're doing this? Probably not. Because if you're using EJB you're probably deploying on WLS / WAS / JBoss / Oracle / Orion and you don't want to test in a different container or have to maintain deployment descriptors for both your real container and OpenEJB.

    >
    > Nowadays I can also embedded JOnAS EJB container within my *standalone* Swing application
    > without any problems and very easy. Just write a simple JOnAS service to run your
    > Swing application automatically.
    >
    > I'm not saying that we don't need any lightweight containers like spring or pico, but
    > I feel that it could be "dangerous" to let all the developers think that they should
    > only use those lightweight containers for any purpose. IMO, if you want to write
    > component-based infrastructure systems like Web container, EJB container, Mail container,
    > Portal server you should use avalon, pico, etc. But if you want to write component-based
    > business systems (domain oriented) you should use EJB container.

    Based on what?

    >
    > Cheers,
    > Lofi.
  56. Push vs. Pull = EJB[ Go to top ]

    <quote>
    Not at all.. In the Spring / Pico case, you have no lookup code in your classes.
    </quote>
    Also not at all in EJB if you are using the 1. pattern. The dependency comes in the assembly part (see my thread before).

    <quote>
    In your tests for an EJB case you have to set up a container, in the lightweight case, you don't. Not the same at all.
    </quote>
    Why is that so complicated to setup a container? If you don't want to run your EJBs within the container for test, please take a look at this project:
    http://www.mockejb.org
    What is MockEJB? "MockEJB is a lightweight framework for running EJBs. MockEJB implements javax.ejb APIs and creates Home and EJBObject implementation classes for your EJBs."

    Anyway if you just use EJB LocalInterface you only have *one* JVM just as the same as your POJO application (or can you start your POJO application without a JVM? ;-)). So you just run your EJB container (one JVM) incl. your test at the same time.

    <quote>
    How exactly? If your component is an EJB, how do you push something into it?
    </quote>
    Please read my thread carefully => MovieLister, MovieFinder + Impl + Assembler.

    <quote>
    The light weight comes from the limitations and requirements your component model places on your code. EJBs are heavy weight because of the 2 extra Interfaces, the 2 deployment descriptors, and the requirement to run in a container for testing.
    </quote>
    1. Point:
    The 2 extra interfaces are based on good patterns. HomeInterface is "Factory" pattern and EJBObject is "Interface" pattern. So, I don't think that this is a bad idea. A good system is always interface based and uses factories. The deployment descriptors are also a good practice since you can change the behaviour of your component at the runtime. No problem with this... ;-)

    2. Point:
    Haven't you tried Model Driven Architecture (ex. AndroMDA)? With such a tool you just draw your conceptual class and generate those 2 interfaces automatically ==> easy + good practice. No problem at all. Using XDoclet you can generate the descriptors automatically...

    3. Point:
    For me it's not a big deal to run a container. JOnAS is for example implemented with service orientation in mind. So you can turn on and off the services you don't need to use and this makes it very fast to start.

    <quote>
    Based on what?
    </quote>
    EJBs was made with business applications in mind (IBM San Fransisco project). It's arrogant to say that those people who invented EJBs were stupid or so, as they had a long and huge experience in this area. Anyway, the idea of MessageDriven Beans (async. method invocation) is also important. How can you do MDB without an EJB container (or if you want, I would say running JVM)? Yes, you would use JMS at least and for this purpose you'll need a container (EJB, Web, JMS, J2EE container as a running JVM process) ;-)

    Cheers,
    Lofi.
  57. Push vs. Pull = EJB[ Go to top ]

    I'm going to skip the silliness about how testing in a container can be as lightweight as calling a POJO from a unit test... It's just plain wrong.


    > Also not at all in EJB if you are using the 1. pattern. The dependency comes in the assembly part (see my thread before).

    > <quote>
    > How exactly? If your component is an EJB, how do you push something into it?
    > </quote>
    > Please read my thread carefully => MovieLister, MovieFinder + Impl + Assembler.
    >

    Your first post and this post fail to show how I can have the dependency pushed into an EJB. You don't have control of the instantiation or lifecycle of an EJB except in the callback methods of the EJB itself, so unless you're putting Service Locator calls in your EJB you're not getting your impl from the assembler.


    > 1. Point:
    > The 2 extra interfaces are based on good patterns. HomeInterface is "Factory" pattern and EJBObject is "Interface" pattern. So, I don't think that this is a bad idea. A good system is always interface based and uses factories. The deployment descriptors are also a good practice since you can change the behaviour of your component at the runtime. No problem with this... ;-)
    >

    Ok.. but you then need a Business Interface for the EJB implementation and the Component Interface to both extend... with a lightweight container, you only need this Interface, not the other 2. You're also free to have a factory, if you need it, but you're not required to have one.

    What's the likelihood that you want to change transactionality of a component at runtime? Zero percent? Nonetheless, in a lightweight container, you can have either code based configuration or an external configuration file. ONE configuration file. Not TWO, one of which changes per deployment environment, causing more work.

    > 2. Point:
    > Haven't you tried Model Driven Architecture (ex. AndroMDA)? With such a tool you just draw your conceptual class and generate those 2 interfaces automatically ==> easy + good practice. No problem at all. Using XDoclet you can generate the descriptors automatically...
    >

    I have yet to see compelling arguments for MDA... We use XDoclet, and it comes with its own price, especially in terms of code/build/test cycle times. I prefer things I can just build quickly and test.

    > 3. Point:
    > For me it's not a big deal to run a container. JOnAS is for example implemented with service orientation in mind. So you can turn on and off the services you don't need to use and this makes it very fast to start.
    >

    Ok, no big deal for you. Just an extra 20 - 30 minutes per day. Times 20 people on a team. For a 6 month project. Now does it seem like a big deal?

    > <quote>
    > Based on what?
    > </quote>
    > EJBs was made with business applications in mind (IBM San Fransisco project). It's arrogant to say that those people who invented EJBs were stupid or so, as they had a long and huge experience in this area. Anyway, the idea of MessageDriven Beans (async. method invocation) is also important. How can you do MDB without an EJB container (or if you want, I would say running JVM)? Yes, you would use JMS at least and for this purpose you'll need a container (EJB, Web, JMS, J2EE container as a running JVM process) ;-)
    >

    Please.... EJB was a solution in search of a problem. They couldn't decide whether it was a component model, a remoting model, an O/R tool, a transaction manager, or what, so it does a little of all of these somewhat poorly and muddles them all together so you can't separate them to get better options.

    MDBs are the best part of the spec, definitely. Interesting how it was the part that came out AFTER people started using EJB and seeing the problems. EJB was a classic example of spec before experience.

    > Cheers,
    > Lofi.
  58. Push vs. Pull = EJB[ Go to top ]

    <Rod>
    > How do you do dependency injection with EJB? Each EJB has to look up other EJBs via JNDI. This is pull, via a complex lookup API.
    >
    <Rod>
    In the case of EJBs, you can still provide the config info like say the JNDI info of the dependency through the environment section in the EJB's deployment file and then use the service locator to pull that component right? So, why do we need to push the whole component itself( which as I understand is being done by specifying these dependencies in the proprietary mechanism of each of these contaners)?

    To make it a more generic question, why not just "inject" the config info and then use a service locator to get the dependent component instead of "injecting" the component itself as in spring f/w? In this case there are no assumptions on who handles the life cycle of the component otherwise there has to be a spring or pico container which will handle the lifecycle and push the dependent components right?

    Thanks,
    Shyam.
  59. Push vs. Pull = EJB[ Go to top ]


    > To make it a more generic question, why not just "inject" the config info and then use a service locator to get the dependent component instead of "injecting" the component itself as in spring f/w? In this case there are no assumptions on who handles the life cycle of the component otherwise there has to be a spring or pico container which will handle the lifecycle and push the dependent components right?
    >
    > Thanks,
    > Shyam.

    Go and read the article. These are exactly the tradeoffs discussed. One of the big benefits of Dependency Injection is testability, since you don't have to set up a context, etc. JNDI contexts are especially annoying to Mock. It's much easier to just create a Mock of your service and push that into the component being tested.
  60. Push vs. Pull = EJB[ Go to top ]

    Go and read the article. These are exactly the tradeoffs discussed. One of the big benefits of Dependency Injection is testability, since you don't have to set up a context, etc. JNDI contexts are especially annoying to Mock. It's much easier to just create a Mock of your service and push that into the component being tested.

    Thanks for the quick reply. I did read the article which was very informative but, I wasn't sure what else I was missing on this IOC stuff... I wasn't necessarily refering to EJB way of lookups in that question... (I was involved in the design of an app framework that uses this semantics to lookup infrastructure services and components which were infact POJOs...)

    For this case that you mentioned, we can still have only the lookup details of the Mock to be injected and have it then be looked up by the service locator right? why inject the component itself and define all those dependencies in pico/spring/xyz specific ways and also giveup control on the component/service lifecycle(these containers are responsible for the component/service lifecycle when those dependency property files are used right?)? I can then just replace the service locator depending on implementation semantics and at the same time not restrict how service/component gets created.(allowing component/service to have it's own creation semantics). I was just curious to know if there are any other compelling reasons to why these frameworks chose this design to inject components themselves when the EJB container creators also seem to have chosen the design of injecting only the location info and defined a locator(JNDI) mechanism...

    Thanks,
    Shyam.
  61. Push vs. Pull = EJB[ Go to top ]

    Thanks for the quick reply. I did read the article which was very informative but, I wasn't sure what else I was missing on this IOC stuff... I wasn't necessarily refering to EJB way of lookups in that question... (I was involved in the design of an app framework that uses this semantics to lookup infrastructure services and components which were infact POJOs...)

    >
    > For this case that you mentioned, we can still have only the lookup details of the Mock to be injected and have it then be looked up by the service locator right? why inject the component itself and define all those dependencies in pico/spring/xyz specific ways and also giveup control on the component/service lifecycle(these containers are responsible for the component/service lifecycle when those dependency property files are used right?)? I can then just replace the service locator depending on implementation semantics and at the same time not restrict how service/component gets created.(allowing component/service to have it's own creation semantics). I was just curious to know if there are any other compelling reasons to why these frameworks chose this design to inject components themselves when the EJB container creators also seem to have chosen the design of injecting only the location info and defined a locator(JNDI) mechanism...
    >
    > Thanks,
    > Shyam.

    You can do this, and this is an extension of the Service Locator pattern, which Mr. Fowler describes in his paper.

    My take on it is that to test something which uses this service you now need to:

    1) Create a Mock Service object
    2) Create a Mock Service Locator
    3) Pass in settings to make your code use the Mock Service Locator, which will then return your Mock Service

    This is as opposed to (in the IoC way)

    1) Create a Mock Service object
    2) Pass the Mock Service object to the code to be tested

    The IoC way seems much cleaner and easier to me. This is not to mention the fact that you now need to copy the Service Locator code (and your more advanced dynamic Service Locator) into every place that uses a Service. This is a lot more complicated than having a setFooService() method or another parameter in your constructor.
  62. Push vs. Pull = EJB[ Go to top ]

    My take on it is that to test something which uses this service you now need to:

    >
    > 1) Create a Mock Service object
    > 2) Create a Mock Service Locator
    > 3) Pass in settings to make your code use the Mock Service Locator, which will then return your Mock Service
    >
    What if the container/framework standardizes some of the commonly occuring locators and the component/service creation semantics for those cases?

    If a framework is designed to use "Push Location Info followed by Pull Component from locator" then it is lot more extensible than restricting to "Push Component" which these IOC way of doing things seems to be advocating...

    To me the spring way of doing is standardizing one such case - a bean locator with the bean creation semantics along with a dependency configuration file but by collapsing these 2 steps into 1 (and these steps being done by the container)... I feel a framework will be lot more extensible if it separates these 2 steps by design (and ofcource reduce work for 80% end-users by providing default implementations and/or making the container do some of these steps sometimes...). Other 20% framework users who need to extend may then plug in say a factory creation semantic + their own dependency configuration mechanism and use the rest of the features of such a framework... ( I feel there are many other component creation + location semantics that are generally used like webservices + uddi, ejbs+jndi, rmi+rmiregistry to mention a few...)
    > This is as opposed to (in the IoC way)
    >
    > 1) Create a Mock Service object
    > 2) Pass the Mock Service object to the code to be tested
    >
    > The IoC way seems much cleaner and easier to me. This is not to mention the fact that you now need to copy the Service Locator code (and your more advanced dynamic Service Locator) into every place that uses a Service. This is a lot more complicated than having a setFooService() method or another parameter in your constructor.
    In our framework, we standardized the infrastructure service locator and the component creation semantics for the infrastructure components & services and there is a service configuration file defining the dependencies and service/component configuration info and a standard location for the file(s)...
    So, instead of setFooService() we have setFooServiceName() and an infrastructure service locator This has reduced the steps back to 1) pass the servicename and then 2) get it from the locator. I was thinking this probably could have been extended to make it generic if needed as I explained in the earlier section...

    I think even if the framework does setFooService()..., if it internally uses separate service creators + locators + configurators then it will be lot more extensible... It's just an opinion...
  63. Push vs. Pull = EJB[ Go to top ]

    What if the container/framework standardizes some of the commonly occuring locators and the component/service creation semantics for those cases?

    >
    > If a framework is designed to use "Push Location Info followed by Pull Component from locator" then it is lot more extensible than restricting to "Push Component" which these IOC way of doing things seems to be advocating...
    >
    > To me the spring way of doing is standardizing one such case - a bean locator with the bean creation semantics along with a dependency configuration file but by collapsing these 2 steps into 1 (and these steps being done by the container)... I feel a framework will be lot more extensible if it separates these 2 steps by design (and ofcource reduce work for 80% end-users by providing default implementations and/or making the container do some of these steps sometimes...). Other 20% framework users who need to extend may then plug in say a factory creation semantic + their own dependency configuration mechanism and use the rest of the features of such a framework... ( I feel there are many other component creation + location semantics that are generally used like webservices + uddi, ejbs+jndi, rmi+rmiregistry to mention a few...)
    >

    You should look at the Spring docs... object creation is just one of the sources for a bean reference to be pushed into your object. Others include a factory object, for object types which are more complex and / or need an adapter for creating them, as well as JNDI lookup references which can look up you EJB and pass the Component Interface implementing stub, which extends the Business Interface your POJO is expecting, to your POJO component. This can allow you to start by using your existing EJBs and move to using POJO service objects in the future. I'm not even sure if this is all of the bean reference types there are... I bet not!

    > In our framework, we standardized the infrastructure service locator and the component creation semantics for the infrastructure components & services and there is a service configuration file defining the dependencies and service/component configuration info and a standard location for the file(s)...
    > So, instead of setFooService() we have setFooServiceName() and an infrastructure service locator This has reduced the steps back to 1) pass the servicename and then 2) get it from the locator. I was thinking this probably could have been extended to make it generic if needed as I explained in the earlier section...
    >
    > I think even if the framework does setFooService()..., if it internally uses separate service creators + locators + configurators then it will be lot more extensible... It's just an opinion...


    Check out the Spring docs... I didn't fully follow what you were saying, but bean references in Spring are very flexible and configurable.
  64. Push vs. Pull = EJB[ Go to top ]

    Shyam,

    There's a miscomprehension here: Spring is by no means restricted in terms of service lookup strategies.

    First of all, Spring offers both dependency injection (direct population of setters or constructor arguments, class Spring/Pico style) *and* service location (receiving a service locator handle to do lookups yourself, Avalon-style). An application bean can choose the latter by implementing BeanFactoryAware respectively ApplicationContextAware. The choice is up to you as application developer: We just *recommend* dependency injection in typical cases.

    A normal bean in a Spring bean factory will be a plain bean instance. But Spring offers a sophisticated mechanism for linking virtually any object into a bean factory: the FactoryBean concept. The basic idea is that a bean that you define does not expose itself but an object it creates: This can be used to expose objects looked up in JNDI, proxies for Hessian remote services, etc. Further up in this thread, I've posted an example of how to link in a JNDI DataSource in Spring: You might want to re-read that.

    As FactoryBean is a simple interface, you can implement *any* object lookup strategy that you prefer and link in such objects via definitions of your FactoryBean. However, we already provide many typical FactoryBeans out-of-the-box - e.g. for JNDI, Hibernate, JDO, iBATIS Database Layer, local and remote SLSBs, various remoting protocols -, so that you typically do not have to care about such integration issues. All of this works nicely with dependency injection, but as I said, you can still choose service location if you prefer.

    Juergen
  65. Component-oriented programming[ Go to top ]

    Hey Juergen,

    Have you guys considered throwing 'component-oriented programming' into your Spring marketing mix? Spring really enables an environment were pre-fabricated components written by different people can be integrated together in a "plug-in" type fashion. I remember that term was pretty big a few years back (especially in academia) but was pretty much a pipe-dream; however now it seems a lot of frameworks like Spring are really enabling the goals set out with COP.
  66. Component-oriented programming[ Go to top ]

    Hey Juergen,

    >
    > Have you guys considered throwing 'component-oriented programming' into your Spring marketing mix? Spring really enables an environment were pre-fabricated components written by different people can be integrated together in a "plug-in" type fashion. I remember that term was pretty big a few years back (especially in academia) but was pretty much a pipe-dream; however now it seems a lot of frameworks like Spring are really enabling the goals set out with COP.

    Keith,

    We haven't considered the term 'component-oriented programming' for Spring promotion yet... But you're definitely right that Spring enables the development of loosely-coupled (and individually testable) components. The difference to the original notion of COP (as promised by early EJB) is that Spring doesn't try to talk about "component developers" and "application assemblers": no meaningless deployment descriptors for communication between two such non-existent roles.

    A reusable component in Spring is just a simple POJO: Its dependencies and configuration parameters are obvious through its bean properties respectively constructor arguments and thus through its Javadoc. A component is not some special kind of deployment unit here, needing its own deployment descriptor and deployment step. It's rather a plain POJO that offers some meaningful functionality (possibly being a facade to further POJOs), to be used in a lightweight container - or in any sort of Java code in a programmatic fashion (it's just a POJO after all).

    Juergen
  67. Push vs. Pull = EJB[ Go to top ]

    In the case of EJBs, you can still provide the config info like say the JNDI info of the dependency through the environment section in the EJB's deployment file and then use the service locator to pull that component right? So, why do we need to push the whole component itself( which as I understand is being done by specifying these dependencies in the proprietary mechanism of each of these contaners)?

    >

    Let me catch that fly and try to molest it a bit.

    There is a known pattern in EJB 101 where you encapsulate the lookup with a javabean that you "new" and the JNDI name is just a property.

    The whole justification on saving code on lookups "through complex APIs" (sic, new() is a complex API? JNDI is a complex API?) smells funny and dated. Slightly green around the edges as much as independence of API.

    System control of object graphes is a lot more interesting (impact caches and session management) there is no discussion on these.

    marcf

    "HE ONLY HAS ONE MOVE! I FEEL LIKE I AM TAKING CRAZY PILLS! DOESN"T ANYONE SEE IT"
    -- Zoolander
  68. An Example of Setter Injection[ Go to top ]

    As usual, Martin has a flair for helping us all understand the purposes and tradeoffs of using certain development patterns. I confess to being a little surprised how much attention IoC has gotten lately -- it is certainly nothing new to the world :-). I'm even more surprised by some of the blogs and comments I've read in response to Martin's article, thinking that he has "annointed" one particular approach (most people seem to think he prefers Constructor Injection simply because of a personal relationship with PicoContainer developers) -- but Martin clearly points out that there are tradeoffs in every approach.

    One thing Martin didn't try to cover in his article, though, was some existing Java practices that use one or more of these patterns (even though the usage might not have been formalized with a name -- let alone *his* name :-) -- yet). But the fundamental design patterns of JavaBeans are clearly oriented towards the Setter Injection pattern. Indeed, a proper JavaBean is required to have a zero-arguments constructor, so calling setters is pretty much the only way to configure them. One of the fundamental benefits from this approach is that there is a plethora of tools that know how to manipulate JavaBeans, including serializing and restoring their state -- and it is *much* simpler to write such tools when you can not only configure a JavaBean using setters in any order you like (so you don't have to worry, for example, about the order of your keys in a properties file). Perhaps more importantly, though, you can *ask* the bean how it is currently configured (so that you can persist that information somewhere and reproduce it later). Tooling support for other approaches exists, but it is definitely not as widely supported.

    Beyond the typical uses of JavaBeans for user interface components, value objects, and so on, an interesting design scenario (at least to me, since I was the primary architect :-) is how you design a long-running server application like the "Catalina" servlet container that forms the core of Tomcat 4 (Tomcat 5 has fundamentally the same architecture, but differs in some implementation issues). The original design of Tomcat 4 (now approaching five years in age, because it was being worked on in Apache JServ before Tomcat ever existed as a public project) had some interesting goals:

    * Tomcat objects exist for a *long* time (days, weeks, months, ...),
      so any design approach that says an object can be configured once
      and never touched again is not very practical.

    * Tomcat needs to be able to reproduce the state of the server
      as of the last time that the state was persisted. And changes to
      this state can happen a lot! Imagine what would happen if the
      object that represents a virtual host used Constructor Injection
      to define the complete set of web applications that would *ever*
      run on that host, throughout the life of the server).

    * Therefore, Tomcat objects are going to need to provide mechanisms
      to modify whatever the original configured properties are over time.
      Re-using such methods for the initial configuration of the services
      is an attractive feature.

    * The state of a Tomcat configuration must be amenable to persistence
      so that it can be reproduced (when you restart the server). The
      original mechanism for this was to rely on the system administrator
      to create and maintain a server.xml file that configured the state
      of the server environment. By the time Tomcat 4.1 rolled around, there
      was also an administrative application that could dynamically change
      the configuration, and persisted the current state by asking all the
      objects for their current configuration properties. Tomcat 5 has
      migrated to using JMX APIs for this purpose, allowing each configured
      object to be known by an identifier (the "object name" in JMX-speak)
      in management tools, and have its runtime properties adjusted dynamically.

      The important thing to note is that the properties originally
      used to configure the object are *not* useful ... you *must* be
      able to ask each object what it's *current* configuration state
      is in order to be able to persist it.

    * When Tomcat internal objects are created, they go through a lifecyle of
      instantiation ("service location" is based on a a classname in an
      external configuration file, and instantiation via a zero args constructor),
      configuration (typically, the initial configuration values are set from
      the external configuration file, but almost all such properties can be
      adjusted during the operation of the server), availability (after
      configuration each instance must explicitly be made available for use),
      normal usage, and then removal from use.

    The "make available" and "remove from availability" operations are areas that Martin pointed out he hasn't thoroughly researched yet (lifecycle issues). In Tomcat, startup and shutdown processing is automatically perfomed by the server for any service class that implements the Lifecycle interface:

      package org.apache.catalina;
      public interface Lifecycle {
        public void addLifecycleListener(LifecycleListener listener);
        public void removeLifecycleListener(LifecycleListener listener);
        public void start() throws LifecycleException;
        public void stop() throws LifecycleException;
      }

    and this interface is implemented by nearly every internal service class.

    The listener registration follows the standard JavaBeans event and listener pattern -- an external class can register an interest in finding out when a particular component is started and stopped. This addresses a concern that Martin didn't discuss ... an "egocentric" object that doesn't think anyone else cares what happens to it is not going to play well in a diverse environment like an application server, where there are legitimate needs for (previously unknown) third parties to become aware of when an service instance becomes valid and invalid.

    The start() and stop() methods turned out to elegantly address the concern Martin raises about creating an object that is *always* valid (a described advantage of the Constructor Injection approach). Tomcat objects that implement Lifecycle will keep track of whether or not they have been "started" yet, and throw IllegalStateException if you try to call one of the functional processing methods before start() has been called, or after stop() has been called.

    VERY IMPORTANT NOTE: I'm by *no* means trying to claim that Setter Injection is the only, or even the best, design approach to take for all projects!!! Requirements are different, and so are solutions. But it's helpful to examine real-life examples of scenarios where one of the possible strategies has been applied; and I'm pretty happy with how using the Setter Injection pattern (even before I knew what he was going to call it :-) has worked out in practice, in more than a few long-running server side scenarios.

    The important point is that talking about patterns in the abstract is very important -- we need to establish a common vocabulary. But anyone who believes that there is one and only one right pattern is being somewhat naive. The real learning comes from examining actual applications, and exploring the tradeoffs that are always there -- even if the passionate advocates of one position or another do not want to deal with that messy fact about reality -- and using the gathered wisdom to select appropriate patterns to meet your particular needs.

    Craig McClanahan

    PS: Anyone who has downloaded the early access or beta version of the JavaServer Faces will see another example of the Setter Injection pattern. In this case, the code that evaluates value binding expressions will automatically create beans (based on metadata defined in a configuration file), *and* configure the bean properties, whenever a bean with a particular name is requested during expression evaluation (but the bean does not already exist). Another example of this pattern (although much less generally useful) is the way that Struts creates ActionForm beans "on demand".
  69. An Example of Setter Injection[ Go to top ]

    Craig,

    I agree: there's a lot to be said for JavaBeans and Setter Injection. Thanks for describing Tomcat's use of bean properties. It's important to point out that JavaBean properties are a language-level convention that have long been used in GUI applications as well as server applications.

    I prefer Setter Injection in most cases. However, I've also warmed to Constructor Injection in recent months. It's not sufficient as the only choice, but it's a good choice for some objects: for example, those with few dependencies and which won't need to be subclassed (in which case constructor chaining gets messy). I think it's important that application developers, not container developers, are able to choose the best choice for each application object: the "injection" approach to IoC enables developers to choose between language-level mechanisms. Thus the Spring philosophy is to let developers define each component the way they prefer.

    Btw the old equations Spring==Setter Injection and Pico==Constructor Injection no longer apply.

    Spring now fully supports Constructor Injection (thanks to some nice work by Juergen before the M3 release), as well as Setter Injection. Spring allows you do do everything you can do with setters with constructors: express dependencies on objects, primitives and Strings, maps, lists (arbitrarily nested); use the Spring AOP framework to advise objects an object depends on, etc.

    AFAIK PicoContainer now supports Setter Injection as well as Constructor Injection.

    Regards,
    Rod
  70. Rod,

    Do you see support for additional lifecycle methods with Spring in the future? As Craig mentioned, that can be important for server-side processes. I have a similiar requirement as Tomcat for my server side agents. Currently I've developed my own "container" (what I call an "Agent System") that manages this lifecycle: consisting of initialize()/configure(), start(), stop(), and destroy() for each "Agent service", including the system itself. These components are also exposed for management via JMX--so you may start(), stop(), and shutdown() them at anytime during operation. Calling start() twice throws an IllegalStateException, too. :-) Some services depend on others, so there is a start/stop order that must be enforced. In addition, their POJO lifecycle interface differs a bit from the JMX management interface (for example, I don't want JMX clients being exposed to the initialize() or destroy() interface, that should be an internal thing - one reason I dislike the JBOSS approach, it seems they make freaking everything exposed through JMX), but I still need a "container" like design applied internally to ensure the following lifecycle:

    1. Initialize state:
       - The system initializes, where it creates a MBeanServer, registers itself in the MBeanServer for management.
       - The system reads a file containing a bean definition for each service, instantiating each one, setting their properties, and calling initialize(). Each service may then be registered in the MBeanServer for management. Dependencies between services are wired up so they can talk to each other through a rich POJO interface (not a fan of passing ObjectNames everywhere.) Note: currently I am doing this all myself, but I really would like leverage the Spring bean factory and auto-wiring here...yalls way of doing it is just better.
       - Any management connectors or adaptors are initialized and also registered in the MBeanServer.

    2. Start() state
      - The system starts each service in the correct order through its start() lifecycle interface. A service can be marked with a "defaultEnabled" status that tells the container whether it should be auto-started or not.
      - Any management connectors or adaptors are started.

    3. Stop() state
      - The system stops each service in the correct order through its stop() lifecycle interface. This method could be invoked by the container itself or by a requesting JMX client. Services that depend on the one stopped are also stopped.

    4. Destroy() state
      - MBean's are unregistered, destroy() is called on all services, and the MBeanServer resources are released.

    Do you think Spring could be adapted to meet some of those lifecycle/management requirements to be better suited for server-side processes? Thinking about it a bit - I probably can just leverage your existing initialize / configure / destroy support and fill in the gaps for the rest. But I haven't actually tried to do that yet. :-)

    Thanks!

    Keith
  71. Storm in a teacup?[ Go to top ]

    Several things on the emotional level:
    1) Martin has in the past written some really good bluffers guides, taking software philosophy and breaking it down to a practical level. Thanks.
    2) I got annoyed that IoC should have another name.
    3) I got really annoyed that what is simply an API should end up with 3 or more seperate pattern names.

    And then we come to:

    >It's often said that configuration files shouldn't use a programing language
    >because they need to be edited by non-programmers. But how often is this the
    >case? Do people really expect non-programmers to alter the transaction
    >isolation levels of complex server-side application? Non-language
    >configuration files work well only to the extent they are simple. If they
    >become complex then it's time to think about using a proper programming
    >language.
    >
    >One thing we're seeing in the Java world at the moment is a cacophony of
    >configuration files, where every component has its own configuration files
    >which are different to everyone else's. If you use a dozen of these
    >components, you can easily end up with a dozen configuration files to keep in
    >sync.

    And I smiled and realised it's a storm in a teacup and thoughtworks doesn't own his brain. It's always nice to have your own world view presented by others.

    My point? The entire area of discussion could be summed up as:

    Is it a project with tight, practical deadlines? If yes use code.
    Is it a project with huge deadlines or budget. Produces loads of API's, with constructors, or setters and then a runtime environment which can call them to configure them (ideally write your own runtime cos it's really interesting).
    OR, write a singleton which knows how to get any given API from any starting point (a 'Service Locator'). Either way generate lots of config files.

    Thats it yes? You can argue forever about what may possibly be needed from a solution, but if you worry about the finite scope and requirements of what is actually needed then you come down to:

    Code it. OO is still ace. And yes, even a config file or two.
    Constructor or setter with runtime framework (decoupling decoupling decoupling), with lots of config files.
    Decouple though a singleton, and then decouple again and again and again because its fun. And you can have lots of config files.

    Jonathan
    ps Yes I favour coding it (well). KISS and JFDI.
  72. Storm in a teacup?[ Go to top ]

    Is it a project with tight, practical deadlines? If yes use code.

    > Is it a project with huge deadlines or budget. Produces loads of API's,

    LOL,

    Thank you for a down to earth post.

    I am tired of reading "type n" post on what is a trivial API. The french call this discussion "enculer des mouches" (fly as*f*cking) usually found in some academic settings. Storm in a tea cup is a much better and PC way of saying it.

    I believe in code that runs.
    Peace Love and simple code,

    marcf
  73. isn't this just factory stuff?[ Go to top ]

    Or am i missing something?
  74. isn't this just factory stuff?[ Go to top ]

    Or am i missing something?


    If you're thinking of things like the factory patterns in the GoF book, that is what Martin was talking about when describing the "Service Locator" patterns.

    The difference is fairly subtle, but important. The "dependency injection" patterns install a reference to the actual service object (or whatever) that the component you're configuring requires. In the "service locator" patterns, you don't provide the actual service implementation object -- instead, you provide a mechanism by which the component you're configuring can "look up" or locate the actual service implementation it requires. The component being configured still has a dependency ... but now it is on the locater instead of the actual service implementation. (Sort of like when your friend asks for interesting sites on the net ... you can give them a few bookmarks to your favorites, or you can point them at Google :-).

    A pretty classic example of the service locator pattern is the JNDI context that is provided by J2EE containers to applications (and, in some cases, by non-J2EE containers like Tomcat as well). Essentially, the component being configured just has to be told the *name* of a resource it should use, and it then depends on JNDI APIs to access the actual implementation that has been configured for this particular execution.

    An example scenario might help illustrate this better. How many of us have been involved in building web applications where there are two or three deployment scenarios (typically "development", "testing", and "production" or something like that)? What you'd like to do is to take a single web application archive (WAR) and deploy it *unchanged* in all three scenarios to avoid any risk that tweaking the configuration files between stages will induce new errors.

    That doesn't work too well, for example, if you configure a JDBC connection pool using context initialization parameters (or something like that) inside the webapp. Each of the three deployment environments will naturally be talking to a different physical database (for obvious reasons :-). So, you have to tweak the connection properties as you move your WAR from one deployment environment to another -- a potential error creation opportunity.

    The J2EE approach to this is to externalize the configuration of the details of the service provider, so that the application only needs to be concerned about acquiring a "resource reference" to that resource. This will typically be some well known String like "jdbc/Customers" for the customer database. The administrator responsible for deploying the application needs to configure the resource reference name to the right (say) physical database -- but you can take exactly the same WAR file and deploy it in all three scenarios.

    From the application developer's perspective, this approach actually *increases* complexity slightly -- now you're dependent on two APIs (the javax.sql.DataSource API for the connection pool itself, and the JNDI API to acquire the reference to the right DataSource instance) -- but this is mitigated by the fact that you, as the developer, don't have to maintain multiple configuration properties sets. Like everything in life, it's a tradeoff ... but this particular one I've found quite beneficial in many scenarios.

    Craig McClanahan
  75. Craig,

    Good point regarding JDBC DataSources. It can indeed be valuable to just refer to a symbolic name in a WAR, doing the actual binding at deployment time. But as you say, it introduces a level of indirection and particularly separation of configuration: You now have to touch your server configuration to set up a DataSource. While this may be what you want for production deployment, this is rather unhandy during development: There, it's arguably better to keep such configuration close together, preferably within the project directory.

    Resource definitions are a central part of Spring. The Spring solution is to expose a property of type javax.sql.DataSource, expecting dependency injection. You can choose between setter and constructor injection; I'll use the former here.

      public class MyDao {
        private DataSource dataSource;

        public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;
        }
      }


    The lightweight container then wires this up at runtime, for example with a locally defined Commons DBCP BasicDataSource:

      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
        <property name="url"><value>jdbc:mysql://localhost:3306/mydb</value></property>
      </bean>

      <bean id="myDao" class="mypackage.MyDao">
        <property name="dataSource"><ref bean="dataSource"/></property>
      </bean>

    If you want to switch to a JNDI DataSource, simply change the configuration:

      <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName"><value>jdbc/mydb</value></property>
      </bean>

      <bean id="myDao" class="mypackage.MyDao">
        <property name="dataSource"><ref bean="dataSource"/></property>
      </bean>

    And in a test suite, either create specific bean definitions for testing purposes, or simply take your component and populate it programmatically:

      DataSource myTestDataSource = ...
      MyDao myDao = new MyDao();
      myDao.setDataSource(myTestDataSource);

    So you can for example develop with a local DataSource, deploy with a JNDI one, and use some mock DataSource for testing. The important point is that your MyDao component class does not have to be adapted, because it simply doesn't care: All it needs is a resolved dependency of type javax.sql.DataSource. It's none of its business where this DataSource actually comes from.

    Now, let's compare the degree of flexibility: The MyDao component above can be used in virtually any Java environment that allows access to a database, be it a standalone application, a web app in Tomcat, or an EJB running in WebLogic. If we would have modelled it with a hard-coded JNDI lookup, we would have restricted it to J2EE environments.

    If we add declarative transactions to the above - which amounts to two more bean definitions in Spring: transaction manager plus transactional proxy for myDao -, the reuse issue because even more significant: Modeling our component the way we did still allows for reuse in any environment, while the alternative of modeling it as local SLSB would restrict it to EJB environments.

    Juergen
  76. what's the big deal?[ Go to top ]

    I for one agrees with the new name. A bad name will confusing someone forever and they'll never get it. IoC is just too fancy (and too offensive to managers:).

    however, we write daily TreeSet(Comparator), ImageWriter.setOutput(), -Djava.protocol.handler.pkgs, etc. Those are IoC type x y z we use without ever needing a big name. so what's the big deal?

    I guess the big deal is most people code by example, they cannot apply patterns in one domain to another domain, they cannot even identify the pattern. if MyBigFatGreekComponent needs a setter to initialize some dependency, people will panic just because they didn't see it before.

    Therefore somebody must stand up, and give it a big name, just to comfort the mass, that it is OK.
  77. Hey, don't forget to rename Data Trasfer Object to Data Teleport Object. This will make RMI/SOAP calls instantaneous.
  78. Hey, don't forget to rename Data Trasfer Object to Data Teleport Object. This will make RMI/SOAP calls instantaneous.


    If I can't see the Transporter make the object shimmer and then disappear on the starship, and then materialize on the planet, I'm not interested in your flavor of DTOs :-).

    Craig McClanahan
  79. Hey, don't forget to rename Data Trasfer Object to Data Teleport Object. This will make RMI/SOAP calls instantaneous.

    >
    > If I can't see the Transporter make the object shimmer and then disappear on the starship, and then materialize on the planet, I'm not interested in your flavor of DTOs :-).

    It's implied. Teleport Objects (TOs) are transfered by Trasporter Manager EJBs implementing "Theatre Facade" pattern.

    One more thing: Cold-blooded "Visitor" pattern should be renamed to warm-hearted "Guest" pattern. "Command" pattern should go as "Advice", mmmmm... what else? Will "Painter" make for "Decorator"?

    Regards,

    Slava Imeshev
  80. Lightweight containers, is that all?[ Go to top ]

    No, it's not. I feel compelled to say that Mr Fowler only described about one tenth, if that, of what Spring is all about, yeast readers get the wrong idea. Note that I'm not accusing Mr Fowler of misleading the reader (I'm quite sure that was not his intent). I'm thrilled that he is writing about such innovative open-source technologies like Spring and Pico. And it's great to have such a recognize leader paying attention to open source. It's just that the article uses the term lightweight containers and then explains only one feature. Furthermore, Mr Fowler's explanation of how this helps / why its important is a tad limited.

    Wiring together "components" while managing dependencies is important but misses the big point. Wiring together the application's own code while managing dependencies is just as important but has an important added benefit - you no longer have to write singletons and factories for things like dao's, excuse me, I'm mean Table Data Gateways. Who says we can't have our cake and eat it too! Faster (development), better (agile application) and cheaper (open source!). The faster & cheaper aspects are real pulses for those of us who have to justify using all this techno weenie stuff.

    I will not try to describe lightweight containers here, others like Juergen Hoeller would be much better at it and for the most part already have posted fairly good descriptions.

    Jeff Boring
  81. Configuration vs Behavior[ Go to top ]

    The configuration aspect of beans being only one part IoC, I expect to see more IoC: XXXXX specialisation terms in the future. I like 'dependency injection' very much, so how about another one ;-)

    I've seen framework and containers (like avalon) that use interfaces extensively to signal the container that a component should be treated differently than other components or that methods have to be called before or after calling other methods. Examples of these are lifecycle methods.
    The example described in the article of IoC in the user interface is a good example to me of something that is part of IoC, but is not described by the term "Dependency Injection".
    >>> The main control of the program was inverted, moved away from you to the framework

    Have a look at for some thought from the avalon community:
    http://avalon.apache.org/framework/cop/guide-patterns-ioc.html
    and
    http://avalon.apache.org/framework/cop/guide-patterns-ioc-security.html

    How about
    >>> In this article I dig into a specific type of IoC and give it a more specialized name, "IoC: Dependency Injection".

    instead of:

    >>> In this article I dig into how this pattern works, give it the more specific name of "Dependency Injection"

    Michael.
  82. Further Reading[ Go to top ]

    I came across this article as I was writing a similar example using Pico and Jaxor. Jaxor is an O/R framework based upon many of the patterns found in Patterns of Enterprise Application Architecture.

    http://jaxor.sourceforge.net/?q=pico
  83. JINI 2.0 Config API[ Go to top ]

    With the new Jini 2.0 Config API I was able to write some distributed components that use SSL as the transport mechanism. Those same components where passed down to a freind who now uses them with Kerberos. Did he have to change any code? the answer is no, with the Jini Config API the transport layer for the remote components was swapped at the config file level. The config file are not XML, but are instead in Java. I think this reflects exactly what Martin is talking about. All dependancies are pushed out to a config file, and descisions are made at deployment time, with no code modifications.
  84. Lines of code[ Go to top ]

    Firstly, thanks to Martin for such clarity on these often confusing subject areas.

    The discussion between service injection and service location seems to have a push vs pull aspect to it that was not discussed in the article. In very simplistic terms the general efficiency from a coding perspective should also factor into a decision listing on which strategy to adopt.

    Given that the component/services are known at development time, that is to say an existing enterprise architecture is in place, then it would appear more efficient to push the configuration into client code rather than pull it.

    The advantages to pushing an enterprise architectural configuration into client code is that the developer does not need to be as aware of the underlying mechanisms in place. Mechanisms including service location.

    After reading the article I was left with a distinct preference for service injection over service location. This in large part mirrors my experiences on a smaller scale with the use of centralised registry services on the Windows operating system and the effect this registry has had on system flexibility and adaptability. The effect of which has resulted in a single point of corruption and failure.

    Cheers
    Shaun
  85. Martin Fowler's article & big problems[ Go to top ]

    It took me a while, but I finally read it...

    Martin Fowler's article is horrible! At the company I work the "service locator pattern" is used instead of dependency injection. Bad Bad Bad.

    As a result, when I had to reuse some classes from the main project in a smaller tool, and instead of using the 17 classes I needed, I had to import 350 classes with LOTS of bugs in it, because the service locator had dependencies to it! Completely pointless! Dep Inj decreses the coupling, service locator increases it.

    In his examples he even implies the locators SHOULD have static class links, and his "interface for locators" solution is completely unclear.

    I completely lost respect for Fowler after that one.