Announcement Announcement Module
Collapse
No announcement yet.
Spring: useful for J2EE. not so useful for J2SE? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring: useful for J2EE. not so useful for J2SE?

    I've read Rod's book and a very interesting read it is to: highly recommended. If had to pick out the top issues Rod has with EJBs I think it's that they're hard to (unit) test and are "less than Java": principally because they disallow inheritance (some vendor specific kludges aside) and prevent thread managemenet.

    And yet it seems two out of three charges (and an additional one) can also be made against the very heart of Spring: the configuration XML file.

    1. How do you unit test an XML configuration file?
    2. Assuming I could unit test it, how would I unit test a J2EE dependent configuration without deploying it? (I can't see anyway to mock elements in an XML file!).
    3. If the configuration XML file were a Java class I think most people would have a hard time taking the designer seriously: talk about overloaded with responsibility!
    4. The configuration file completely lacks any support for genuine modularisation. All the simple import model does is split one physically large file into many parts. Logically it's still one entity with no enforcable boundaries: it's like defining a bunch of classes and making every single attribute and operation, whether internal or not, publicly visible.
    5. No compile time checking. With Java I get immediate feedback when I compile a class telling me that there is no attribute called foo or that operation bar isn't visible (with a decent IDE I get that feedback without even compiling). With Spring and the configuration file I only find out that I have two beans named fooBean and barBean doesn't have a property called wibble after I've compiled, deployed and then run my application.

    Don't get me wrong: I like the ideas behind Spring: dependency injection and aop proxying are certainly steps forward I just wonder whether it's actually as usefully broadly applicable as it's being sold. (As an aside: I think Inversion of Control is a poor name).

    As a replacement for Singletons: yes I can go for that. As a way to load time configure the application: eg configuring an Action with a Strategy where that flexibility is a *requirement*: Yes. As a way of reducing (or eliminating) the application's dependencies on hard to mock resources/environments (ie J2EE): definately.

    And of course it's less of an issue in areas where you already have impossible to unit test configurations.

    But I wonder if the usefulness of Spring with J2SE applications is much more limited. J2SE applications don't have the inherent difficult-to-testability that Spring addresses: you don't need to deploy it anywhere before running it and, of course, J2SE doesn't suffer from being "less than Java" in the way that EJBs do.

    For example, probably the biggest improvement we've made as a result of incorporating Spring into our J2SE applications was in switching from using template methods to using strategys to configure Actions. As a result we've reduce my code count in that area by about half: which is great! But whilst that was triggered by my exposure to Spring (or more specifically Rod's book) it in no way depends on Spring.

    So the conclusions I've come to about Spring are:

    1. It's maximum benefit comes in building J2EE applications. Both in making them easier to unit test and breaking the tight coupling between application and the J2EE server. And this is no small thing! The major downside to Spring: the untestable configuration xml isn't such an issue in J2EE which is already awash with such beasts, so replace one with another <shrug>: at least the problem's no bigger.

    2. For J2SE the benefits are much smaller simply because the same problems that exist with J2EE simply do not exist in J2SE. And adding in an untestable monolithic configuration file is a definite net change for the worse. In J2SE Spring is probably most useful for directly replacing existing Singletons (by run time configuring the classes that need a resource with that resource, rather than having them call a global object to lookup the resource) and as a result keeping the configuration xml as small as possible.

    Edward Kenworthy

  • #2
    Edward, a quick comment:

    1. How do you unit test an XML configuration file?
    You don't unit test configuration. Unit testing is about testing classes in isolation. With EJB or traditional "pull" configuration unit testing Java classes becomes hard; a DI container makes it easier.

    You can test Spring configuration however (it's a form of integration testing): you can simply load a Spring container and run tests on the objects. This is way faster than starting an app server. See the org.springframework.test package in the mock JAR for classes to help you do this.

    2. Assuming I could unit test it, how would I unit test a J2EE dependent configuration without deploying it? (I can't see anyway to mock elements in an XML file!).
    Again I think this misses the point of unit testing. And XML is actually a pretty good way to enable substitution of test-time classes. For example, I usually pull out DataSource and PlatformTransactionManager into their own XML file, so I can test outside an app server using BasicDataSource and DataSourceTransactionManager or another local tx manager.

    3. If the configuration XML file were a Java class I think most people would have a hard time taking the designer seriously: talk about overloaded with responsibility!
    It's possible to split up configuration into multiple files. But there are strong practical benefits in this tradeoff--I would always choose a few "centralized" files in a consistent format rather than the host of ad hoc configurations found in large apps. The fact is that quite a bit of metadata is used in every big (J2EE or other) app that I've seen. It's more obvious when you put it in a few XML files as Spring tends to do, but that doesn't mean there's actually more. It tends to be lurking away otherwise until you go looking for where some value came from.

    4. The configuration file completely lacks any support for genuine modularisation
    Fair point. We're considering addressing that in 1.2.

    5. No compile time checking. With Java I get immediate feedback when I compile a class telling me that there is no attribute called foo or that operation bar isn't visible (with a decent IDE I get that feedback without even compiling). With Spring and the configuration file I only find out that I have two beans named fooBean and barBean doesn't have a property called wibble after I've compiled, deployed and then run my application.
    We're considering adding a Java configuration option (as well as XML, and allowing mixing and matching) in Spring 1.2 that will offer checking. You don't need to deploy to do such checking if you run integration tests against a Spring container as I mentioned above.

    For J2SE the benefits are much smaller simply because the same problems that exist with J2EE simply do not exist in J2SE. And adding in an untestable monolithic configuration file is a definite net change for the worse.
    Certainly I would agree that the benefits are greater for J2EE. However, I don't think the motivation for Spring is merely the deficiencies of J2EE. Of course, however, you are free to use new whenever there's no benefit in having the container instantiate an object. But I would not want to go back to ad hoc configuration even in J2SE applications.

    My experience overall is that the Spring approach helps me write Java code the way I want to--regardless of whether I'm working with nasty, hard-to-test, APIs underneath.

    Thanks for your comments. Modularization is certainly something we need to work on. And Java--or Groovy--configuration options may sometimes be appropriate where XML doesn't fit so well.

    Rgds
    Rod

    Comment


    • #3
      You have to keep in mind that Spring is more than just a IoC framework: it provides many support libraries addressing typical 'generic' infrastructure problems that build on lower-level services. An example of this would be the JDBC abstraction framework, which builds on JDBC, or the Hibernate and transaction management abstractions, which build on Hibernate and JDBC or JTA. Whether these libraries are "J2EE" or "J2SE" is a bit blurred---however, it's important to note that most all of these support libraries (and the services they build on) can be used in standard J2SE environments just as well as they can in managed J2EE environments.

      So, for example, if I need a fat client app with a database connection, I'll use Spring rich (swing support) with the JDBC/TM support. I'll almost always use the core container to "glue the layers" of my app together, to cleanly separate out a well-defined service layer from my presentation layer (and to decouple my components from hard-coded lookups).

      It's all about choice. You use the parts of Spring you need, and only what you need.

      The beans, dao, transaction, jdbc, orm, scheduling, richclient, aop, mail, jms, and remoting packages of the Spring framework are usable in J2SE OR J2EE environments--a real powerful differentiator for Spring (and a major reason I like it so much to invest much of my career in building applications with it!)

      Comment

      Working...
      X