Senior Consultant at Interface21
Ben Hale is a senior consultant for Interface21, the company behind the Spring Framework and the Spring family of products. Ben's specialties include middle tier architecture with an emphasis on integration technologies such as JMS and JMX. Leading up to his role at Interface21 Ben has led teams in the architecture and development of large-scale enterprise management applications.SpringSource Team Blog
The voice of SpringSource
Monday, November 26, 2007

By popular demand, the Spring Framework Maven artifacts are now being uploaded to the Spring Snapshot Maven Repository. You can find details about all of the Spring Portfolio Maven repositories in my previous post but I'll reprint the details for the Spring snapshot repository here.
The Spring Snapshot Maven Repository is located at http://s3.amazonaws.com/maven.springframework.org/snapshot. Using this repository requires you to add an entry to the <repositories/> element in your POM. It should look like this:
<id>spring-snapshot</id>
<name>Spring Portfolio Snapshot Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/snapshot</url>
</repository>
The artifacts in this repository do not follow expected repository behaviors and will be removed regularly. At least the last 10 snapshot builds for a given artifact will be retained. If an artifact is removed from a distribution its snapshot builds will be removed immediately. On the release of a milestone or a final release, all snapshots for an artifact will be removed and a new snapshot for the next release created.
Tuesday, September 18, 2007

Up to this point the Spring Portfolio Maven artifacts, especially the snapshots, were inconsitently created and scattered about in various locations. Over the past couple of weeks, we've been working to get the projects to be more consistent in the creation and uploading of these artifacts.
Maven Repositories
One of the most useful improvements to the Maven support in the Spring Portfolio is the use of consistent repository locations. There are three different repositories depending on your level of comfort with the code.
Release Repository
For any final release (Spring 2.5, Spring Web Flow 2.0, etc.) the Maven artifacts for that release will be uploaded to the Maven Central repository (http://repo1.maven.org/maven2). Using this repository requires no effort on your part as Maven will automatically look for artifacts there.
The artifacts in this repository do follow expected repository behaviors and will not (and cannot) not be removed.
Milestone Repository
For any milestone release (Spring 2.5-RC1, Spring Web Flow 2.0-M2, etc.) the Maven artifacts for that release will be uploaded to the the Spring Milestone repository (http://s3.amazonaws.com/maven.springframework.org/milestone). Using this repository requires you to add an entry to the <repositories/> element in your POM. It should look like this:
<id>spring-milestone</id>
<name>Spring Portfolio Milestone Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/milestone</url>
</repository>
The artifacts in this repository do not follow expected repository behaviors and will be removed regularly. Upon the release of a final version (Spring 2.6, Spring Web Flow 2.1, etc.) all milestone versions from the previous release of an artifact will be removed. For example, when Spring 2.6 is released, Spring 2.5 milestones will be removed while Spring 2.6 milestones will be retained.
Snapshot Repository
For any snapshot build (Spring 2.5-SNAPSHOT, Spring Web Flow 2.0-SNAPSHOT, etc.) the Maven artifacts for that build will be uploaded to the Spring Snapshot repository (http://s3.amazonaws.com/maven.springframework.org/snapshot). Using this repository requires you to add an entry to the <repositories/> element in your POM. It should look like this:
<id>spring-snapshot</id>
<name>Spring Portfolio Snapshot Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/snapshot</url>
</repository>
The artifacts in this repository do not follow expected repository behaviors and will be removed regularly. At least the last 10 snapshot builds for a given artifact will be retained. If an artifact is removed from a distribution its snapshot builds will be removed immediately. On the release of a milestone or a final release, all snapshots for an artifact will be removed and a new snapshot for the next release created.
Repository Browsing
The milestone and snapshot repositories are both hosted on Amazon's S3 service and as such the directory structure is not human-readable. To view the repositories in a human-readable format, use the S3Browse utility.
- Milestone Repository: http://s3browse.com/explore/maven.springframework.org/milestone
- Snapshot Repository: http://s3browse.com/explore/maven.springframework.org/snapshot
Only use these URLs for human-readable viewing. If you use them as the URLs for your POMs you will encounter errors.
Artifact Sources
Another important improvement is the addition of source artifacts for all releases. You will notice in the milestone repository all artifacts have sources deployed with them. This will also be true as we go forward for all final releases as well. Specifically, starting with the Spring 2.5 release, in addition to the combined Spring sources, each module will also have a source artifact.
Spring Snapshots
The final improvement is one that isn't yet complete; a nightly snapshot of Spring. I'm pleased to say that this is close to being completed. I'm still working out the final kinks with respect to the Maven Ant Tasks but this will eventually start showing up and I'll announce it again when it does. As well, you can expect this functionality to eventually make its way out to all of the other ANT-based Spring Portfolio projects so that all projects will create Maven snapshots as well as milestones.
Friday, June 1, 2007

With the release of Spring 2.1-m2, some significant changes have been made to the infrastructure of the Spring distribution. Please see the announcement and changelog for the complete list of changes.
Distribution
The distribution has been trimmed from 26 JARs in 2.1-m1 to 17 JARs in 2.1-m2. Take a look at the changelog for the list of files that changed, but from the commit message, here's what's new:
- spring-context.jar includes JMX support and core remoting support (no spring-jmx and spring-remoting jars anymore)
- spring-orm.jar combines all ORM support packages (replaces spring-hibernate, spring-ibatis, spring-jdo, spring-jpa, and spring-toplink jars)
- spring-web.jar contains web-related remoting and ORM classes (for proper use in J2EE EAR deployment structures)
- renamed spring-dao.jar to spring-tx.jar, also containing the JCA support now
- renamed spring-support.jar to spring-context-support.jar
- renamed spring-portlet.jar to spring-webmvc-portlet.jar
- module jar files contain module-specific "spring.handlers" and "spring.schemas" files now
Maven Artifacts
I'm also pleased to announce that starting with the 2.1-m2 release, each Spring module will now have source jars in the Maven repository. The 2.1-m2 Maven artifacts are located in a private snapshot repository at this point, but the final release will be in the main Maven repo. If you would like to start using 2.1-m2 in your Maven project add a repository location to your POM that points at https://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-snapshots/. If you are using any Maven IDE support, please also download the source jars and open any issues with them at our JIRA.
Tuesday, May 8, 2007

I've recently finished up an interesting issue in Spring Web Flow. This issue (SWF-163) dealt with adding Spring 2.0 bean scoping support for Spring Web Flow's internal scopes. The implementation isn't really that interesting (the Scope interface is pretty easy to implement after all), but I wanted to mention exactly how you would use something like this in your application.
Spring 2.0 Scoping
In Spring 1.x, we had the idea of singleton and prototype bean scopes, but the notation was fixed and not especially descriptive with singleton="[true | false]". So in Spring 2.0, this notation was removed from the XSD style of configuration and now you see a notation that is more clear with scope="[singleton | prototype | …]". Spring itself adds three more bean scopes; request, session, and globalSession which are related to web applications.
With the latest snapshots of Spring Web Flow 1.1, we now see bean scopes for the three major Web Flow scopes, flash, flow, and conversation.
<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="flow"/>
<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="conversation"/>
To utilize these bean scopes you'll need to leverage the a new 1.1 version of the configuration (included in the Web Flow jar) and add a single element to your bean definition.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.1.xsd">
<flow:enable-scopes/>
<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="conversation"/>
</beans>
The <enable-scopes/> tag only needs to exist once in a given application context and will allow you to use any of the three scopes contributed by Spring Web Flow.
Scoped Beans and JSF
Right now the most compelling use of these new scopes is in JSF. By using the scope notation in a standard Spring bean definition file instead of the <var/> notation in a flow definition, the experience for JSF users is much closer to standard JSF behavior. To add this ability to JSF you register the standard Spring JSF DelegatingVariableResolver. The other definitions (FlowNavigationHandler, and FlowPhaseListener) are standard for using JSF with Spring.
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<application>
<navigation-handler>
org.springframework.webflow.executor.jsf.FlowNavigationHandler
</navigation-handler>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
<lifecycle>
<phase-listener>
org.springframework.webflow.executor.jsf.FlowPhaseListener
</phase-listener>
</lifecycle>
</faces-config>
The major change from the previous Web Flow enabled configuration is that now the variable resolver is the one from Spring and not Spring Web Flow. When a JSP page looks for a sale variable, JSF will delegate to Spring for bean resolution and the bean instance will be scoped according to the scope attribute on its definition.
Conclusion
The end result of this is that now JSF users can now use a syntax similar to the built-in style but in a container that is much more powerful.
If you'd like to use this new functionality, it will be coming shortly with the Spring Web Flow 1.1-m1 release, or you can get a preview by downloading the latest Spring Web Flow 1.1-m1 nightly snapshot.
Monday, April 30, 2007

In a previous post, I described how we use a custom ANT task to upload nightly snapshots from the ANT based projects in the Spring portfolio. In this post I'll describe how we use Amazon S3 to generate pages for the snapshots from each project and allow users to download the snapshots.
As I mentioned in the previous post, S3 is primarily used as a REST-ful service. This means that while I used Java for the upload portion, I was free to use other languages for the download portion. I chose to use PHP in this case because it was already available on the server I was working with, and was the path of least resistance.
There were two parts for this effort. The first was that I needed to query the Amazon S3 service for the list of snapshots for a given Spring project. To do this, you create a REST query with a prefix parameter:
Now that you've seen the basic way to query, I want to go back to the previous example and point out some important parts of the upload definition:
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release-with-dependencies.zip}"
toFile="SPR/spring-framework-${spring-version}-with-dependencies-${tstamp}-${build.number}.zip"
publicRead="true"/>
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release.zip}"
toFile="SPR/spring-framework-${spring-version}-${tstamp}-${build.number}.zip"
publicRead="true"/>
</aws:s3>
The first thing that you'll notice is that for the Spring artifacts, I've chosen to prefix them with SPR. The name of the file is essentially free form, so using slashes, you can create a virtual directory structure to query against. If you take a look at the builds for Spring Web Flow, you'll see its artifacts are prefixed with SWF, Spring LDAP's artifacts get LDAP, and Spring Modules' artifacts get MOD. So now by customizing our query parameters, we can choose one project specifically.
The second thing to notice is the publicRead=true declaration. By default, S3 does not allow anyone to view or download from your bucket. You can give them permission by using your secret and access keys to create a token that will allows downloads. For this effort though, I deemed that unnecessary. The snapshots are publicly accessible, so I loosened the security and allowed them to be downloadable without the token.
Now you can call the S3 REST service and get a properly filtered list of items in the bucket, but the response is in raw XML. Even though I'm a Spring developer, looking through raw XML in a web browser doesn't excite me.
So the next step in the process is to transform the XML into a useful HTML page. I had two choices at this point. I could execute the transform on the server to generate HTML and then return it to the user, or I could return the XML to the user along with an XSLT file and let the users browser do the transform for me. Now I'll be honest, the latter lightens the load on the server and actually allows the user's browser to cache the transform for performance. But the reality is, I just didn't have access to the XSLT PHP libraries so I couldn't do the server-side transform if I wanted to. I realize that some older browsers will have trouble with this setup, but we'll cross that bridge when we get to it.
So I needed to take the returned XML:
<Name>static.springframework.org</Name>
<Prefix>SPR</Prefix>
<Marker/>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070411-50.zip</Key>
<LastModified>2007-04-11T13:27:34.000Z</LastModified>
<ETag>"1ab20ad18ca0edb4a360279f27409d54"</ETag>
<Size>10725241</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070411-51.zip</Key>
<LastModified>2007-04-12T01:25:58.000Z</LastModified>
<ETag>"de2e5833ae8fe4cc06987935bea06e57"</ETag>
<Size>10727049</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070412-52.zip</Key>
<LastModified>2007-04-13T01:22:23.000Z</LastModified>
<ETag>"414b947226fc4e08bd118e0f16a6be67"</ETag>
<Size>10736732</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
…
and turn it into HTML:

Most of the content returned from the service isn't useful to this effort, and so the XSLT becomes very simple:
<head>
<style type="text/css" media="all">@import "./snapshot-download.css";</style>
</head>
<body>
<xsl:apply-templates select="s3:ListBucketResult"/>
</body>
</xsl:template>
<xsl:template match="s3:ListBucketResult">
<xsl:variable name="bucket-name" select="s3:Name"/>
<table>
<tr>
<th class="name"><xsl:value-of select="s3:Prefix"/> Project Snapshots</th>
<th class="size">Size</th>
</tr>
<xsl:for-each select="s3:Contents">
<tr>
<td class="name">
<a class="name" href="http://s3.amazonaws.com/{$bucket-name}/{s3:Key}">
<xsl:value-of select="substring-after(s3:Key, '/')"/>
</a>
</td>
<td class="size"><xsl:value-of select="format-number(s3:Size div 1048576, '###,###.0')"/> MB</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
The transform starts with some HTML declarations and then iterates over each of the bucket's items. Then it uses the object identifier to create a link to the file on the S3 servers. That's it. The PHP page calls S3 for the XML and then passes it along with an XSLT declaration to the user's browser:
$prefix = $HTTP_GET_VARS["project"];
$url = "http://s3.amazonaws.com/static.springframework.org/?prefix=$prefix";
$xml = file_get_contents($url);
header('Content-Type: text/xml; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<?xml-stylesheet type="text/xsl" href="./snapshot-download.xsl"?>';
echo substr($xml, 39);
?>
Add a little customization for each project with a request parameter and you get individual download pages for each project:
- http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR
- http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SWF
- http://static.springframework.org/downloads/nightly/snapshot-download.php?project=LDAP
- http://static.springframework.org/downloads/nightly/snapshot-download.php?project=MOD
This completes my exploration of the Amazon S3 service. I can say from experience now that if you have a ton of data and a lot of bandwidth needs there aren't many places that will give you better rates. And with the REST-ful interface, it's flexible enough to use with your favorite language. Thank you for having me, and I'll take any questions now.