Skip to main content

The Geronimo renegade: Ease data access and configuration issues with the Spring Framework

Erase these typical problems with the dynamic duo of Apache Geronimo and Spring

Nicholas Chase has been involved in Web-site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. He has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the chief technology officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sams).

Summary:  If you're a typical developer, you'd no doubt welcome a solution to data access issues and embrace any tool that would make configuration easier. It's hard to have a conversation about Web applications in general, and these issues specifically, without somebody somewhere mentioning Spring. But good grief, do we really need another Web application framework? When I decided to do a Geronimo renegade piece on the intersection between Apache Geronimo and Spring, I knew it was high time to find out what all the Spring Framework buzz was about. I did that by cornering Jeff Genender.

View more content in this series

Date:  27 Feb 2007
Level:  Intermediate PDF:  A4 and Letter (41KB)Get Adobe® Reader®
Activity:  1576 views
Comments:  

Inversion of control simplifies configuration

I started out on my quest to answer all the questions I had about the Spring Framework by turning to Jeff Genender, Geronimo committer and all-around talented guy, and asking him, for those of us not familiar with it, just what is Spring, anyway?

A little research had told me that Spring is a Web application API and that it includes an implementation of the Model-View-Controller (MVC) model for those who are unhappy with Struts. But what makes it such a big deal? What's the killer feature that seems to provide critical mass for this framework?

"Spring is an IoC container," Jeff explained. "That stands for Inversion of Control, which enables you to inject dependencies by declaring them in an XML file."

IoC was a new term for me, so Jeff explained that when you're creating an application, you typically have one object that relies on another object. For example, you might have a business object that represents, say, a sandwich maker. That sandwich maker refers to a second object, the sandwich filler. So you might have code like this (see Listing 1).


Listing 1. A sample class
package com sandwiches;

public class SandwichMaker implements FoodMaker {

    private SandwichFiller filler;
    private String currentSandwich;

    public void setSandwichFiller(SandwichFiller filler) {
        this.filler = filler;
    }

    public void setNameOfSandwich(string currentSandwich) {
        this.currentSandwich = currentSandwich;
    }

    public void makeSandwiches() {
        //make sandwiches using the SandwichFiller
    }
}

Now of course, the actual SandwichFiller is going to depend on what kind of sandwiches you want to make. So you might have a different implementation of the SandwichFiller class for a bagel shop than you would for a submarine shop. When you instantiate the SandwichMaker class, you can, of course, provide the appropriate implementation of SandwichFiller by calling the setSandwichFiller() method. But then you would need to change the code to install the SandwichMaker in a new location. Spring enables you to create an application context that includes definitions for these dependencies. (This is why this is sometimes called dependency injection.)

The file might look like Listing 2.


Listing 2. The ApplicationContext.xml file
<beans>

  <bean id="bagel" class="com.sandwiches.BagelShop">
    <property name="breadPreference" value="bagel" />
    <property name="diameter" value="5" />
  </bean>

  <bean id="ccandjFiller" class="com.sandwiches.CreamCheeseAndJellyFiller">
    <property name="sandwichType" ref="bagel" />
    <property name="creamCheesePortion" value="60" />
    <property name="jellyPortion" value="40" />
    <property name="jellyFlavor" value="grape" />
  </bean>

  <bean id="sandwichMaker" class="com.sandwich.SandwichMaker">
    <property name="sandwichFiller" ref="ccandjFiller" />
    <property name="nameOfSandwich" value="Cream Cheese and Jelly" />
  </bean>

</beans>

Okay, let's look at this more closely, starting at the bottom. We've told the environment that when we instantiate the class com.sandwich.SandwichMaker, the property sandwichFiller should be populated by the bean identified as ccandjFiller. That bean is a com.sandwiches.CreamCheesAndJellyFiller, which has its own properties. It has a sandwichType of bagel, which sets the breadPreference to bagel (rather than rye or bialy), and it's five inches wide. Also, we want just a little more cream cheese than grape jelly.

Now, that's an awful lot of customization; if you wanted to program that into the application, it would mean a lot of recompiling when things changed, or a lot of work building in the option to make all those choices. Spring makes it easy to make changes by just altering an XML file. I've chosen a somewhat lighthearted example here, but imagine that you're configuring data sources and all of a sudden this IoC becomes invaluable.


Database advantages

Speaking of data sources, Jeff explained that this is another area in which "Spring has an excellent API that extends many J2EE (and non-J2EE) components, making the developer's life a lot easier.

"Creating Data Access Objects in Spring is relatively simple," he explained. "You extend a couple of Spring classes with your JDBC (or other framework like Hibernate), implement your DAO, then make the declaration in the applicationContext.xml file. You can then inject these DAOs declaratively into your business objects just by making a setter for the DAO and declaring the business object in the Spring XML file."

That much I had learned in our discussion on IoC. But there's more: "By doing this, you do away with having to trap for SQLExceptions and make testing [of a database] as simple as swapping your declarations."

I understood this last part; the database is a property you can easily set in the applicationContext.xml file. But how does it keep you from having to trap for SQLExceptions?

"Spring hides the JDBC SQL issues by converting the SQLExceptions, and so on, to unchecked exceptions. They then also clean up the errors, which makes it so it is very clear what the problem is. It's a much better approach to doing database exceptions."

Basically, when you create a JDBC application, and something goes wrong, you get a SQLException. Unfortunately, that SQLException rarely contains all the information you need to actually find out what went wrong, because the real information is encoded as vendor-specific error codes that you have to track down. And of course, since part of the point here is that you can easily change data sources, coding the intelligence into the application isn't an option. However, by wrapping your database interactions in Spring classes, such as JdbcTemplate, you make sure that any errors are expressed as a DataAccessException, or more importantly, as one of the DataAccessException's dozen or so subclasses, which include DataAccessResourceFailureException, DataIntegrityViolationException, and OptimisticLockingFailureException. This way you can code your application much more intelligently.


Hidden classes prevent clashes

Well, that was a lot of information about Spring, but what about Geronimo? Did the team have to do any special work to integrate it into the application server?

"I believe Bruce Snyder and Aaron Mulder wrote a Spring plug-in for the Apachecon 2006 presentation they gave on plug-ins, but outside of that, Spring is really an API, so with Spring, you can place it into our repository, and it's available to all to use."

In other words, they didn't have to do anything special; Spring is just available as long as it's in the repository.

But that's not the end of the story. Jeff continued, "One of the biggest complaints people have on other application servers is that you need to place Spring in the server's classpath, and when you also include it in your Web application" -- as you must do if your application uses a different version of Spring than the server has installed -- "you get a clash of which Spring is being used. It's part of the parent-child, child-parent classloading dichotomy of J2EE apps."

The problem is that in some situations, Java™ 2 Platform, Enterprise Edition (J2EE) or Java Platform, Enterprise Edition (Java EE) starts at the most specific level looking for a class to instantiate (in which case it uses the classes that are part of the application), and in others it uses the most general (in which case it uses the classes that are part of the server). The result is that you might create a resource in the context of the application, but when you try to access it, the server is looking in the context of the application server.

"This will make your apps not find [their] Hibernate resources, etcetera, because they get created in one Spring container and accessed in another."

Originally, the Geronimo developers solved this problem by auto-hiding certain common classes, such as Spring and Apache Commons Logging, a frequent cause of this trouble. But things came to a head with Liferay, an open source JSR 168-compliant portal (see Resources for a link). Liferay uses Spring and includes a version of Spring in the .ear file for all of the sub-applications deployed in it. "The reason I mention them," Jeff told me, "is that our hidden classloading architecture caused a problem early on because we were auto-hiding Spring so their Web apps couldn't see the EAR-level version of Spring."

Finally, the Geronimo developers hit on a solution. "But we have one better thing than most other app servers. Many people run into issues regarding commons logging. When they run in a container that uses commons logging, like JBoss, Tomcat, etcetera, and they include the commons-logging JAR [file] in their app, they run into nasty exceptions." These are the same problems encountered by Spring applications before the initial changes. "It really is a matter of classloaders clashing. We had a few open issues saying Web apps didn't work, but they did; they just needed to remove commons logging, like needed to be done for Tomcat and JBoss, etcetera. So we had a lot of discussions and started to hardcode blocking classes like commons logging. Discussion ensued, and we figured a declarative approach was much better. And thus the hidden classes declaration was born. We have the ability to declare hidden classes in our plan files, which you use to deploy your apps."

"It works great," he continued. "So we don't have the problem many other containers have. You control the classloader for parent-child child-parent delegation. So with Geronimo you can declare that your app only uses the Spring that is included in your app, ignores the server version, or vice versa. The other positive about that is you can use multiple versions of Spring. So if the server is using 2.0 and your legacy app used 1.x, you can ensure no clashing will occur, and your app uses the proper version."


Adding more to Apache Geronimo for Spring

While Spring may have been what pushed the team to make these changes, they're useful for any class for which this might be a problem. But that doesn't mean that Spring-specific work won't one day end up in Geronimo.

"Now I was just talking with Bruce Snyder," Jeff told me after wrapping up a phone call while I grabbed a quick bite. "We were talking about building or extending a plug-in to allow you to place Spring ApplicationContexts in the JNDI, so you could have server-wide access to Spring-based objects. I have written this for a client and think it should be a core function for an app server. It's a matter of getting time to do it," he said, smiling.

"At some point we will do it," he said. "It's nice to offer server-based Spring objects to applications. You could store specific objects or references to objects for Spring that you want your applications to have access to. For example, if you are using Quartz, and you want a reference to the container, and you created objects via Spring, you may need access to the ApplicationContext that has a reference to that object, thus it needs to be widely available. Storing it in the JNDI will give your applications access to other ApplicationContexts that were started in another context. This would be huge for Service-Oriented Architecture- and enterprise service bus-based applications, which is where I developed this before. I guess in a nutshell, to put it more directly, it's good for applications that aren't connected but need access to common resources. That's the best way to put it. SOA apps need this functionality."


Summary

We talked a bit longer about all the hard work the Geronimo committers and community were doing, and I took my leave, finally understanding what all the fuss is about. Spring seems to be a pretty handy framework to have around. It's obvious how IoC and dependency injection can make my life a whole lot easier when applications require any sort of configuration change, and I've wasted way too many hours of my life trying to decipher SQLExceptions not to appreciate Spring's approach to data access. What's more, I learned something about classloaders and why I sometimes get errors that seem to defy any sort of problem solving, so I definitely appreciate Geronimo's hidden class declaration.

Now if somebody could just explain the big deal about JavaServer Faces (JSF) technology.


Resources

Learn

Get products and technologies

Discuss

About the author

Nicholas Chase has been involved in Web-site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. He has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the chief technology officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sams).

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, Java technology, WebSphere
ArticleID=198033
ArticleTitle=The Geronimo renegade: Ease data access and configuration issues with the Spring Framework
publish-date=02272007
author1-email=ibmquestions@nicholaschase.com
author1-email-cc=

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