Skip to main content

Secrets of lightweight development success, Part 4: A comparison of lightweight containers

Spring, HiveMind, and PicoContainer

Bruce Tate (bruce.tate@j2life.com), President, RapidRed
Bruce Tate
Bruce Tate is a father, mountain biker, and kayaker in Austin, Texas. He's the author of three best-selling Java books, including the Jolt winner Better, Faster, Lighter Java. He recently released Spring: A Developer's Notebook. He spent 13 years at IBM and is now the founder of the J2Life, LLC, consultancy, where he specializes in lightweight development strategies and architectures based on Java technology and Ruby.

Summary:  Lightweight containers can dramatically loosen the coupling between major components of your system. Different containers embrace the same design patterns, but have otherwise radically different philosophies. This article helps you make the best choice among three lightweight containers: Spring Framework, HiveMind, and PicoContainer.

View more content in this series

Date:  16 Aug 2005
Level:  Introductory
Activity:  3411 views
Comments:  

In a trip through Colorado in 2002, I caught the Arkansas River at a perfect level. The river showcased stunning diversity across three different runs. The laid-back Brown's Canyon run had wide open rapids with huge, fun wave trains. The characteristic cliffs of the Royal Gorge channeled the power of the river beneath a massive vertical canyon, in which little mistakes in the straightforward lines were punished with long swims. The Numbers had nice drops requiring precise maneuvering among restricted boulder gardens. In one river, I had three vastly different experiences.

In my last article, "Secrets of lightweight development success, Part 3: The emergence of Spring," you learned the basics of lightweight containers. In this article, I walk you through the three most popular containers:

  • Spring Framework has a full-featured container, an aspect-oriented programming (AOP) model, and integration code for just about anything you need for enterprise development.
  • HiveMind, from the creator of Jakarta Tapestry, lets you perform dependency injection for beans or larger components, called modules.
  • PicoContainer is the smallest of the lightweight containers and uniquely supports a Java™ technology-style configuration, rather than an XML configuration.

All these containers flow from dependency injection, but each has a vastly different character. As I walk through a high-level description of each, you'll see each framework in action, as well as where you can apply each framework.

Core philosophies

All of these containers accept plain old Java objects (POJOs), all have hooks for object life cycles (so they can call your code when they create or destroy a bean), and they all perform dependency injection. You might think these central themes would lead to similar containers, but that's not at all the case. While the code that goes into each container may be similar, the containers themselves reflect different capabilities, styles, and overall philosophies. All in all, the authors of each container stay true to their philosophies.

Spring Framework

The Geneva of open source frameworks, Spring Framework provides a lightweight container and glue code for hundreds of Java 2 Platform, Enterprise Edition (J2EE) APIs and open source frameworks. Spring has one overriding vision: to make J2EE easier to use. After reading through some examples and books, you'll see some common themes:

  • Spring supports three types of dependency injection -- setter, constructor, and method injection -- but overall, the prevailing model is setter injection.
  • Spring's XML-style configuration values flexibility over simplicity. You can do just about anything, but the configuration files are hard to read and difficult for novices to understand.
  • Spring's founders believe that the container is a only small part of the overall framework. Most of Spring's value comes from the thousands of lines of glue code supporting the framework. It's easy to plug in just about anything.
  • The Spring framework is the most complete and well polished of the three container implementations. In particular, the excellent documentation is complete and well written.
  • Spring has an autowire mode, but most examples fail to use it. I don't quite understand this decision, but at times, it's nice to see dependencies explicitly listed.
  • Spring provides a full AOP framework to make it easier to attach services. You can use Spring's own framework or rely on the rich AspectJ integration (see Resources).

If I were to characterize Spring with a phrase, I'd say, hardened for the enterprise.

HiveMind

Howard Lewis Ship, the creator of the Jakarta Tapestry Web framework, also created HiveMind. As a container, HiveMind is clever, clean, and a joy to use. Like many of the other, better, open source frameworks, Ship created HiveMind to help him solve real problems. However, HiveMind adds a couple of new wrinkles to traditional lightweight containers:

  • The most important HiveMind innovation is the module. According to Ship, the Eclipse plug-in inspired the HiveMind module.
  • HiveMind forces you to program to interfaces. (Like all lightweight containers, it doesn't impose an interface; you provide your own.)
  • HiveMind is user-friendly, providing items like a documentation tool called HiveDoc, a friendly and concise XML configuration, and line-precise error reporting.
  • HiveMind users typically prefer setter injection, but the container also supports constructor injection.

If I were to characterize HiveMind with one phrase, I'd say it's conceptually sound.

PicoContainer

By far, the biggest overriding characteristic of PicoContainer is its size. It won't give you a lot of extras, but it has a complete dependency injection container. PicoContainer also has some unique properties:

  • PicoContainer is small, so it doesn't have interceptors, AOP, or similar types of services, preferring instead to let other frameworks create them.
  • PicoContainer supports Java technology for configuration, rather than XML, like the other containers.
  • PicoContainer's prevailing usage model is constructor injection, although it also supports setter injection.
  • PicoContainer doesn't give you much documentation, and some of the existing documentation is incomplete, although you don't need much.
  • PicoContainer has one autowire mode, and it's nice.
  • PicoContainer's development seems to have stagnated somewhat.

If I were to characterize PicoContainer with a phrase, I'd pick theoretically pure, but not as practical as Spring or HiveMind.


Programming model

Now I'll point you to programming examples prevalent in the community to help you better understand how the authors of the containers would like you to use them. I use the Kiss example from PicoContainer to showcase autowiring and Java technology-style configuration, the HiveMind adder example to showcase the module capability, and the Spring PetClinic application to showcase Hibernate integration.

The Kiss example (PicoContainer)

Of the three containers, PicoContainer has the simplest programming model. To see the Kiss example, download it from PicoContainer.org. Install the example, browse to docs\Two+minute+tutorial.htm, and you should see two components:


Listing 1. Two Kiss components

public class Boy {
    public void kiss(Object kisser) {
        System.out.println("I was kissed by " + kisser);
    }
}
public class Girl {
    Boy boy;

    public Girl(Boy boy) {
        this.boy = boy;
    }

    public void kissSomeone() {
        boy.kiss(this);
    }
}

These two classes are self-explanatory. Girl has a dependency on Boy. The dependency will be injected through the constructor. You instantiate a container:

MutablePicoContainer pico = new DefaultPicoContainer();

Then you register the two components:

pico.registerComponentImplementation(Boy.class);
pico.registerComponentImplementation(Girl.class);

Later, you can ask PicoContainer for an object, then exercise it:

Girl girl = (Girl) pico.getComponentInstance(Girl.class);
girl.kissSomeone();

That's pretty much it. The programming model is elegant, and the constructor-based style means you don't have to include a constructor without arguments. Calling such an instructor on the Girl in this example would leave the object in an inconsistent state because the kiss method would throw an exception.

The adder example (HiveMind)

Now, let's take a look at HiveMind's programming example. Download HiveMind from The Apache Jakarta Project, then look at the adder example. You should see an interface and an implementation. (Remember: HiveMind enforces interfaces.)


Listing 2. Adder example interface and implementation

public interface Adder
{
    public double add(double arg0, double arg1);
}

public class AdderImpl implements Adder
{
    public double add(double arg0, double arg1)
    {
        return arg0 + arg1;
    }
}

You expose the service in an XML file, like this:


Listing 3. Expose the service in an XML file

<module id="examples" version="1.0.0">

  <service-point id="Adder"
      interface="org.apache.hivemind.examples.Adder">

    <create-instance
      class="org.apache.hivemind.examples.impl.AdderImpl"/>

  </service-point>
</module>

Other applications could then use the service, like this:


Listing 4. Other applications can use the service

Registry registry = RegistryBuilder.constructDefaultRegistry();
 
Adder adder = (Adder) registry.getService("examples.Adder",
  Adder.class);

... adder.add(arg0, arg1)

Notice that HiveMind's module lets you group together multiple services. If you needed to add functionality to services in the container, you could use an interceptor:


Listing 5. Use an interceptor to add functionality

<module id="examples" version="1.0.0">
  <service-point id="Adder"
      interface="org.apache.hivemind.examples.Adder">

    <create-instance
      class="org.apache.hivemind.examples.impl.AdderImpl"/>

    <interceptor service-id="hivemind.LoggingInterceptor"/>
  </service-point>
</module>

The PetClinic application (Spring)

Spring approaches things just a little differently. Because the Spring framework doesn't come with a simple application, I'm choosing one from my book, Spring: A Developer's Notebook. You can get the sample code from O'Reilly Media. Crack open example 4, which shows a CommandLineView object with a property for a RentaBike store, which eventually becomes the data access object for this application.


Listing 6. CommandLineView object

public class CommandLineView {
   private RentABike rentaBike;
   public CommandLineView() {}
   public void setRentABike(RentABike rentaBike) {this.rentaBike = rentaBike;}
   public RentABike getRentaBike() { return this.rentaBike; }
...
}


RentaBike is an interface with the types of methods you'd expect to see on a bike store object:


Listing 7. Interface methods

public interface RentABike {   
   List getBikes();   
   Bike getBike(String serialNo);   
   void setStoreName(String name);   
   String getStoreName();
}

Not shown is ArrayListBikeStore, which is a stub implementation of the BikeStore interface. Note that Spring allows interfaces, but doesn't enforce them. Here's the XML configuration file, describing the beans in the application:


Listing 8. XML configuration file describing application beans

<beans>
  <bean id="rentaBike" class="com.springbook.ArrayListRentABike">
    <property name="storeName"><value>Bruce's Bikes</value></property>
  </bean>
  <bean id="commandLineView" class="com.springbook.CommandLineView">
    <property name="rentaBike">
      <ref bean="rentaBike" /> 
    </property>
  </bean>
</beans>

This context has two beans in it. The commandLineView bean depends on the rentaBike bean. This application resolves the dependency explicitly by specifying the rentaBike name for the rentaBike property. Note that PicoContainer automatically wires obvious relationships like these, and Spring can, too, but most users don't use the autowire option. Spring can also let you add services to any method of the façade through interceptors or AOP.


Comparisons

Now that you have seen the overall philosophies for each container, here's a more detailed comparison of the intangibles of each environment, such as market share, fit and finish, and the overall feature list. After all, even if the programming model is perfect, it's not going to be a good container with no documentation or you have to support it yourself because of a lack of community.

Active community

Spring has a vibrant community, as well as a professional services company called Interface21 that supports the framework. That's important because you know you can get excellent support, and the company is motivated to support the Spring framework. My experience with the community has been nothing short of sensational. Spring contributors, authors, and users alike pack the message board with outstanding content.

The HiveMind framework is an Apache Jakarta project, so it's on firm footing. It has a budding community growing in activity. The framework's founder, Howard Lewis Ship, is an independent consultant, an excellent instructor, and a tireless promoter. However, it's still much more difficult to hire quality help for HiveMind or find content beyond a few articles and what's on the Web site. Still, the online support seems good, and the community seems to be growing. Hibernate scored an interesting victory when it was chosen -- or, more likely, Ship was chosen -- to form the foundation of the new infrastructure for TheServerSide.com, one of the most important online Java technology communities.

PicoContainer, also an Apache Jakarta project, seems to be winding down. As of this writing, the last major code drop for PicoContainer was in November 2004. You don't see many new articles about PicoContainer, which is a shame because I like some of PicoContainer's philosophies. In fact, I'm not sure that there's room for three open source lightweight containers, especially since a fourth lightweight container project called Avalon recently shut down.

As far as the activity generated in each community, Spring is far and away the winner. The support of Interface21, fantastic forums, active mailing lists, and the track record of the community are unrivaled.

Fit and finish

The size and strength of a community often drives fit and finish within open source projects. Vibrant communities demand better documentation and examples, and they lend more hands to do the finishing details.

The Spring team writes documentation that rivals some of the better commercial products I've seen. If that's not enough, you can find at least five major Spring books and many other publications with some Spring content. (I've written two books with some Spring myself, including one chapter of the Jolt-winning Better, Faster, Lighter Java and the quick start book called Spring: A Developer's Notebook.) The error messages are professional and descriptive. The integration with third-party frameworks and APIs is among the best of any Java technology framework. The packaging is thoughtful, if a bit on the excessive side. (It makes sense to me to begin breaking out some of the more minor projects as modules.) The examples are good and instructive.

Like Tapestry, HiveMind also has good fit and finish. Ship prides himself on the features that make HiveMind easy to use, like line-precise error reporting; a friendly, concise XML syntax; and an excellent documentation tool called HiveDoc. In combination with JavaDoc documentation for low-level details, you have the excellent capability to describe the high-level features of your application (HiveMind modules), complete with the dependencies between them.

The PicoContainer programming model feels natural, but the documentation is incomplete in places (with many to-do markers that look many months old), and there aren't many real-world examples of what you can do with the container. At times, I felt like I was walking alone through an abandoned haunted house.

You do get one major advantage with PicoContainer, though. Because you're configuring real-world objects, you get some compile time error checking. In reality, the container is so small and light that there's not much that can go wrong, other than basic configuration. PicoContainer does a reasonable job.

Features

I don't need to talk about features much. Spring wins hands down if you're looking for a lot of glue code to ease the integration of your open source favorites or that certain J2EE API. HiveMind doesn't try to compete. Instead, it's compatible with Spring's services. PicoContainer doesn't build the extras and doesn't try, preferring to let open source projects provide the services for them. So far, it's not working very well.


Which one is best?

Right now, there's only one real solution. HiveMind has interesting innovations, and PicoContainer has an easy-to-use model (in theory), but the community seems to have voted on Spring Framework. Over time, a new container may develop, or HiveMind could continue to garner market share, but right now, Spring's your best bet.

If you're willing to take on some risk and use a container with less popularity or maturity, you may decide to implement HiveMind (if you need the module-level configuration) or PicoContainer (if you want a tiny container). If you need a lot of glue code to integrate aspects such as persistence engines, transaction strategies, and security, Spring has the most complete component stack. Remember, though: You can use Spring components in the HiveMind container.


Resources

Learn

Get products and technologies

  • Innovate your next open source development project with IBM trial software, available for download or on DVD.

Discuss

About the author

Bruce Tate

Bruce Tate is a father, mountain biker, and kayaker in Austin, Texas. He's the author of three best-selling Java books, including the Jolt winner Better, Faster, Lighter Java. He recently released Spring: A Developer's Notebook. He spent 13 years at IBM and is now the founder of the J2Life, LLC, consultancy, where he specializes in lightweight development strategies and architectures based on Java technology and Ruby.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=91914
ArticleTitle=Secrets of lightweight development success, Part 4: A comparison of lightweight containers
publish-date=08162005
author1-email=bruce.tate@j2life.com
author1-email-cc=bruce.tate@j2life.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers