<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkcHQHY6fyp7ImA9WhRWFEU.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642</id><updated>2012-01-02T07:00:31.817+01:00</updated><category term="scripting" /><category term="hibernate" /><category term="acegi" /><category term="jdbc" /><category term="java" /><category term="security" /><category term="beanshell" /><category term="junit" /><category term="aop" /><category term="best practices" /><category term="web services" /><category term="CoC" /><category term="ear" /><category term="log4j" /><category term="mvc" /><category term="test" /><category term="osgi" /><category term="struts" /><category term="agile" /><category term="ehcache" /><category term="ejb" /><category term="groovy" /><category term="xfire" /><category term="spring" /><category term="tips" /><category term="remoting" /><category term="jta" /><category term="performance" /><category term="jruby" /><category term="jotm" /><category term="webapp" /><category term="jmx" /><category term="ioc" /><title>Spring Tips</title><subtitle type="html">A spring framework knowledge base discussing different topics of the spring portfolio and technologies around spring (IoC, AOP, OSGi, Hibernate, Groovy, JMX ...)</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://springtips.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/SpringTips" /><feedburner:info uri="springtips" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;AkYBR3o_eyp7ImA9WxRRFEs.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-2144017659110350021</id><published>2008-09-27T00:29:00.001+02:00</published><updated>2008-09-27T00:29:16.443+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-27T00:29:16.443+02:00</app:edited><title>Configuring applications with Spring</title><content type="html">&lt;p&gt;If you&amp;#8217;ve used Spring before, you&amp;#8217;ve almost definitely used a PropertyPlaceholderConfigurer to inject settings from external sources &amp;#8212; most likely properties files &amp;#8212; into your application context. The most common use cases include JDBC and Hibernate settings, but it&amp;#8217;s not that uncommon to also configure Lucene index, temp file, or image cache directories as well. The simplest case looks something like this:&lt;/p&gt;  &lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;location&amp;quot; value=&amp;quot;classpath:application.properties&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&amp;#160;&amp;#160; &amp;lt;!-- A sample bean that needs some settings. --&amp;gt;
&amp;lt;bean id=&amp;quot;dataSource&amp;quot; class=&amp;quot;org.springframework.jdbc.datasource.DriverManagerDataSource&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;driverClassName&amp;quot; value=&amp;quot;${jdbc.driver}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;url&amp;quot; value=&amp;quot;${jdbc.url}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;username&amp;quot; value=&amp;quot;${jdbc.username}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;${jdbc.password}&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;And application.properties might look like this:&lt;/p&gt;

&lt;pre&gt;jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:mem:example
jdbc.username=sa
jdbc.password=&lt;/pre&gt;

&lt;p&gt;Note, you can achieve the same simple configuration using the new spring 2.x style schema configuration, but it doesn&amp;#8217;t allow for any further customization so we&amp;#8217;re going to use the old style.&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- Example of new Spring 2.x style --&amp;gt;
&amp;lt;context:property-placeholder location=&amp;quot;classpath:application.properties&amp;quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;This handles the simple case of replacing placeholders (e.g. ${jdbc.url}) with values found in a properties files (e.g. jdbc.url=jdbc:h2:mem:example). In a real-world application, we not only need to collect settings, but also override them in different environments. Many of our applications are deployed in 4 or more environments (developer machine, build server, staging server, and production), each requiring different databases at the very least.&lt;/p&gt;

&lt;p&gt;There are a few ways to enable overriding of properties. Let&amp;#8217;s take a look at them in turn:&lt;/p&gt;

&lt;h6&gt;1. Setting the system properties mode to override (default is fallback)&lt;/h6&gt;

&lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;systemPropertiesModeName&amp;quot; value=&amp;quot;SYSTEM_PROPERTIES_MODE_OVERRIDE&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;location&amp;quot; value=&amp;quot;classpath:application.properties&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;When configured in this mode, any value specified as a system property to the JVM will override any values set in properties files. For example, adding -Djdbc.url=jdbc:h2:mem:cheesewhiz to the JVM arguments would override the value in the file (jdbc:h2:mem:example). On a Java 1.5 or newer platform, Spring will also look for an environment variable called jdbc.url is no system property was found.&lt;/p&gt;

&lt;h6&gt;2. Specifying an optional properties file&lt;/h6&gt;

&lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;ignoreResourceNotFound&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;
        &amp;lt;list&amp;gt;
            &amp;lt;value&amp;gt;classpath:application.properties&amp;lt;/value&amp;gt;
            &amp;lt;value&amp;gt;classpath:local.properties&amp;lt;/value&amp;gt;
        &amp;lt;/list&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;When &lt;i&gt;ignoreResourceNotFound&lt;/i&gt; is set to true, Spring will ignore resources that don&amp;#8217;t exist. You can imagine application.properties, containing all of the default settings, versioned in your SCM system. Developers have the option of creating a properties file called local.properties to override any settings that differ in their environment. This file should be unversioned and ignored by your SCM system. This works because properties are loaded in order and replace previous values.&lt;/p&gt;

&lt;h6&gt;3. Web Application overrides&lt;/h6&gt;

&lt;p&gt;In a web application environment, Spring also supports specifying values in web.xml as context params or in your application server specific meta-data as servlet attributes. For example, if you&amp;#8217;re using Tomcat you can specify one or more parameter elements in your context.xml, and Spring will can inject those values into placeholders.&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;location&amp;quot; value=&amp;quot;classpath:application.properties&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;The ServletContextPropertyPlaceholderConfigurer conveniently works in non servlet environments by falling back to the behavior of a PropertyPlaceholderConfigurer. This is great when running unit tests.&lt;/p&gt;

&lt;h6&gt;4. Combining techniques&lt;/h6&gt;

&lt;p&gt;There&amp;#8217;s no reason why these techniques can&amp;#8217;t be combined. Technique #1 is great for overriding a few values while #2 is better for overriding many. #3 just expands the field of view when Spring goes to resolve placeholders. When combined, system properties override those in files. When using technique #3, there are some settings available for adjusting the override behavior (see contextOverride). Test the resolution order when combining to ensure it&amp;#8217;s behaving as expected.&lt;/p&gt;

&lt;h6&gt;Optional External Properties&lt;/h6&gt;

&lt;p&gt;There&amp;#8217;s another use case that applies to some projects. Often in non-developer environments, system admins want to keep properties for the environment outside of the deployable archive or the application server, and they don&amp;#8217;t want to deal with keeping those files in a Tomcat context file; they prefer a simple properties file. They also don&amp;#8217;t want to have to place the file in a hard-coded location (e.g. /var/acmeapp/application.properties) or they may keep configuration for multiple servers in the same network directory, each file names after the server. With a little trickery, it&amp;#8217;s easy to support an optional external properties file that isn&amp;#8217;t in a hard-coded location. The location of the file is passed as a single system property to the JVM, for example: -Dconfig=file://var/acmeapp/server1.properties. Here&amp;#8217;s the configuration to make it happen:&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;ignoreUnresolvablePlaceholders&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&amp;#160;&amp;#160; &amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;ignoreResourceNotFound&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;location&amp;quot; value=&amp;quot;${config}&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;The first definition enables basic property resolution through system properties (in fallback mode). The second bean loads the resource from the location resolved from the system property -Dconfig. All spring resource urls are supported, making this very flexible.&lt;/p&gt;

&lt;h6&gt;Putting it all together&lt;/h6&gt;

&lt;p&gt;Here&amp;#8217;s a configuration that does more than most people would need, but allows for ultimate flexibility:&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;ignoreUnresolvablePlaceholders&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&amp;#160;&amp;#160; &amp;lt;bean class=&amp;quot;org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;systemPropertiesModeName&amp;quot; value=&amp;quot;SYSTEM_PROPERTIES_MODE_OVERRIDE&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;searchContextAttributes&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;contextOverride&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;ignoreResourceNotFound&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;
        &amp;lt;list&amp;gt;
            &amp;lt;value&amp;gt;classpath:application.properties&amp;lt;/value&amp;gt;
            &amp;lt;value&amp;gt;classpath:local.properties&amp;lt;/value&amp;gt;
            &amp;lt;value&amp;gt;${config}&amp;lt;/value&amp;gt;
        &amp;lt;/list&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;Every placeholder goes through the following resolution process. Once a value is found it&amp;#8217;s set and the next placeholder is resolved:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;(optional) Property value specified as a system or environment property; useful for overriding specific placeholders (e.g. -Djdbc.host=devdb / -Djdbc.username=carbon5) &lt;/li&gt;

  &lt;li&gt;(optional) Context parameters located in web.xml or context attributes specified in application server meta-data (e.g. a Tomcat context.xml). &lt;/li&gt;

  &lt;li&gt;(optional) Properties file located by the system/environment variable called &amp;#8220;config&amp;#8221;; useful for externalizing configuration. All URL types are supported (e.g. -Dconfig=c://hmc.properties). &lt;/li&gt;

  &lt;li&gt;(optional) Properties file identified by classpath:local.properties; useful for specific developer overrides. &lt;/li&gt;

  &lt;li&gt;(required) Properties file identified by classpath:application.properties, which contains default settings for our application. &lt;/li&gt;
&lt;/ol&gt;

&lt;h6&gt;Best Practices&lt;/h6&gt;

&lt;ul&gt;
  &lt;li&gt;Deploy the same exact artifact (e.g. war, ear, etc) across all environments by externalizing configuration. This may seem daunting, but the emergent benefits are huge in terms of simplicity. &lt;/li&gt;

  &lt;li&gt;Only make things that can safely change across environments configurable. Also, only things that need to be configurable should be configurable, it&amp;#8217;s easy to go overboard. &lt;/li&gt;

  &lt;li&gt;Configure the minimal properties search path that meets your requirements. &lt;/li&gt;

  &lt;li&gt;When looking for properties files in the project tree, use classpath resources whenever possible. This makes finding those files easy, consistent, and insensitive to the working-dir, which is great when running tests from your IDE and command line. &lt;/li&gt;

  &lt;li&gt;Aim for a zero-configuration check-out, build, run-tests cycle for the environment where its happens most: development. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What other interesting configuration scenarios have you seen?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by christian&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-2144017659110350021?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q4E0tcaNMvYBjIrxxJXQ1YV7iVw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q4E0tcaNMvYBjIrxxJXQ1YV7iVw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q4E0tcaNMvYBjIrxxJXQ1YV7iVw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q4E0tcaNMvYBjIrxxJXQ1YV7iVw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/I0hrn8sThvA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/2144017659110350021/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=2144017659110350021" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/2144017659110350021?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/2144017659110350021?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/I0hrn8sThvA/configuring-applications-with-spring.html" title="Configuring applications with Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/09/configuring-applications-with-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IDR3c5fCp7ImA9WxRSEEs.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-3483800053185277362</id><published>2008-09-10T19:59:00.001+02:00</published><updated>2008-09-10T19:59:36.924+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-10T19:59:36.924+02:00</app:edited><title>Lazy loading vs. pre-loading beans with Spring Framework</title><content type="html">&lt;p&gt;Spring framework can instantiate and bind (called loading) related Java objects (called beans) according to a given configuration. An XML file can easily be used to define these bindings. Spring framework supports two different types of loading methods; lazy loading and pre-loading respectively managed by BeanFactory and ApplicationContext containers.&lt;/p&gt;  &lt;h4&gt;Lazy Loading&lt;/h4&gt; A bean is loaded only when an instance of that Java class is requested by any other method or a class. org.springframework.beans.factory.BeanFactory (and subclasses) container loads beans lazily. Following code snippet demonstrate lazy loading, concentrate on how &amp;quot;beans.xml&amp;quot; spring configuration file is loaded by BeanFactory container class.   &lt;pre&gt;BeanFactory factory = new XmlBeanFactory(&lt;br /&gt;                        new InputStreamResource(&lt;br /&gt;                        new FileInputStream(&amp;quot;beans.xml&amp;quot;))); // 1&lt;br /&gt;Employee emp = (Employee) factory.getBean(&amp;quot;employeeBean&amp;quot;); // 2&lt;/pre&gt;

&lt;p&gt;Even though &amp;quot;beans.xml&amp;quot; configuration file is loaded with BeanFactory container in line number 1, none of the beans will be instantiated. Instantiation takes place only at line number 2, where bean called &amp;quot;employeeBean&amp;quot; is requested from container. Since the class is instantiated at getBean() method call, time spend to return this method will vary depending on the instantiated object.&lt;/p&gt;

&lt;h4&gt;Pre-loading&lt;/h4&gt;
All beans are instantiated as soon as the spring configuration is loaded by a container. org.springframework.context.ApplicationContext container follows pre-loading methodology. 

&lt;pre&gt;ApplicationContext context =&lt;br /&gt;            new ClassPathXmlApplicationContext(&amp;quot;beans.xml&amp;quot;); // 1 &lt;br /&gt;Employee emp = (Employee) context.getBean(&amp;quot;employeeBean&amp;quot;); // 2&lt;/pre&gt;

&lt;p&gt;As all singleton beans are instantiated by container at line number 1, this line will take some considerable time to complete. However line number 2 will return the bean instance immediately since instances are already available inside the container.&lt;/p&gt;

&lt;h4&gt;Point to note&lt;/h4&gt;

&lt;p&gt;Decision to choose one from these two methods would depend solely on application specific requirements. Some applications need to load as soon as possible while many others would probably willing to spend more time at startup but serve client requests faster. However some of the beans defined in a configuration may only be used rarely, so instantiating such classes at start up would not be a wise decision. Similarly, some Java instances would be highly resource consuming; leading not to instantiate at start up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Kamal Mettananda&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-3483800053185277362?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AYmkwSoktxcFVRQZp2KEJDhf-XU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AYmkwSoktxcFVRQZp2KEJDhf-XU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AYmkwSoktxcFVRQZp2KEJDhf-XU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AYmkwSoktxcFVRQZp2KEJDhf-XU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/9zonI4RGHR0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/3483800053185277362/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=3483800053185277362" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3483800053185277362?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3483800053185277362?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/9zonI4RGHR0/lazy-loading-vs-pre-loading-beans-with.html" title="Lazy loading vs. pre-loading beans with Spring Framework" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/09/lazy-loading-vs-pre-loading-beans-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQMRXk-fCp7ImA9WxRTGU0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-5393694701701842879</id><published>2008-09-08T23:13:00.001+02:00</published><updated>2008-09-08T23:13:04.754+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-08T23:13:04.754+02:00</app:edited><title>Using Spring MVC Controllers in Grails</title><content type="html">&lt;p&gt;Groovy is slower than Java and sometimes dramatically slower. Realistically, this has little impact on a web application since response time is affected more by the database and network latency, so as long as the slowdown isn't too dramatic, the benefits of Groovy and Grails far outweigh these concerns. And Grails is still way faster than Rails :)&lt;/p&gt;  &lt;p&gt;But having said that, I was wondering how to use a regular Java &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html"&gt;Spring MVC controller&lt;/a&gt; and JSP instead of a Grails controller and a GSP (both of which use Groovy). Turns out it's pretty easy:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Register the traditional Spring dispatcher servlet in &lt;code&gt;web.xml&lt;/code&gt; (you'll need to have run &lt;code&gt;grails install-templates&lt;/code&gt;). In this example the name (SpringMVC) isn't important, use whatever you want, and I've chosen to map *.action URLs to this controller and let Grails handle the rest: &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;lt;servlet&amp;gt;    &lt;br /&gt;&amp;lt;servlet-name&amp;gt;SpringMVC&amp;lt;/servlet-name&amp;gt;     &lt;br /&gt;&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;     &lt;br /&gt;&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;     &lt;br /&gt;&amp;lt;/servlet&amp;gt;     &lt;br /&gt;&amp;lt;servlet-mapping&amp;gt;     &lt;br /&gt;&amp;lt;servlet-name&amp;gt;SpringMVC&amp;lt;/servlet-name&amp;gt;     &lt;br /&gt;&amp;lt;url-pattern&amp;gt;*.action&amp;lt;/url-pattern&amp;gt;     &lt;br /&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Generate web-app/WEB-INF/SpringMVC-servlet.xml: &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;beans xmlns='http://www.springframework.org/schema/beans'    &lt;br /&gt;&amp;#160;&amp;#160; xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'     &lt;br /&gt;&amp;#160;&amp;#160; xmlns:p='http://www.springframework.org/schema/p'     &lt;br /&gt;&amp;#160;&amp;#160; xmlns:lang='http://www.springframework.org/schema/lang'     &lt;br /&gt;&amp;#160;&amp;#160; xsi:schemaLocation='     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; http://www.springframework.org/schema/beans     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; http://www.springframework.org/schema/beans/spring-beans-2.0.xsd     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; http://www.springframework.org/schema/lang     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; http://www.springframework.org/schema/lang/spring-lang-2.5.xsd'&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id='mvcHandlerMapping'    &lt;br /&gt;class='org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:order='1'&amp;gt;     &lt;br /&gt;&amp;lt;property name='interceptors'&amp;gt;     &lt;br /&gt;&amp;lt;list&amp;gt;     &lt;br /&gt;&amp;lt;ref bean='openSessionInViewInterceptor' /&amp;gt;     &lt;br /&gt;&amp;lt;ref bean='localeChangeInterceptor' /&amp;gt;     &lt;br /&gt;&amp;lt;/list&amp;gt;     &lt;br /&gt;&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id='mvcViewResolver'    &lt;br /&gt;class='org.springframework.web.servlet.view.UrlBasedViewResolver'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:viewClass='org.springframework.web.servlet.view.InternalResourceView'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:order='1'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:prefix='/WEB-INF/jsp/'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:suffix='.jsp'     &lt;br /&gt;/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean name='baseSimpleController' abstract='true' p:cacheSeconds='0'/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean name='jspController'    &lt;br /&gt;class='com.foo.spring.controller.JspController'     &lt;br /&gt;parent='baseSimpleController'     &lt;br /&gt;abstract='true'     &lt;br /&gt;/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!-- actions --&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean name='/test.action'    &lt;br /&gt;class='com.foo.spring.controller.TestController'     &lt;br /&gt;parent='baseSimpleController'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; p:successView='test'     &lt;br /&gt;/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean name='/other.action' parent='jspController' p:successView='other' /&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;/beans&amp;gt;&lt;/p&gt;  &lt;p&gt;And that's it. Some notes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the handler mapping uses the id &lt;code&gt;mvcHandlerMapping&lt;/code&gt; since Grails will create one using the standard name of &lt;code&gt;handlerMapping&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;since handler mappings are auto-discovered by default, you need to set the &lt;code&gt;order&lt;/code&gt; attribute to something lower than the Grails mapping's (which uses the default value of &lt;code&gt;Integer.MAX_VALUE&lt;/code&gt;) so this mapping is accessed first &lt;/li&gt;    &lt;li&gt;the &lt;code&gt;HandlerInterceptor&lt;/code&gt;s that are configured for the Grails mapping (OpenSessionInView, LocaleChange) won't be automatically available to this mapping, but it's simple to borrow them since they're registered as beans; you can also add other custom interceptors to the list &lt;/li&gt;    &lt;li&gt;I've created an optional abstract parent controller bean (&lt;code&gt;baseSimpleController&lt;/code&gt;) for simple controllers (single-page, i.e. not form or wizard controllers) &lt;/li&gt;    &lt;li&gt;I've also created a simple controller that just shows a JSP &amp;#8211; this is useful for pages that don't have any controller logic:      &lt;p&gt;package com.foo.spring.controller; &lt;/p&gt;      &lt;p&gt;import javax.servlet.http.HttpServletRequest;        &lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;/p&gt;      &lt;p&gt;import org.springframework.web.servlet.ModelAndView;        &lt;br /&gt;import org.springframework.web.servlet.mvc.AbstractController;&lt;/p&gt;      &lt;p&gt;public class JspController extends AbstractController {&lt;/p&gt;      &lt;p&gt;private &lt;a href="http://www.google.com/search?q=allinurl%3AString+java.sun.com&amp;amp;bntl=1"&gt;String&lt;/a&gt; _successView;&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160; @Override        &lt;br /&gt;protected ModelAndView handleRequestInternal(         &lt;br /&gt;final HttpServletRequest request,         &lt;br /&gt;final HttpServletResponse response) {&lt;/p&gt;      &lt;p&gt;return new ModelAndView(_successView);        &lt;br /&gt;}&lt;/p&gt;      &lt;p&gt;public void setSuccessView(final &lt;a href="http://www.google.com/search?q=allinurl%3AString+java.sun.com&amp;amp;bntl=1"&gt;String&lt;/a&gt; view) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _successView = view;         &lt;br /&gt;}         &lt;br /&gt;}&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I've mapped two sample URLs &amp;#8211; &lt;code&gt;/test.action&lt;/code&gt;, which uses a controller, and &lt;code&gt;/other.action&lt;/code&gt;, which uses &lt;code&gt;JspController&lt;/code&gt; to just show &lt;code&gt;other.jsp&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;Note that it is possible to use JSPs with Grails; Grails looks for a GSP using the specified name, but if it doesn't find one it looks for a JSP (under &lt;code&gt;/WEB-INF/grails-app/views/&lt;/code&gt;) and uses that if it exists. So another option is to use Grails controllers and JSP.&lt;/p&gt;  &lt;p&gt;Big caveat: I haven't used this in production yet &amp;#8211; I'm just prototyping so I'll have this available in the future just in case.   &lt;br /&gt;&lt;/p&gt;  &lt;h6&gt;&lt;a href="http://burtbeckwith.com/blog/?p=58"&gt;original post&lt;/a&gt;&lt;/h6&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-5393694701701842879?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/I3P6wNVNQ4LTi6f40Xgx12pDykY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/I3P6wNVNQ4LTi6f40Xgx12pDykY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/I3P6wNVNQ4LTi6f40Xgx12pDykY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/I3P6wNVNQ4LTi6f40Xgx12pDykY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/ZnDNrYBVofo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/5393694701701842879/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=5393694701701842879" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5393694701701842879?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5393694701701842879?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/ZnDNrYBVofo/using-spring-mvc-controllers-in-grails.html" title="Using Spring MVC Controllers in Grails" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/09/using-spring-mvc-controllers-in-grails.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMNSHw9eyp7ImA9WxRTGUU.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-8239501963703853949</id><published>2008-09-02T09:07:00.003+02:00</published><updated>2008-09-09T21:11:39.263+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-09T21:11:39.263+02:00</app:edited><title>RESTful URLs with Spring MVC and UrlRewriteFilter</title><content type="html">&lt;p&gt;While Spring 3.0 promises to support &lt;acronym&gt;REST&lt;/acronym&gt; style URLs out of the box, it won&amp;#8217;t ship until sometime later this year. Spring 3.0 M1 will offer this functionality for anyone brave enough to work with potentially unstable technologies and should be available soon. And while this is good news for those starting out on new projects (or those willing to undergo a significant refactoring), most won&amp;#8217;t want to migrate their applications just for RESTful URLs. All hope is not lost though, thanks to Paul Tuckey&amp;#8217;s &lt;a href="http://tuckey.org/urlrewrite/"&gt;UrlRewriteFilter&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;With this short tutorial, I&amp;#8217;ll demonstrate how easy it is to configure &lt;tt&gt;UrlRewriteFilter&lt;/tt&gt; for use within your Spring MVC application. I should mention that this technique will work well for just about any Java-based web framework, like JSF or Struts. &lt;/p&gt;  &lt;p&gt;For those of you that want to skip to the end, I&amp;#8217;ve created a small, functional sample application which demonstrates the techniques described in this tutorial. It can be downloaded &lt;a href="http://sziebert.net/software/examples/RESTful.zip"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Getting started, we need to register the filter within our application&amp;#8217;s web.xml file.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;web.xml&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Code:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;  &lt;pre&gt;    &amp;lt;!-- UrlRewriteFilter --&amp;gt;
    &amp;lt;filter&amp;gt;
        &amp;lt;filter-name&amp;gt;UrlRewriteFilter&amp;lt;/filter-name&amp;gt;
        &amp;lt;filter-class&amp;gt;
            org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
        &amp;lt;/filter-class&amp;gt;
        &amp;lt;init-param&amp;gt;
            &amp;lt;param-name&amp;gt;logLevel&amp;lt;/param-name&amp;gt;
            &amp;lt;param-value&amp;gt;WARN&amp;lt;/param-value&amp;gt;
        &amp;lt;/init-param&amp;gt;
    &amp;lt;/filter&amp;gt;

    &amp;lt;!-- UrlRewriteFilter Mapping --&amp;gt;
    &amp;lt;filter-mapping&amp;gt;
        &amp;lt;filter-name&amp;gt;UrlRewriteFilter&amp;lt;/filter-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;/pre&gt;

&lt;p&gt;That out of the way, we can dig into the application itself. Let&amp;#8217;s review an example controller class as it might exist in your application today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SprocketsController.java&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;@Controller
public class SprocketsController {

    private final SprocketService service;

    @Autowired
    public SprocketsController(SprocketService service) {
        this.service = service;
    }

    @RequestMapping(&amp;quot;/sprockets/list.do&amp;quot;)
    public String list(ModelMap model) {
        model.addAttribute(&amp;quot;sprockets&amp;quot;, service.list());
        return &amp;quot;sprocket/list&amp;quot;;
    }

    @RequestMapping(&amp;quot;/sprocket/display.do&amp;quot;)
    public String display(@RequestParam(&amp;quot;sprocketId&amp;quot;) int sprocketId, ModelMap model) {
        model.addAttribute(&amp;quot;sprocket&amp;quot;, service.find(sprocketId));
        return &amp;quot;sprocket/display&amp;quot;;
    }

    @RequestMapping(&amp;quot;/sprocket/edit.do&amp;quot;)
    public String edit(@RequestParam(&amp;quot;sprocketId&amp;quot;) int sprocketId, ModelMap model) {
        model.addAttribute(&amp;quot;sprocket&amp;quot;, service.find(sprocketId));
        return &amp;quot;sprocket/edit&amp;quot;;
    }
}&lt;/pre&gt;

&lt;p&gt;Our controller contains actions for displaying a list of sprockets, drilling down into each sprocket&amp;#8217;s details and editing an individual sprocket. Each action is mapped to a URI path via the &lt;tt&gt;@RequestMapping&lt;/tt&gt; annotation and, as you can see, all three defined here handle requests mapped to the &lt;tt&gt;*.do&lt;/tt&gt; extension. The beauty of the solution I&amp;#8217;m demonstrating here is that you should not need to make any changes to your application code at all. That in mind, let&amp;#8217;s move on to the interesting part, configuring our application to respond to a REST style URL like &lt;tt&gt;http://localhost:8080/sprocket/1234/edit&lt;/tt&gt; instead of what we&amp;#8217;ve got now: &lt;tt&gt;http://localhost:8080/sprocket/edit.do?sprocketId=1234&lt;/tt&gt;. You&amp;#8217;ll need to create a new configuration file named &lt;tt&gt;urlrewrite.xml&lt;/tt&gt; and make it available on the classpath. (For those with a distaste for XML based configuration, the latest version of the filter offers a means to generate the configuration via annotations. Details on that can be found &lt;a href="http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/3.1/annotation.html"&gt;here&lt;/a&gt;.) We&amp;#8217;ll start our configuration by defining a few rules to handle the incoming requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;urlrewrite.xml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprockets/$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprockets/list.do&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprocket/([a-z0-9]+)/$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprocket/display.do?sprocketId=$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprocket/([a-z0-9]+)/edit$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprocket/edit.do?sprocketId=$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s take a look at what each one of these rules does. The first rule states that the UrlRewriteFilter should transparently forward each request for &lt;tt&gt;http://localhost:8080/sprockets/&lt;/tt&gt; to the existing application URL of &lt;tt&gt;http://localhost:8080/sprockets/list.do&lt;/tt&gt;. The second and third rules handle the display and edit requests. These 2 rules define simple regular expressions that are parsed out and appended to the destination URI as query string parameters. If you have more than 1 query string parameter, you&amp;#8217;ll need to use &lt;tt&gt;&amp;amp;&lt;/tt&gt; XML entity. (It should be noted that you can use wildcard matching &lt;tt&gt;(*)&lt;/tt&gt; instead, however it lacks some of the flexibility offered by regular expressions.) &lt;/p&gt;

&lt;p&gt;That takes care of the inbound URLs, but we still have a problem. Within our application, we have a number of links which point to the old URL structure. No worries, &lt;tt&gt;UrlRewriteFilter&lt;/tt&gt; tackles this issue with ease. By examining the response, the filter can rewrite the existing links defined within &lt;tt&gt;anchor&lt;/tt&gt; tags, i.e. &lt;tt&gt;&amp;lt;a href=&amp;#8221;&amp;lt;c:url value=&amp;#8217;/sprockets/list.do&amp;#8217;/&amp;gt;&amp;#8221;&amp;gt;Return to the list.&amp;lt;/a&amp;gt;&lt;/tt&gt;. Let&amp;#8217;s take a look at the rule definitions to handle this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;urlrewrite.xml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;    &amp;lt;outbound-rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprockets/list.do$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprockets/&amp;lt;/to&amp;gt;
    &amp;lt;/outbound-rule&amp;gt;
    &amp;lt;outbound-rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprocket/display.do\?sprocketId=([a-z0-9]+)$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprocket/$1/&amp;lt;/to&amp;gt;
    &amp;lt;/outbound-rule&amp;gt;
    &amp;lt;outbound-rule&amp;gt;
        &amp;lt;from&amp;gt;^/sprocket/edit.do\?sprocketId=([a-z0-9]+)$&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/sprocket/$1/edit&amp;lt;/to&amp;gt;
    &amp;lt;/outbound-rule&amp;gt;&lt;/pre&gt;

&lt;p&gt;More or less, these outbound rules are just the inverse of the inbound rule definitions. All it takes is a simple regular expression to parse out the &lt;tt&gt;sprocketId&lt;/tt&gt;. One common gotcha to note here is that you need to add the &lt;tt&gt;\&lt;/tt&gt; character before the start of the query string marked by the question mark. If you don&amp;#8217;t do this, the filter won&amp;#8217;t be able to process your links.&lt;/p&gt;

&lt;p&gt;Pretty easy, right? With your rules in place, fire up your application and give it a try. You can always examine the status of the filter by visiting &lt;a href="http://127.0.0.1:8080/rewrite-status"&gt;http://127.0.0.1:8080/rewrite-status&lt;/a&gt;. If you&amp;#8217;re a bit hesitant to try this out on your own app, fret not, I&amp;#8217;ve created a simple, yet functional sample application which you can use to experiment with. The example source code can be downloaded &lt;a href="http://sziebert.net/software/examples/RESTful.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by &lt;/em&gt;&lt;a href="http://sziebert.net/posts/author/admin/"&gt;&lt;em&gt;Carl Sziebert&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-8239501963703853949?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7oReUUtwLzlkb-ywce9GjaUvBwc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7oReUUtwLzlkb-ywce9GjaUvBwc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7oReUUtwLzlkb-ywce9GjaUvBwc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7oReUUtwLzlkb-ywce9GjaUvBwc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/KGpLP6COvGY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/8239501963703853949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=8239501963703853949" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8239501963703853949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8239501963703853949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/KGpLP6COvGY/restful-urls-with-spring-mvc-and.html" title="RESTful URLs with Spring MVC and UrlRewriteFilter" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/09/restful-urls-with-spring-mvc-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08HRXY9cSp7ImA9WxRTEU0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-756855071749363911</id><published>2008-08-30T15:10:00.001+02:00</published><updated>2008-08-30T15:10:34.869+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-30T15:10:34.869+02:00</app:edited><title>Database Testing with Spring 2.5 and DBUnit</title><content type="html">&lt;p&gt;We&amp;#8217;ve been using &lt;a href="http://www.dbunit.org"&gt;DB Unit&lt;/a&gt; on our Java projects for years and the mechanics of how it&amp;#8217;s used has evolved over time. I&amp;#8217;ve recently spent some time making it work a little nicer for how we typically write database tests. What I&amp;#8217;ve created makes using DBUnit on a project that is already using Spring and the testing support added in Spring 2.5 just a little easier through the application of convention and annotations.&lt;/p&gt;  &lt;p&gt;In general, we&amp;#8217;ve adopted the convention of loading data off the classpath from a flat dataset file named after the test located next to the test on the classpath. For example (in the maven standard directory structure):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;src/test/java/com/acme/TripRepositoryTest.java - Java Test Code &lt;/li&gt;    &lt;li&gt;src/test/resources/com/acme/TripRepositoryTest.xml - DB Unit Data Set for TripRepositoryTest &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For most tests, the data set is loaded inside the test&amp;#8217;s transaction and rolled back when the test completes so that nothing needs to be cleaned up (see &lt;a href="http://www.springframework.net/doc-latest/reference/html/testing.html#testing-tx"&gt;Spring&amp;#8217;s reference&lt;/a&gt;). For other tests &amp;#8212; service or integration tests &amp;#8212; the data is loaded outside of a transaction and must be cleared out manually. Most projects have a mix of both strategies and both should be easily supported.&lt;/p&gt;  &lt;p&gt;When Spring 2.5 came out with its &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/new-in-2.html#new-in-2-other-testing"&gt;new testing framework&lt;/a&gt;, I threw together a custom TestExecutionListener that looks for test methods that are annotated with @DataSet, and when found, loads the data using DB Unit. Here&amp;#8217;s a transaction-per-test example:&lt;/p&gt;  &lt;h6&gt;TripRepositoryImplTest.java - Example transaction-per-test Test Case&lt;/h6&gt;  &lt;pre&gt;@ContextConfiguration(locations = {&amp;quot;classpath:applicationContext.xml&amp;quot;})
public class TripRepositoryImplTest extends AbstractTransactionalDataSetTestCase {
    @Autowired TripRepository repository;&amp;#160;&amp;#160; @Test
    @DataSet
    public void forIdShouldFindTrip() throws Exception {
        Trip trip = repository.forId(2);
        assertThat(trip, not(nullValue()));
    }
}&lt;/pre&gt;

&lt;p&gt;The high-level execution path for this example looks like:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Inject dependencies (DependencyInjectionTestExecutionListener) &lt;/li&gt;

  &lt;li&gt;Start transaction (TransactionalTestExecutionListener) &lt;/li&gt;

  &lt;li&gt;Load dbunit data set from TripRepositoryImplTest.xml (DataSetTestExecutionListener) using the setup operation (default is CLEAN_INSERT) &lt;/li&gt;

  &lt;li&gt;Execute test &lt;/li&gt;

  &lt;li&gt;Optionally cleanup dbunit data using the tear down operation (default is NONE) &lt;/li&gt;

  &lt;li&gt;Rollback transaction (TransactionalTestExecutionListener) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here&amp;#8217;s the trimmed down log output for this test:&lt;/p&gt;

&lt;pre&gt;INFO: Began transaction (1): transaction manager; rollback [true] (TransactionalTestExecutionListener.java:259)
INFO: Loading dataset from location 'classpath:/eg/domain/TripRepositoryImplTest.xml' using operation 'CLEAN_INSERT'. (DataSetTestExecutionListener.java:152)
INFO: Tearing down dataset using operation 'NONE', leaving database connection open. (DataSetTestExecutionListener.java:67)
INFO: Rolled back transaction after test execution for test context (TransactionalTestExecutionListener.java:279)&lt;/pre&gt;

&lt;p&gt;For this to work in its current incarnation, a single datasource must be available for lookup in the application context. One of the interesting details is what to do with the connection used to load the data. The framework assumes that if it&amp;#8217;s a transactional connection it should be left open because whatever started the transaction should do the closing. When it&amp;#8217;s non-transactional it&amp;#8217;s closed after the dataset is loaded. This convention works well for how I typically write my database tests.&lt;/p&gt;

&lt;p&gt;In addition to the @DataSet annotation, we must add the DataSetTestExecutionListener to the set of listeners that are applied to the test class. As in the above example, you can extend AbstractTransactionalDataSetTestCase which does this for you or you can specify the listener using the class-level annotation @TestExecutionListeners (see &lt;a href="http://svn.carbonfive.com/public/christian/spring-dbunit-test-extension/trunk/src/test/java/eg/domain/TripServiceImplTest.java"&gt;example&lt;/a&gt;). It&amp;#8217;s important that the listener is triggered after the TransactionalTestExecutionListener.&lt;/p&gt;

&lt;p&gt;If all test methods use the dataset, then the test class (or super class) can be annotated and every test will load the dataset. Also, if a different dataset should be loaded, the name of the resource can be specified in the annotation (e.g. @DataSet(&amp;#8221;TripRepositoryImplTest-foo.xml&amp;#8221;) or @DataSet(&amp;#8221;classpath:/db/trips.xml&amp;#8221;)). Lastly, the setup and teardown database operations can be overriden (e.g. @DataSet(setupOperation = &amp;#8220;INSERT&amp;#8221;, teardownOperation=&amp;#8221;DELETE&amp;#8221;)).&lt;/p&gt;

&lt;p&gt;This functionality is part of the C5 Test Support package and is available in our maven repository. To use it, first add the C5 Public Maven repository to your pom.xml, and then add the necessary dependencies:&lt;/p&gt;

&lt;h6&gt;pom.xml&lt;/h6&gt;

&lt;pre&gt;&amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
        &amp;lt;id&amp;gt;c5-public-repository&amp;lt;/id&amp;gt;
        &amp;lt;url&amp;gt;http://mvn.carbonfive.com/public&amp;lt;/url&amp;gt;
        &amp;lt;snapshots&amp;gt;
            &amp;lt;updatePolicy&amp;gt;always&amp;lt;/updatePolicy&amp;gt;
        &amp;lt;/snapshots&amp;gt;
    &amp;lt;/repository&amp;gt;
&amp;lt;/repositories&amp;gt;
...
&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.dbunit&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;dbunit&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;2.2.3&amp;lt;/version&amp;gt;
        &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
    &amp;lt;/dependency&amp;gt;&amp;#160;&amp;#160; &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.carbonfive&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;test-support&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;0.6&amp;lt;/version&amp;gt;
        &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
    &amp;lt;/dependency&amp;gt;
    ...
&amp;lt;/dependencies&amp;gt;&lt;/pre&gt;

&lt;p&gt;Check out the &lt;a href="http://svn.carbonfive.com/public/christian/spring-dbunit-test-extension/trunk"&gt;sample application&lt;/a&gt; for details. It&amp;#8217;s mavenized and utilizes an in-memory database. Just check it out of subversion, look over the code, and give it a run using your IDE or from the command-line (mvn install). I&amp;#8217;d be psyched to hear what you think and of course, welcome comments and suggestions.&lt;/p&gt;

&lt;h6&gt;Resources:&lt;/h6&gt;

&lt;ul&gt;
  &lt;li&gt;C5 Test Support Source: &lt;a href="http://svn.carbonfive.com/public/carbonfive/test-support/trunk"&gt;http://svn.carbonfive.com/public/carbonfive/test-support/trunk&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;C5 Test Support Maven Home: &lt;a href="http://mvn.carbonfive.com/public/com/carbonfive/test-support/0.6/"&gt;http://mvn.carbonfive.com/public/com/carbonfive/test-support/0.6/&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Sample Application: &lt;a href="http://svn.carbonfive.com/public/christian/spring-dbunit-test-extension/trunk"&gt;http://svn.carbonfive.com/public/christian/spring-dbunit-test-extension/trunk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;By Carbon Five Community&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-756855071749363911?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uwzRLAM1FBPkAM3cWoTCdIk34I0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uwzRLAM1FBPkAM3cWoTCdIk34I0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uwzRLAM1FBPkAM3cWoTCdIk34I0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uwzRLAM1FBPkAM3cWoTCdIk34I0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/U3N0U9m564k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/756855071749363911/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=756855071749363911" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/756855071749363911?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/756855071749363911?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/U3N0U9m564k/database-testing-with-spring-25-and.html" title="Database Testing with Spring 2.5 and DBUnit" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/08/database-testing-with-spring-25-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4MQXszcSp7ImA9WxdbGUo.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-1001732627007939112</id><published>2008-08-17T13:53:00.001+02:00</published><updated>2008-08-17T13:53:00.589+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-17T13:53:00.589+02:00</app:edited><title>using Spring Web Flow 2</title><content type="html">&lt;p&gt;I have got opportunity to work with Spring WebFlow 2 recently in a project, here I share my personal views on that with you.&lt;/p&gt;  &lt;p&gt;Let me first tell you all nice things about recent spring stack (spring 2.5 and above). Two things which&amp;#160; improved a lot with recent release are: annotation support, specific namespaces.&lt;/p&gt;  &lt;p&gt;Annotations lets you spend your time more on writing code than to wiring components through xml. Off-course spring fails fast if you have messed up a configuration, but still annotations are lot better to avoid that in first place. With improved @Repository, @Service and @Component it&amp;#8217;s easy to configure beans with required specific responsibilities by default.&lt;/p&gt;  &lt;p&gt;Namespace improvements, help to keep the xml configuration minimal and typo-error free. Schema definitions helps to validate you configuration as you type, and also with convention over configuration approach they have reduced the lines of XML we need to wire up objects. If you want to replace a component with your custom implementation, sometimes its easy by using auto-wire option; sometime you have to configure them by the old way (i.e. using beans namespace and manually declaring most of the configuration) which is more painful after you getting used to the new way.&lt;/p&gt;  &lt;p&gt;With &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/testing.html#testcontext-ctx-management"&gt;SpringTest&lt;/a&gt; framework it&amp;#8217;s fairly easy to write integration test cases. With simple annotation spring will automatically loads the application context on the test start up. Also with @Timed you could even clock your test method, and make it fail if it exceeds specified time. And it also supports Transactional test with automatic rollback on default, so if you could write tests which doesn&amp;#8217;t dirties up the database.&lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s come back to the original topic Spring web flow. Spring webflow works as advertised for, i.e. they are for application which has a natural flow behind in business, and UI acts as a way to capture input for the flow and to display something back. Not for an application that has a different requirement than stated above.&lt;/p&gt;  &lt;p&gt;Everything is a flow, each flow has a starting point and a end point, and could have any number of transitions in between. As a part of transition you could go to a sub-flow and come back to the original flow later, but these transitions could only happen at the pre-defined places on the flow. It will be tough to implement a free-flow (random browse) kind of applications with it.&lt;/p&gt;  &lt;p&gt;It serializes all the information you add to the flow context and restores them as you resume a flow after UI interaction, so every object like entities, repositories, and whatever should implement Serializable. This restricts what you could share in the flow context.&lt;/p&gt;  &lt;p&gt;Most of the decision for transition could be easily handled in the flow definition, this avoids creating Action classes which returns just the outcome.&lt;/p&gt;  &lt;p&gt;in JSF UI:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;h:commandButton action=&amp;#8221;save&amp;#8221; /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;in Flow definition:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;view-state &amp;#8230;&lt;/p&gt;    &lt;p&gt;&amp;lt;transition on=&amp;#8221;save&amp;#8221; &amp;gt;&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;expression =&amp;#8221;validator.validate(model)&amp;#8221; /&amp;gt;&lt;/p&gt;    &lt;p&gt;&amp;lt;/transition&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As you could see, you don&amp;#8217;t need to have the Action class which returns outcome &amp;#8217;save&amp;#8217;, you could direct specify a transition on the command button. Ok, now you could ask what if the save has to be returned only on certain condition (say after only validation passes on the entity). For that you could have a expression executed on the transition, the transition will execute only if the validator returns true, if the validator returns false it will come back to the same view. The expression will accept any EL method expression, need not be just a validator. So you could run any action before the transition. As you could see the method executions in the action class are moved to the flow definition. This will look elegant only if the number of calls made at transition is small, or your application is well thought and designed to share less number of information in state, and keeping the method calls down. (Basically this is a nice feature , but would go awry for huge apps, and for apps which there is no certain business flow behind it)&lt;/p&gt;  &lt;p&gt;Spring web flow also supports inheritance of flows, so you could inherit common transition rules from a parent flow. Which is a nice feature to keep the definition DRY as far as possible.&lt;/p&gt;  &lt;p&gt;What makes flow definition looks ugly? Whenever there are more no. of mere actions which is called in the transitions to set a variable, to retrieve a variable from flowScope and setting back to the viewScope or so. One thing I had to do multiple times in flow definitions are to transform a List to dataModel for the UI, so I could use listName.selectedRow to identify item selected by the user.&lt;/p&gt;  &lt;p&gt;Adding this kind of non-business related method executions and transformations, etc ., to the flow definitions makes it bulky, and also alienates the flow from resembling the business definitions. This defeats the very own cause of having a flow definition.&lt;/p&gt;  &lt;p&gt;WebFlow provides convenient default variables like resourceBundle, currentUser, messageContext available in the flow context, which you could refer directly in the flow definition or pass it as arguments to bean action methods, or call actions on them.&lt;/p&gt;  &lt;p&gt;When a root flow ends, all the information will be discarded. This is nice for cleaning unwanted data in the&amp;#160; memory but that also means that you cannot share anything with the user after the flow is ended. Suppose I would like to say that the user have successfully placed an order at the end of the flow, I could not do that! You could ask that why not keep the confirmation as part of the flow, well it depends on what time you are committing the changes to the db, or how you are sharing a persistent context, or even like its just a end message, there should not be interaction after that from the view to end the flow.&lt;/p&gt;  &lt;p&gt;It&amp;#8217;s like redirecting to the home page after successfully placing the order and showing a banner &amp;#8220;Thank you for shopping with us!&amp;#8221;, which is not just possible.&lt;/p&gt;  &lt;p&gt;One last point is that with UrlMapper definition in the configuration you could make a simple url as a starting point of the flow, but otherwise generally can&amp;#8217;t use a RESTFUL GET url to reach a page on the flow.&lt;/p&gt;  &lt;p&gt;What&amp;#8217;s your experience with Spring Web Flow?&lt;/p&gt;  &lt;p&gt;&lt;em&gt;by Srinivasan Raguraman,&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-1001732627007939112?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5LJWbebC_x7zDEr3rDNdqhaXKbs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5LJWbebC_x7zDEr3rDNdqhaXKbs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5LJWbebC_x7zDEr3rDNdqhaXKbs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5LJWbebC_x7zDEr3rDNdqhaXKbs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/I6tZeu_XWjY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/1001732627007939112/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=1001732627007939112" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/1001732627007939112?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/1001732627007939112?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/I6tZeu_XWjY/using-spring-web-flow-2.html" title="using Spring Web Flow 2" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/08/using-spring-web-flow-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AGSHY4cCp7ImA9WxdVGUk.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-2970948570275541947</id><published>2008-07-25T01:22:00.001+02:00</published><updated>2008-07-25T01:22:09.838+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-25T01:22:09.838+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web services" /><title>Spring Web services and Axis2</title><content type="html">&lt;p&gt;As you know &lt;a href="http://ws.apache.org/axis2"&gt;Axis2 &lt;/a&gt;is a Web service framework which has support many things. It has support for scripting languages , it has support for &lt;a href="http://wso2.org/projects/wsas/java"&gt;data services&lt;/a&gt; and it has &lt;a href="http://wso2.org/projects/wsas/java"&gt;support for EJB&lt;/a&gt; , Corba and etc. In addition that since a long time it has support for Spring as well. With that you can deploy Spring bean as Web services in Axis2. Yes I agree it is yet another way of getting the thing done. I also realized that is not enough for spring developers. They need everything works on spring.&lt;/p&gt;  &lt;p&gt;To solve that in &lt;a href="http://wso2.com"&gt;WSO2 &lt;/a&gt;we came up with a solution where we have integrated Axis2 into Spring. When doing this we have convert all the axis2 configurations files into bean descriptors , for example we came up with a set of beans for axis2.xml. With this we have integrated Axis2 smoothly into Spring. After thing anyone can easily expose a bean as a Web service. And get the power of all the other WS* support , such as security , reliability etc. , above all you can get the power of Axis2 while you are in spring container. &lt;/p&gt;  &lt;p&gt;With this approach you can make a bean into a Web service just using following line of codes&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id=&amp;quot;services&amp;quot; class=&amp;quot;org.wso2.spring.ws.WebServices&amp;quot;&amp;gt;    &lt;br /&gt;&amp;lt;property name=&amp;quot;services&amp;quot;&amp;gt;     &lt;br /&gt;&amp;lt;list&amp;gt;     &lt;br /&gt;&amp;lt;bean id=&amp;quot;helloService&amp;quot; class=&amp;quot;org.wso2.spring.ws.SpringWebService&amp;quot;&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;serviceBean&amp;quot; ref=&amp;quot;helloworld&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;serviceName&amp;quot; value=&amp;quot;helloWorldService&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;     &lt;br /&gt;&amp;lt;/list&amp;gt;     &lt;br /&gt;&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/p&gt;  &lt;p&gt;You can read more about Spring support from the following links&lt;/p&gt;  &lt;p&gt;&lt;a href="http://wso2.org/projects/wsf/spring"&gt;WSO2 Web Services Framework for Spring&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://wso2.org/library/3208"&gt;Hello World with WSO2 WSF/Spring&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;by Deepal Jayasinghe&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-2970948570275541947?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Iw0FoY1pDXnZqGbai1gT56d4I3w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Iw0FoY1pDXnZqGbai1gT56d4I3w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Iw0FoY1pDXnZqGbai1gT56d4I3w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Iw0FoY1pDXnZqGbai1gT56d4I3w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/lNtYmji_YNc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/2970948570275541947/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=2970948570275541947" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/2970948570275541947?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/2970948570275541947?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/lNtYmji_YNc/spring-web-services-and-axis2.html" title="Spring Web services and Axis2" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/07/spring-web-services-and-axis2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYFQX0yeCp7ImA9WxdVF0g.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-3403600806248560673</id><published>2008-07-22T22:05:00.001+02:00</published><updated>2008-07-22T22:05:10.390+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-22T22:05:10.390+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="osgi" /><category scheme="http://www.blogger.com/atom/ns#" term="test" /><title>Unit test with Spring Dynamic Modules</title><content type="html">&lt;p&gt;Follow our story about developing services by using Spring Dynamic Modules. We are developing our application and we have already migrated our application to support osgi. During migration, we have some problems with our test classes, we wanted to run our unit test in osgi environment (so we called integration test - integration test in osgi environment should be the better choice because we can check the class resolving among bundles besides of making sure all business rules are run properly). We already have a lot of unit tests written by JUnit 4 (which are based on Unitils and we already developed a bunch of test module such as Servlet Container, Ldap etc) and unfortunately they can not run in osgi environment. This post is our experience while we develop our integration test base on Spring DM testing framework, actually the cost of migration from our unit test is not much, most of time for researching how to do and simply replaces the revelant things of Unit 4 to Unit 3. Spring DM testing framework supports integration test but for JUnit 3 only now. Here is the general scenerio of Spring DM supports to run integration testing (quoted from Spring DM reference document)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Start the OSGi framework (Equinox, Knopflerfish, Felix)&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;install and start any specified bundles required for the test&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;package the test case itself into a on the fly bundle, generate the manifest (if none is provided) and install it in the OSGi framework&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;execute the test case inside the OSGi framework&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;shut down the framework&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;passes the test results back to the originating test case instance that is running outside of OSGi&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Setting the integration test environment&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Make sure that the following necessary files belong your class-path:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;spring-osgi-core-1.1.0 &lt;/li&gt;    &lt;li&gt;spring-osgi-extender-1.1.0 &lt;/li&gt;    &lt;li&gt;spring-osgi-io-1.1.0 &lt;/li&gt;    &lt;li&gt;spring-osgi-test-1.1.0 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Creating the first Osgi integration test&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All integration test class must inherit the org.springframework.osgi.test.AbstractConfigurableBundleCreatorTest. The first step is creating our base class for all osgi integration testing:&lt;/p&gt;  &lt;pre&gt;/**
 * The base class of integration testing of Engroup. All integration testing
 * classes must be derived from this class
 *
 */
public class AbstractEngroupOsgiTest extends
  AbstractConfigurableBundleCreatorTests {
   ...
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Configuring boot bundles of Spring DM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By default, Spring DM testing frameworks will load some default bundles before loading specific bundles for your test. You can see the default bundles loaded by Spring DM testing framework at org.springframework.osgi.test.internal.boot-bundles of spring-test project. In some cases, you need to replace the boot bundles of Spring DM testing framework by your bundles. The typical scenario that you need to do that is case you already have some bundles, in these bundles you add some extra osgi meta data (such as DynamicImport-Package field to allow the bundle can dynamic load class at runtime). Having the same package with the same version is prohibited. In addition, we are doing integration test, so make the test environment is similar with real environment is a must. Spring DM allows you can inject the new configuration of boot bundles by simply override the method getTestingFrameworkBundlesConfiguration of class AbstractConfigurableBundleCreatorTest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt; Inject the new configuration of boot bundles for Spring DM testing&lt;/p&gt;

&lt;pre&gt;private static final String TEST_FRRAMEWORK_BUNDLES_CONF_FILE = &amp;quot;/META-INF/boot-bundles.properties&amp;quot;;
...
@Override
protected Resource getTestingFrameworkBundlesConfiguration() {
  return new InputStreamResource(AbstractEngroupOsgiTest.class
    .getResourceAsStream(TEST_FRRAMEWORK_BUNDLES_CONF_FILE));
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Customizing the bundle content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Due to your test class is bundled in on-the-fly bundle. You can customize the manifest file of this bundle. In some cases, it is the must for complex case while the test class use the class of other bundles run during test executing. To do this, you simply override the method getManifestLocation (note that you can change the content of manifest file programatically by override the method getManifest, however we prefer to use the manifest file)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt; Customizing the test manifest file&lt;/p&gt;

&lt;pre&gt;@Override
protected String getManifestLocation() {
    return &amp;quot;classpath:META-INF/MANIFEST.MF&amp;quot;;
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Example 3:&lt;/strong&gt; Customized manifest file&lt;/p&gt;

&lt;pre&gt;Manifest-Version: 1.0
Embed-Directory: lib
Implementation-Title: Engroup Osgi Integration Test
Spring-Version: 2.5.5
Bundle-Activator: &lt;strong&gt;org.springframework.osgi.test.JUnitTestActivator&lt;/strong&gt;
Implementation-Version: 2.5.5
Tool: Bnd-0.0.160
Bundle-Name: engroup-integration-test
Created-By: 1.6.0 (Sun Microsystems Inc.)
Bundle-Version: 0.0.1
Bnd-LastModified: 1207763595575
Bundle-ManifestVersion: 2
Import-Package:
 com.engroup.module.common.domain,
 com.engroup.module.common.service,
 &amp;#8230;
 com.mysql.jdbc,
 javax.jcr,
 javax.naming,
 javax.naming.directory,
 javax.naming.ldap,
 javax.sql,
 junit.framework,
 org.dbunit,
 org.dbunit.database,
 org.dbunit.dataset,
 org.dbunit.dataset.xml,
 org.dbunit.operation,
 org.osgi.framework,
 org.springframework.context,
 &amp;#8230;
Bundle-ClassPath: .,
 {src/test/resources}
Bundle-SymbolicName: engroup.server.engroup-integration-test
Include-Resource: {src\test\resources}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Some tips of writing Osgi Integration Test&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Set the default wait timer of creating spring context:&lt;/strong&gt; 

    &lt;br /&gt;Waiting time is set to wait until all dependencies are resolved before running test execution. Base on practice the waiting time is varied but limit under 20s (in our project). However, to support debugging while running integration test, the longer value should be set to prevent Spring DM interupt the test while developers are debugging the test program.&lt;strong&gt;Example 4:&lt;/strong&gt; Set the wait time override the default value of Spring DM 

    &lt;pre&gt;    @Override
    protected long getDefaultWaitTime() {
        return 3000;
    }&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Inject spring beans in test class:&lt;/strong&gt; 

    &lt;br /&gt;We use Spring DM with the purpose that Spring beans could be exposed as the osgi services and used in other bundles. Of course, we would like to test spring beans in integration testing. To use spring, make sure the integration test class load the spring context files first&lt;strong&gt;Example 5:&lt;/strong&gt; Load the spring context files 

    &lt;pre&gt;     @Override
     protected String[] getConfigLocations() {
         return new String[] {
             &amp;quot;classpath:META-INF/spring/hr-context-osgi-test.xml&amp;quot;,
             &amp;quot;classpath:META-INF/spring/common-context-osgi-test.xml&amp;quot;,
             &amp;quot;META-INF/spring/db-context-osgi-test.xml&amp;quot; };
     }&lt;/pre&gt;

    &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All spring context files should only declare only spring beans are exposed by other bundles and remember to import the necessary packages in your manifest file&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Example 6:&lt;/strong&gt; Spring context file declares the spring bean service exported by other bundles and they serve for testing purpose&lt;/p&gt;

    &lt;pre&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
 xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
 xmlns:osgi=&amp;quot;http://www.springframework.org/schema/osgi&amp;quot;
 xsi:schemaLocation=
  &amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd&amp;quot;&amp;gt;
 &amp;lt;osgi:reference id=&amp;quot;companyService&amp;quot;
  interface=&amp;quot;com.engroup.module.hr.service.CompanyService&amp;quot; /&amp;gt;

 &amp;lt;osgi:reference id=&amp;quot;divisionService&amp;quot;
  interface=&amp;quot;com.engroup.module.hr.service.DivisionService&amp;quot; /&amp;gt;
...&lt;/pre&gt;

    &lt;p&gt;Now, it is ready to inject our spring beans to test class by injecting the spring bean to protected objects of test class&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Example 7:&lt;/strong&gt; Inject the spring bean to test class protected fields&lt;/p&gt;

    &lt;pre&gt;   protected CompanyService companyService;

   public AbstractEngroupOsgiTest() {
       setPopulateProtectedVariables(true);
   }&lt;/pre&gt;

    &lt;p&gt;Now, you can use companyService spring bean is exposed from other bundles in your test method.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;by haiphucnguyen &lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-3403600806248560673?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aQ21IYQ4if0dYqbHWQoK3I0xzfk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aQ21IYQ4if0dYqbHWQoK3I0xzfk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aQ21IYQ4if0dYqbHWQoK3I0xzfk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aQ21IYQ4if0dYqbHWQoK3I0xzfk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/-Elq3SZgAEc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/3403600806248560673/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=3403600806248560673" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3403600806248560673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3403600806248560673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/-Elq3SZgAEc/unit-test-with-spring-dynamic-modules.html" title="Unit test with Spring Dynamic Modules" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/07/unit-test-with-spring-dynamic-modules.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4BQHo5fip7ImA9WxdWGU0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-3186682377134562332</id><published>2008-07-13T01:22:00.001+02:00</published><updated>2008-07-13T01:22:31.426+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-13T01:22:31.426+02:00</app:edited><title>Seam, Spring and jBPM integration HowTo</title><content type="html">&lt;p&gt;This HowTo describes a way to integrate Seam, Spring and jBPM in order to use the same Hibernate SessionFactory in both Spring and jBPM (and of course, Seam).&lt;/p&gt;  &lt;p&gt;At first, make sure you use the latest version 2.1.0 of Seam since you could get trouble with 2.0.1 and SpringTransactions.&lt;/p&gt;  &lt;p&gt;The relevant parts of the configuration are:&lt;/p&gt;  &lt;p&gt;- in your Spring bean config, define your Hibernate sessionFactory as usual and set the following properties in special&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id=&amp;#8220;hibernateSessionFactory&amp;#8221;    &lt;br /&gt;class=&amp;#8220;&amp;#8230;&amp;#8221;&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!&amp;#8211; The hibernate properties&amp;#160; &amp;#8211;&amp;gt;    &lt;br /&gt;&amp;lt;property name=&amp;#8220;hibernateProperties&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;props&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&amp;lt;prop key=&amp;#8220;hibernate.hbm2ddl.auto&amp;#8221;&amp;gt;update&amp;lt;/prop&amp;gt;    &lt;br /&gt;&amp;lt;!&amp;#8211; set to create-drop to NOT maintain state between two executions of the app &amp;#8211;&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;prop    &lt;br /&gt;key=&amp;#8220;hibernate.transaction.flush_before_completion&amp;#8221;&amp;gt;     &lt;br /&gt;true     &lt;br /&gt;&amp;lt;/prop&amp;gt;     &lt;br /&gt;&amp;lt;prop key=&amp;#8220;hibernate.connection.release_mode&amp;#8221;&amp;gt;     &lt;br /&gt;after_transaction     &lt;br /&gt;&amp;lt;/prop&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;/props&amp;gt;    &lt;br /&gt;&amp;lt;/property&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!&amp;#8211; this property must be set to false so we can use independent sessions &amp;#8211;&amp;gt;    &lt;br /&gt;&amp;lt;property name=&amp;#8220;useTransactionAwareDataSource&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;value&amp;gt;false&amp;lt;/value&amp;gt;     &lt;br /&gt;&amp;lt;/property&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;property name=&amp;#8220;mappingResources&amp;#8221;&amp;gt;    &lt;br /&gt;&amp;lt;list&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!&amp;#8211; here you have to list all the *hbm.xml files for jBPM &amp;#8211;&amp;gt;    &lt;br /&gt;&amp;lt;!&amp;#8211; see the default hibernate.cfg.xml file from jBPM &amp;#8211;&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&amp;lt;/bean&amp;gt;&lt;/p&gt;  &lt;p&gt;- second, for the Seam Spring integration we need two beans&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id=&amp;#8220;sessionFactory&amp;#8221;    &lt;br /&gt;class=&amp;#8220;org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;#8220;sessionName&amp;#8221; value=&amp;#8220;hibernateSession&amp;#8221; /&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;     &lt;br /&gt;&amp;lt;bean id=&amp;#8220;localTransactionManager&amp;#8221;     &lt;br /&gt;class=&amp;#8220;org.springframework.orm.hibernate3.HibernateTransactionManager&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;#8220;sessionFactory&amp;#8221; ref=&amp;#8220;hibernateSessionFactory&amp;#8221; /&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/p&gt;  &lt;p&gt;That&amp;#8217;s it for Spring configuration.&lt;/p&gt;  &lt;p&gt;Now in components.xml, we need&lt;/p&gt;  &lt;p&gt;&amp;lt;!&amp;#8211; use the power of Spring transactions &amp;#8211;&amp;gt;    &lt;br /&gt;&amp;lt;spring:spring-transaction platform-transaction-manager-name=&amp;#8220;localTransactionManager&amp;#8221;/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;persistence:managed-hibernate-session name=&amp;#8220;hibernateSession&amp;#8221; auto-create=&amp;#8220;true&amp;#8221;    &lt;br /&gt;session-factory=&amp;#8220;#{hibernateSessionFactory}&amp;#8221;/&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;component class=&amp;#8220;org.jboss.seam.bpm.Jbpm&amp;#8221;&amp;gt;    &lt;br /&gt;&amp;lt;property name=&amp;#8220;processDefinitions&amp;#8221;&amp;gt;processdefinition.jpdl.xml&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/component&amp;gt;&lt;/p&gt;  &lt;p&gt;In order to use the hibernateSession in jBPM, I subclassed the DbPersistenceService from jBPM. You need two classes:&lt;/p&gt;  &lt;p&gt;package your.namespace.jbpm.integration; &lt;/p&gt;  &lt;p&gt;import org.hibernate.Session;    &lt;br /&gt;import org.hibernate.SessionFactory;&lt;/p&gt;  &lt;p&gt;import org.jboss.seam.Component;    &lt;br /&gt;import org.jboss.seam.contexts.Contexts;&lt;/p&gt;  &lt;p&gt;import org.jbpm.svc.Service;&lt;/p&gt;  &lt;p&gt;/**    &lt;br /&gt;* @author Frank Bitzer     &lt;br /&gt;*     &lt;br /&gt;*     &lt;br /&gt;*     &lt;br /&gt;*/&lt;/p&gt;  &lt;p&gt;public class DbPersistenceServiceFactory extends    &lt;br /&gt;org.jbpm.persistence.db.DbPersistenceServiceFactory {&lt;/p&gt;  &lt;p&gt;private static final long serialVersionUID = 997L;    &lt;br /&gt;SessionFactory sessionFactory;&lt;/p&gt;  &lt;p&gt;/**    &lt;br /&gt;* {@inheritDoc}     &lt;br /&gt;*/     &lt;br /&gt;public Service openService() {&lt;/p&gt;  &lt;p&gt;//create instance of own service implementation    &lt;br /&gt;return new your.namespace.jbpm.integration.DbPersistenceService(this);     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;/**    &lt;br /&gt;* Retrieve Hibernate sessionFactory     &lt;br /&gt;*/     &lt;br /&gt;@Override     &lt;br /&gt;public synchronized SessionFactory getSessionFactory() {&lt;/p&gt;  &lt;p&gt;if (sessionFactory==null) {&lt;/p&gt;  &lt;p&gt;if(Contexts.isApplicationContextActive()){&lt;/p&gt;  &lt;p&gt;//access seam component holding session    &lt;br /&gt;Session session = (Session)     &lt;br /&gt;&lt;a href="http://www.google.com/search?q=allinurl%3AComponent+java.sun.com&amp;amp;bntl=1"&gt;Component&lt;/a&gt;.getInstance(&amp;#8220;hibernateSession&amp;#8221;);&lt;/p&gt;  &lt;p&gt;//and extract sessionFactory    &lt;br /&gt;sessionFactory = session.getSessionFactory();&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;return sessionFactory;    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;/**    &lt;br /&gt;* Set sessionFactory     &lt;br /&gt;*/     &lt;br /&gt;@Override     &lt;br /&gt;public void setSessionFactory(SessionFactory sessionFactory) {     &lt;br /&gt;this.sessionFactory = sessionFactory;     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;package your.namespace.jbpm.integration; &lt;/p&gt;  &lt;p&gt;import org.hibernate.Session;    &lt;br /&gt;import org.jbpm.JbpmContext;     &lt;br /&gt;import org.jbpm.persistence.db.DbPersistenceServiceFactory;     &lt;br /&gt;import org.jbpm.svc.Services;     &lt;br /&gt;import org.springframework.orm.hibernate3.SessionFactoryUtils;&lt;/p&gt;  &lt;p&gt;/**    &lt;br /&gt;* @author Frank Bitzer     &lt;br /&gt;*     &lt;br /&gt;*     &lt;br /&gt;*     &lt;br /&gt;*/     &lt;br /&gt;public class DbPersistenceService extends     &lt;br /&gt;org.jbpm.persistence.db.DbPersistenceService {&lt;/p&gt;  &lt;p&gt;private static final long serialVersionUID = 996L;&lt;/p&gt;  &lt;p&gt;public DbPersistenceService(    &lt;br /&gt;DbPersistenceServiceFactory persistenceServiceFactory) {     &lt;br /&gt;this(persistenceServiceFactory, getCurrentServices());     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;static Services getCurrentServices() {    &lt;br /&gt;Services services = null;     &lt;br /&gt;JbpmContext currentJbpmContext = JbpmContext.getCurrentJbpmContext();     &lt;br /&gt;if (currentJbpmContext != null) {     &lt;br /&gt;services = currentJbpmContext.getServices();     &lt;br /&gt;}     &lt;br /&gt;return services;     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;DbPersistenceService(DbPersistenceServiceFactory persistenceServiceFactory,    &lt;br /&gt;Services services) {&lt;/p&gt;  &lt;p&gt;super(persistenceServiceFactory);&lt;/p&gt;  &lt;p&gt;this.persistenceServiceFactory = persistenceServiceFactory;    &lt;br /&gt;this.isTransactionEnabled = persistenceServiceFactory     &lt;br /&gt;.isTransactionEnabled();     &lt;br /&gt;this.isCurrentSessionEnabled = persistenceServiceFactory     &lt;br /&gt;.isCurrentSessionEnabled();     &lt;br /&gt;this.services = services;&lt;/p&gt;  &lt;p&gt;}    &lt;br /&gt;/**     &lt;br /&gt;* Use Hibernate sessionFactory to retrieve a Session instance.     &lt;br /&gt;*/     &lt;br /&gt;public Session getSession() {&lt;/p&gt;  &lt;p&gt;if ((session == null) &amp;amp;&amp;amp; (getSessionFactory() != null)) {&lt;/p&gt;  &lt;p&gt;session = getSessionFactory().openSession();&lt;/p&gt;  &lt;p&gt;mustSessionBeClosed = true;    &lt;br /&gt;mustSessionBeFlushed = true;     &lt;br /&gt;mustConnectionBeClosed = false;&lt;/p&gt;  &lt;p&gt;isTransactionEnabled = !SessionFactoryUtils.isSessionTransactional(    &lt;br /&gt;session, getSessionFactory());&lt;/p&gt;  &lt;p&gt;if (isTransactionEnabled) {&lt;/p&gt;  &lt;p&gt;beginTransaction();    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;}    &lt;br /&gt;return session;     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;To finish work, simply use the brand-new DbPersistenceService in jbpm.cfg.xml like&lt;/p&gt;  &lt;p&gt;&amp;#8230;    &lt;br /&gt;&amp;lt;jbpm-context&amp;gt;     &lt;br /&gt;&amp;lt;service name=&amp;#8220;persistence&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;factory&amp;gt;     &lt;br /&gt;&amp;lt;bean class=&amp;#8220;your.namespace.jbpm.integration.DbPersistenceServiceFactory&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;field name=&amp;#8220;isTransactionEnabled&amp;#8221;&amp;gt;     &lt;br /&gt;&amp;lt;false/&amp;gt;     &lt;br /&gt;&amp;lt;/field&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;     &lt;br /&gt;&amp;lt;/factory&amp;gt;     &lt;br /&gt;&amp;lt;/service&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;    &lt;br /&gt;&amp;lt;/jbpm-context&amp;gt;     &lt;br /&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;Also make sure your Spring WebApplicationContext is initialized before the startup of Seam. This can be achieved by placing the &lt;em&gt;org.jboss.seam.servlet.SeamListener&lt;/em&gt; behind the listener for Spring in your web.xml.&lt;/p&gt;  &lt;p&gt;That&amp;#8217;s it! Now everything should work fine.&lt;/p&gt;  &lt;p&gt;Note that I also contributed this HowTo to the official Seam Knowledge Base. You can find it &lt;a href="http://www.seamframework.org/9262.lace"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-3186682377134562332?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8cbUlarnZBEU9v4rFvXfiGh4SfE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8cbUlarnZBEU9v4rFvXfiGh4SfE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8cbUlarnZBEU9v4rFvXfiGh4SfE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8cbUlarnZBEU9v4rFvXfiGh4SfE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/XtiYToWdVVc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/3186682377134562332/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=3186682377134562332" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3186682377134562332?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3186682377134562332?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/XtiYToWdVVc/seam-spring-and-jbpm-integration-howto.html" title="Seam, Spring and jBPM integration HowTo" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/07/seam-spring-and-jbpm-integration-howto.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cGQ3kyfSp7ImA9WxdXFk0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-5585548752364970797</id><published>2008-06-28T00:17:00.001+02:00</published><updated>2008-06-28T00:17:02.795+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-28T00:17:02.795+02:00</app:edited><title>Spring and Lingo = Easy JMS</title><content type="html">&lt;p&gt;With &lt;a href="http://lingo.codehaus.org/"&gt;Lingo&lt;/a&gt; from codeHaus, Spring remoting can be extended to support JMS.     &lt;br /&gt;Here&amp;#8217;s a great article on &lt;a href="http://www.jroller.com/page/sjivan?entry=asynchronous_calls_and_callbacks_using"&gt;Saniv Jivan&amp;#8217;s blog&lt;/a&gt; that shows some of its capabilities (synchronous calls over JMS and asynchronous callbacks)&lt;/p&gt;  &lt;p&gt;One feature really seducing is asynchronous callbacks over JMS    &lt;br /&gt;with POJOS (without a single line of JMS code).     &lt;br /&gt;The Lingo site does not provide much documentation on it     &lt;br /&gt;so thanks for the author of this nice article.&lt;/p&gt;  &lt;p&gt;We applied this technique for our build system to distribute load    &lt;br /&gt;on different machines to speed up the process (we only have mono pro     &lt;br /&gt;build machines) and gets informed when tasks are done via callbacks.     &lt;br /&gt;We used Spring 2.0M4 and ActiveMQ 3.2.2 in standalone mode.&lt;/p&gt;  &lt;p&gt;Note that I had troubles to make it run with Websphere MQ 5.3    &lt;br /&gt;First, recent MQ JMS 1.1 compliant Jars must be used and     &lt;br /&gt;a misinterpretation of the JMS specs by Websphere seems to break     &lt;br /&gt;the Lingo Spring JMS service exporter see     &lt;br /&gt;&lt;a href="http://opensource.atlassian.com/projects/spring/browse/SPR-1324"&gt;     &lt;br /&gt;http://opensource.atlassian.com/projects/spring/browse/SPR-1324&lt;/a&gt;     &lt;br /&gt;which is for JMS templates but can also be applied to lingo.&lt;/p&gt;  &lt;p&gt;Here&amp;#8217;s the diff of org.logicblaze.lingo.jms.JmsServiceExporter between unpatched and patched version for Websphere MQ:&lt;/p&gt;  &lt;pre&gt;diff -aur lingo-1.1/src/java/org/logicblaze/lingo/jms/JmsServiceExporter.java li
ngo-1.1-patch/src/java/org/logicblaze/lingo/jms/JmsServiceExporter.java
--- lingo-1.1/src/java/org/logicblaze/lingo/jms/JmsServiceExporter.java 2006-06-
13 13:45:12.716722400 +0200
+++ lingo-1.1-patch/src/java/org/logicblaze/lingo/jms/JmsServiceExporter.java200
6-06-13 13:44:49.899847100 +0200
@@ -180,7 +180,7 @@&amp;#160;&amp;#160; }
else {
-            return session.createConsumer(destination, messageSelector, noLocal
);
+            return session.createConsumer(destination, messageSelector);
}
}&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-5585548752364970797?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/fa87y1tekt998xRAadDgqujJFuQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fa87y1tekt998xRAadDgqujJFuQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/fa87y1tekt998xRAadDgqujJFuQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fa87y1tekt998xRAadDgqujJFuQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/yaOI1RTwOtY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/5585548752364970797/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=5585548752364970797" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5585548752364970797?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5585548752364970797?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/yaOI1RTwOtY/spring-and-lingo-easy-jms.html" title="Spring and Lingo = Easy JMS" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/spring-and-lingo-easy-jms.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHR3c9eip7ImA9WxdXEkg.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-5581941754520631047</id><published>2008-06-23T21:47:00.001+02:00</published><updated>2008-06-23T21:47:16.962+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-23T21:47:16.962+02:00</app:edited><title>Spring entityManagerFactory in jta and non-jta modes</title><content type="html">&lt;p&gt;This blog post is about using JPA with Spring in 2 contexts :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;production with a JTA transaction manager &lt;/li&gt;    &lt;li&gt;testing with transactions handled by jpa transaction manager. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It has been inspired by &lt;a href="http://erich.soomsam.net/2007/04/24/spring-jpa-and-jta-with-hibernate-and-jotm/"&gt;Erich Soomsam blog post&lt;/a&gt;     &lt;br /&gt;You can achieve such configuration with a PersistenceUnitPostProcessor having a single persistence.xml file and 2 Spring context files (1 for each environment).&lt;/p&gt;  &lt;p&gt;Since you are likely to have at least 2 different Spring dataSource definitions : 1 for production that performs a JNDI lookup to find a bound datasource and 1 for development that uses a local and Spring declared datasource backed by a JDBC connection pool (C3p0 or DBCP), place the entityManager declaration in the same file as the datasource declaration.&lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s say that the default persistence.xml use the non-jta datasource:&lt;/p&gt;  &lt;pre&gt;&amp;lt;persistence xmlns=&amp;quot;http://java.sun.com/xml/ns/persistence&amp;quot;
   xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
   xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&amp;quot;
   version=&amp;quot;1.0&amp;quot;&amp;gt;
   &amp;lt;persistence-unit name=&amp;quot;seamphony&amp;quot; transaction-type=&amp;quot;RESOURCE_LOCAL&amp;quot;&amp;gt;
      &amp;lt;properties&amp;gt;
          &amp;lt;!-- Scan for annotated classes and Hibernate mapping XML files --&amp;gt;
          &amp;lt;property name=&amp;quot;hibernate.archive.autodetection&amp;quot; value=&amp;quot;class, hbm&amp;quot;/&amp;gt;
          &amp;lt;property name=&amp;quot;hibernate.dialect&amp;quot;
                    value=&amp;quot;org.hibernate.dialect.MySQLDialect&amp;quot;/&amp;gt;
      &amp;lt;/properties&amp;gt;
   &amp;lt;/persistence-unit&amp;gt;
&amp;lt;/persistence&amp;gt;&lt;/pre&gt;

&lt;p&gt;Here&amp;#8217;s how you can use Spring to post process the persistence unit and configure it for production (here 
  &lt;br /&gt;with MySQL datasource and JBoss Transaction Manager):&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean id=&amp;quot;entityManagerFactory&amp;quot; class=&amp;quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&amp;quot;&amp;gt;
   &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;dataSource&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
   &amp;lt;property name=&amp;quot;jpaVendorAdapter&amp;quot;&amp;gt;
	&amp;lt;bean class=&amp;quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&amp;quot;&amp;gt;
            &amp;lt;property name=&amp;quot;database&amp;quot; value=&amp;quot;MYSQL&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
            &amp;lt;property name=&amp;quot;showSql&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
            &amp;lt;property name=&amp;quot;databasePlatform&amp;quot; value=&amp;quot;org.hibernate.dialect.MySQLDialect&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
	&amp;lt;/bean&amp;gt;
   &amp;lt;/property&amp;gt;
   &amp;lt;property name=&amp;quot;jpaPropertyMap&amp;quot;&amp;gt;
      &amp;lt;map&amp;gt;
	&amp;lt;entry key=&amp;quot;hibernate.transaction.manager_lookup_class&amp;quot; value=&amp;quot;org.hibernate.transaction.JBossTransactionManagerLookup&amp;quot;/&amp;gt;
	&amp;lt;entry key=&amp;quot;hibernate.transaction.flush_before_completion&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
	&amp;lt;entry key=&amp;quot;hibernate.transaction.auto_close_session&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
	&amp;lt;entry key=&amp;quot;hibernate.current_session_context_class&amp;quot; value=&amp;quot;jta&amp;quot;/&amp;gt;
	&amp;lt;entry key=&amp;quot;hibernate.connection.release_mode&amp;quot; value=&amp;quot;auto&amp;quot;/&amp;gt;
      &amp;lt;/map&amp;gt;
   &amp;lt;/property&amp;gt;
   &amp;lt;property name=&amp;quot;persistenceUnitPostProcessors&amp;quot;&amp;gt;
      &amp;lt;list&amp;gt;
         &amp;lt;bean class=&amp;quot;JtaPersistenceUnitPostProcessor&amp;quot;&amp;gt;
            &amp;lt;property name=&amp;quot;jtaMode&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
            &amp;lt;property name=&amp;quot;jtaDataSource&amp;quot; ref=&amp;quot;dataSource&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
         &amp;lt;/bean&amp;gt;
      &amp;lt;/list&amp;gt;
   &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;!--
 Datasource Lookup
--&amp;gt;
&amp;lt;bean id=&amp;quot;dataSource&amp;quot; class=&amp;quot;org.springframework.jndi.JndiObjectFactoryBean&amp;quot;&amp;gt;
   &amp;lt;property name=&amp;quot;resourceRef&amp;quot;&amp;gt;
       &amp;lt;value&amp;gt;false&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
   &amp;lt;property name=&amp;quot;jndiName&amp;quot;&amp;gt;
      &amp;lt;value&amp;gt;java:/MyDS&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&amp;#160;&amp;#160; &amp;lt;!--
 Transaction Manager
--&amp;gt;&amp;#160;&amp;#160; &amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.transaction.jta.JtaTransactionManager&amp;quot;&amp;gt;
   &amp;lt;property name=&amp;quot;transactionManagerName&amp;quot; value=&amp;quot;java:/TransactionManager&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
   &amp;lt;property name=&amp;quot;autodetectUserTransaction&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;Here&amp;#8217;s the class that reads the jta mode property and configure the transaction type accordingly:&lt;/p&gt;

&lt;pre&gt;import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;&amp;#160;&amp;#160; public class JtaPersistenceUnitPostProcessor implements
		PersistenceUnitPostProcessor {&amp;#160;&amp;#160; private boolean jtaMode = false;&amp;#160;&amp;#160; private DataSource jtaDataSource;
	private PersistenceUnitTransactionType transacType = PersistenceUnitTransactionType.RESOURCE_LOCAL;&amp;#160;&amp;#160; public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo mutablePersistenceUnitInfo) {&amp;#160;&amp;#160; if (jtaMode) {
			transacType = PersistenceUnitTransactionType.JTA;
			mutablePersistenceUnitInfo.setJtaDataSource(this.getJtaDataSource());
		}&amp;#160;&amp;#160; mutablePersistenceUnitInfo.setTransactionType(transacType);&amp;#160;&amp;#160; }&amp;#160;&amp;#160; public boolean isJtaMode() {
		return jtaMode;
	}&amp;#160;&amp;#160; public void setJtaMode(boolean jtaMode) {
		this.jtaMode = jtaMode;
	}&amp;#160;&amp;#160; public DataSource getJtaDataSource() {
		return jtaDataSource;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; public void setJtaDataSource(DataSource jtaDataSource) {
		this.jtaDataSource = jtaDataSource;
	}&amp;#160;&amp;#160; }&lt;/pre&gt;

&lt;p&gt;Spring really helps tuning your persistence unit for different environments. It could be achieved by a custom build task that could alter the persistence.xml file but since this example assumes that Spring is already used, it can be avoided.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-5581941754520631047?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IZVDwnyrkrB_MUyYM3peNi_3i8o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IZVDwnyrkrB_MUyYM3peNi_3i8o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IZVDwnyrkrB_MUyYM3peNi_3i8o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IZVDwnyrkrB_MUyYM3peNi_3i8o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/_yrjivyI6NQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/5581941754520631047/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=5581941754520631047" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5581941754520631047?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5581941754520631047?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/_yrjivyI6NQ/spring-entitymanagerfactory-in-jta-and.html" title="Spring entityManagerFactory in jta and non-jta modes" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/spring-entitymanagerfactory-in-jta-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUFSHg9fip7ImA9WxdXEE4.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-112964568744245825</id><published>2008-06-21T09:43:00.001+02:00</published><updated>2008-06-21T09:43:39.666+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-21T09:43:39.666+02:00</app:edited><title>Jackbrabbit OCM and Spring</title><content type="html">&lt;p&gt;Content Repository API becomes more and more popular nowadays, however it is rather difficult in use because its takes time of learning and use. OCM (Object Content Mapping) module is the great tool to helps developers save a lot of time to develop the content-driven application and Spring is the great DI platform to hide most of complexity of initializing, creating and executing repository. We are developing the &lt;strong&gt;engroup ECM&lt;/strong&gt; module base on Jackbrabbit OCM and Spring Module. During development, we look for help in many forums, websites but unfortunately we do not seek the full solution, we hope that this article provide the full example of using Jackbrabbit and Spring in the real application. Part of engroup ECM code base is included in attached file, it is developed base on jackrabbit 1.5 (snapshot version - you can get it at apache maven repository &lt;a href="http://www.haiphucnguyen.net/cgi-gin/ax.pl?http://people.apache.org/maven-snapshot-repository/"&gt;http://people.apache.org/maven-snapshot-repository/&lt;/a&gt;), spring modules 0.9 and the patch spring-ocm got at &lt;a href="http://www.haiphucnguyen.net/cgi-gin/ax.pl?http://jira.springframework.org/browse/MOD-446"&gt;http://jira.springframework.org/browse/MOD-446&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;First, create the POJOs for JCR repository:&lt;/p&gt;  &lt;pre&gt;  @Node(jcrMixinTypes = &amp;#8220;mix:versionable&amp;#8221;)
  public class Content {
    @Field(uuid=true)
    protected String id;
    @Field(path=true)
    protected String path;
    @Field
    protected String name;
    &amp;#8230;
  }&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; if you want to create the POJO inherit the JCR fields of its parent class, you must use the extend property field of annotation Node like the following example:&lt;/p&gt;

&lt;pre&gt;  @Node(jcrMixinTypes = &amp;#8220;mix:versionable&amp;#8221;, extend = AbstractFile.class)
  public class File extends Content {
    @Field
    protected byte[] content;
    &amp;#8230;
  }&lt;/pre&gt;

&lt;p&gt;The next step is creating the spring beans to init the repository, register nodes types and POJOs with repository. Here is the part of configuration file (you can see the full file in the attachment):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Initialize the repository:&lt;/strong&gt; 

    &lt;pre&gt;    &amp;lt;bean id=&amp;quot;repository&amp;quot; class=&amp;quot;org.springmodules.jcr.jackrabbit.RepositoryFactoryBean&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;configuration&amp;quot; value=&amp;quot;classpath:jackrabbit-repo.xml&amp;quot; /&amp;gt;
      &amp;lt;property name=&amp;quot;homeDir&amp;quot; value=&amp;quot;file:/tmp/repository&amp;quot; /&amp;gt;
    &amp;lt;/bean&amp;gt;
    &amp;lt;bean id=&amp;quot;jcrSessionFactory&amp;quot; class=&amp;quot;org.springmodules.jcr.jackrabbit.ocm.JackrabbitSessionFactory&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;repository&amp;quot; ref=&amp;quot;repository&amp;quot; /&amp;gt;
      &amp;lt;property name=&amp;quot;credentials&amp;quot;&amp;gt;
        &amp;lt;bean class=&amp;quot;javax.jcr.SimpleCredentials&amp;quot;&amp;gt;
          &amp;lt;constructor-arg index=&amp;quot;0&amp;quot; value=&amp;quot;superuser&amp;quot; /&amp;gt;
          &amp;lt;!-- create the credentials using a bean factory --&amp;gt;
            &amp;lt;constructor-arg index=&amp;quot;1&amp;quot;&amp;gt;
              &amp;lt;bean factory-bean=&amp;quot;password&amp;quot; factory-method=&amp;quot;toCharArray&amp;quot; /&amp;gt;
            &amp;lt;/constructor-arg&amp;gt;
        &amp;lt;/bean&amp;gt;
      &amp;lt;/property&amp;gt;
      &amp;lt;property name=&amp;quot;nodeTypes2Import&amp;quot; value=&amp;quot;nodetypes/custom_nodetypes.xml&amp;quot; /&amp;gt;
    &amp;lt;/bean&amp;gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Make the mapping between POJOs and annotation mapper 
      &lt;br /&gt;&lt;/strong&gt;

    &lt;pre&gt;    &amp;lt;bean id=&amp;quot;jcrMappingDescriptor&amp;quot; class=&amp;quot;org.apache.jackrabbit.ocm.mapper.impl.annotation.AnnotationMapperImpl&amp;quot;&amp;gt;
      &amp;lt;constructor-arg index=&amp;quot;0&amp;quot;&amp;gt;
        &amp;lt;!--Put all your POJOs in this list--&amp;gt;
        &amp;lt;list&amp;gt;
          &amp;lt;value&amp;gt;com.engroup.module.ecm.domain.AbstractFile&amp;lt;/value&amp;gt;
          &amp;lt;value&amp;gt;com.engroup.module.ecm.domain.Content&amp;lt;/value&amp;gt;
          &amp;lt;value&amp;gt;com.engroup.module.ecm.domain.File&amp;lt;/value&amp;gt;
          &amp;lt;value&amp;gt;com.engroup.module.ecm.domain.Folder&amp;lt;/value&amp;gt;
        &amp;lt;/list&amp;gt;
      &amp;lt;/constructor-arg&amp;gt;
    &amp;lt;/bean&amp;gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Declare the Content Service Bean with transaction management support&lt;/strong&gt; 

    &lt;pre&gt;&lt;strong&gt;
&lt;/strong&gt; &amp;lt;bean id=&amp;#8221;internalContentService&amp;#8221;
    class=&amp;#8221;com.engroup.module.ecm.service.impl.ContentServiceImpl&amp;#8221;&amp;gt;
    &amp;lt;property name=&amp;#8221;jcrTemplate&amp;#8221; ref=&amp;#8221;jcrMappingTemplate&amp;#8221; /&amp;gt;
 &amp;lt;/bean&amp;gt;
 &amp;lt;bean id=&amp;#8221;contentService&amp;#8221; parent=&amp;#8221;baseTransactionProxy&amp;#8221;&amp;gt;
    &amp;lt;property name=&amp;#8221;proxyInterfaces&amp;#8221;&amp;gt;
      &amp;lt;value&amp;gt;com.engroup.module.ecm.service.ContentService&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#8221;target&amp;#8221;&amp;gt;
      &amp;lt;ref bean=&amp;#8221;internalContentService&amp;#8221; /&amp;gt;
    &amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;#8221;transactionAttributes&amp;#8221;&amp;gt;
      &amp;lt;props&amp;gt;
        &amp;lt;prop key=&amp;#8221;*&amp;#8221;&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;
      &amp;lt;/props&amp;gt;
    &amp;lt;/property&amp;gt;
  &amp;lt;/bean&amp;gt;&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, all configuration tasks are done. Now, you can access the content of repository by using POJOs. Thanks for spring modules that helps you reduce lot of code for initilizing and manage repository. The tasks later just be simply like you work with Hibernate entity, all works are done by Java code (Of course, you need to know a little advance knowledge of repository to customize data types etc for your needs). After I create the service, now it is time to write some little unit test to make sure all configurations are set properly &lt;img alt=":)" src="http://www.haiphucnguyen.net/blog/wp-includes/images/smilies/icon_smile.gif" /&gt;&lt;/p&gt;

&lt;pre&gt;  @RunWith(UnitilsJUnit4TestClassRunner.class)
  public class ContentServiceTest {
    @SpringBean
    private ContentService&amp;lt;Content&amp;gt; contentService;

    @Test
    public void testSave() {
      File file = createFile();
      contentService.save(file);
      file = (File)contentService.findByPath(&amp;quot;/nextss&amp;quot;);
      Assert.assertThat(file.getPath(), is(&amp;quot;/nextss&amp;quot;));
      Assert.assertThat(file.getFileType(), is(FileType.UNDEFINED));
      contentService.remove(file);
    }

    private File createFile() {
      File file = new File();
      file.setId(&amp;quot;1&amp;quot;);
      file.setPath(&amp;quot;/nextss&amp;quot;);
      file.setName(&amp;quot;ABC&amp;quot;);
      file.setFileType(FileType.UNDEFINED);
      file.setTitle(&amp;quot;Test Exam&amp;quot;);
      file.setLastModified(Calendar.getInstance().toString());
      file.setContent(&amp;quot;Hello world&amp;quot;.getBytes());
      file.setComment(&amp;quot;AAA&amp;quot;);
      return file;
    }
    ...
  }&lt;/pre&gt;

&lt;p&gt;I am happy when the unit test run well :). Hope it is the part complements with Jackrabbit OCM and Spring modules - OCM. Welcomes any comments from you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Jackrabbit home page: &lt;a href="http://www.haiphucnguyen.net/cgi-gin/ax.pl?http://jackrabbit.apache.org/"&gt;http://jackrabbit.apache.org/&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Jackrabbit OCM page: &lt;a href="http://www.haiphucnguyen.net/cgi-gin/ax.pl?http://jackrabbit.apache.org/object-content-mapping.html"&gt;http://jackrabbit.apache.org/object-content-mapping.html&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Spring Modules home page: &lt;a href="https://springmodules.dev.java.net/"&gt;https://springmodules.dev.java.net/&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Source code: &lt;a href="http://www.haiphucnguyen.net/blog/wp-content/uploads/2008/06/ecm-0.0.1-sources.jar"&gt;download &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-112964568744245825?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nrWUmsbmknxs4XJTgRvydVQ_HV4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nrWUmsbmknxs4XJTgRvydVQ_HV4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nrWUmsbmknxs4XJTgRvydVQ_HV4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nrWUmsbmknxs4XJTgRvydVQ_HV4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/C91n9-UusPU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/112964568744245825/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=112964568744245825" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/112964568744245825?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/112964568744245825?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/C91n9-UusPU/jackbrabbit-ocm-and-spring.html" title="Jackbrabbit OCM and Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/jackbrabbit-ocm-and-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEACR3g4cCp7ImA9WxdQF04.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-678861531436446579</id><published>2008-06-17T23:06:00.001+02:00</published><updated>2008-06-17T23:06:06.638+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-17T23:06:06.638+02:00</app:edited><title>Who hides in your Spring factory?</title><content type="html">&lt;p&gt;Using schema-based configuration in Spring framework is powerful yet leads to less transparent configuration. Here I introduce single class that allows you to unleash all details of your Spring context. &lt;/p&gt;  &lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Schema based configuration&lt;/h4&gt;  &lt;p&gt;Spring framework has very interesting and powerful feature - ability to use custom namespaces within ordinary Spring configuration file. &lt;/p&gt;  &lt;p&gt;Using that functionality, it's possible to create custom XML element (with providing necessary XSD scheme to Spring) that will be parsed and used for declaring specific beans that corresponds to appropriate custom tags from scheme. &lt;/p&gt;  &lt;p&gt;That's feature is really cool, since, from one hand, it allows to create own DSL (domain specific language) that is plugged into usual Spring declaration. Using DSL instead of Spring declaration is pretty convenient since it allows to have clean, compact and, what is more important, domain specific markup instead of generic one. &lt;/p&gt;  &lt;p&gt;In addition, by introducing support of such functionality, Spring encourages vendors of third-party tools and libraries to plug them into Spring as components with functionality exposed via elements in custom namespace provided by vendor.&lt;/p&gt;  &lt;p&gt;In general, support of custom namespaces in Spring context brings higher level of abstraction and increases overall productivity of developers.&lt;/p&gt;  &lt;h4&gt;Caveat&lt;/h4&gt;  &lt;p&gt;Higher level of abstraction, as usual, adds more complexity and leaves many things under the hood. Until you use namespace you've implemented by own, you can now which beans will be created in Spring context as you use it (well, at least until during some reasonable period of time after developing it). However, what to do if you simply use tags provided by someone else? First, you got that library somehow and description of tag promises that if you use it you may throw away all old configuration for persistence, hibernate etc. etc. since at the moment of adding that custom tag into your context it scans your brain and does everything much better as you can even imagine... Sure thing, you think that it could be great and use it... &lt;/p&gt;  &lt;p&gt;And until everything work fine - no one cares what is under that tag (it scans the brain, after all!). But if something goes wrong - well, if you have ordinary Spring config, you have a chance to take a look to configuration and find the problem' source. Not for custom tags - all details are hidden from outside world. &lt;/p&gt;  &lt;p&gt;Seriously, using of custom namespaces in Spring config has such a drawback - in general, you don't know what &lt;b&gt;actually&lt;/b&gt; happens when you use such a tags. &lt;/p&gt;  &lt;h4&gt;Solution&lt;/h4&gt;  &lt;p&gt;We here in &lt;a href="http://www.soft-amis.com"&gt;SoftAMIS&lt;/a&gt; have got that problem some time ago trying to figure quite subtle problems with configuration. To avoid that in the future, we've created small utility that performs dump of internals for given Spring context (by examining registered bean definitions). Of course, it was not practical to invent some new format for such a dump, so old good Spring configuration is used - however, it unwraps all custom tags into their internal representation.&lt;/p&gt;  &lt;p&gt;Similarly to approach from Spring reference:) If you have in your context declaration like that:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;lt;util:map id=&amp;quot;testMap&amp;quot;&amp;gt; &amp;lt;entry key=&amp;quot;key&amp;quot; value=&amp;quot;value&amp;quot;/&amp;gt; &amp;lt;/util:map&amp;gt; &amp;lt;util:property-path path=&amp;quot;testMap.values&amp;quot;/&amp;gt;&lt;/p&gt;  &lt;p&gt;in corresponding dumped context you'll get:&lt;/p&gt;  &lt;p&gt;&amp;lt;bean name=&amp;quot;testMap&amp;quot; class=&amp;quot;org.springframework.beans.factory.config.MapFactoryBean&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160; &amp;lt;property name=&amp;quot;sourceMap&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;map&amp;gt; &amp;lt;entry key=&amp;quot;key&amp;quot; value=&amp;quot;value&amp;quot;/&amp;gt; &amp;lt;/map&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;     &lt;br /&gt;&amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertyPathFactoryBean&amp;quot; name=&amp;quot;testMap.values&amp;quot; p:propertyPath=&amp;quot;values&amp;quot; p:targetBeanName=&amp;quot;testMap&amp;quot;/&amp;gt;&lt;/p&gt;  &lt;h4&gt;How to use&lt;/h4&gt;  &lt;p&gt;To make dump of Spring context, I've wrote custom &lt;code&gt;BeanFactoryPostProcessor&lt;/code&gt;. Ones is invoked by Spring automatically (if factory is created via application context) and simply inspects internal bean definitions registered in context and generates appropriate XML for them.&lt;/p&gt;  &lt;p&gt;Therefore, everything you need to obtain dump of Spring factory - simply add the following declaration into context for wich you'd like to have such dump: &lt;/p&gt;  &lt;p&gt;&amp;lt;bean class=&amp;quot;org.softamis.tools4spring.dump.DumpBeanFactoryPostProcessor&amp;quot; p:generateSchemaBasedContext=&amp;quot;true&amp;quot; p:outputLocation=&amp;quot;z:\context.xml&amp;quot;/&amp;gt;&lt;/p&gt;  &lt;p&gt;I's possible to specify location of file which dump should be written to and also specify whether dump should be created based on DTD or XSD. In later case, applicable attributes will be written using p: namespace&lt;/p&gt;  &lt;p&gt;Of course, since that class works on context level, it's perfectly will dump Spring factory created from several configuration files. &lt;/p&gt;  &lt;h4&gt;License and download&lt;/h4&gt;  &lt;p&gt;To download source code for that class, please use &lt;a href="http://www.soft-amis.com/serendipity/index.php?serendipity%5Bsubpage%5D=downloadmanager&amp;amp;level=1&amp;amp;thiscat=5"&gt;this link&lt;/a&gt;. That class is licensed under Apache License, so it could be used both in open source and commercial applications. &lt;/p&gt;  &lt;p&gt;I hope that this small utility will be helpful for you and will save your time in some tight situation.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-678861531436446579?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zsH7HxVfTaBXYnBWoG1FAnRw05k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zsH7HxVfTaBXYnBWoG1FAnRw05k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zsH7HxVfTaBXYnBWoG1FAnRw05k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zsH7HxVfTaBXYnBWoG1FAnRw05k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/a0yffEy1ITw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/678861531436446579/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=678861531436446579" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/678861531436446579?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/678861531436446579?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/a0yffEy1ITw/who-hides-in-your-spring-factory.html" title="Who hides in your Spring factory?" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/who-hides-in-your-spring-factory.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYEQ3Y_fCp7ImA9WxdQFkk.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-4690675216025374980</id><published>2008-06-16T22:28:00.001+02:00</published><updated>2008-06-16T22:28:22.844+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-16T22:28:22.844+02:00</app:edited><title>Spring &amp; LDAP</title><content type="html">&lt;p&gt;Just like you have JDBC/Hibernate/iBatis templates in Spring, we also have an LDAPTemplate. You can download the spring LDAP library from &lt;a href="http://springframework.org/ldap"&gt;http://springframework.org/ldap&lt;/a&gt;. I like this template approach simply because it lets us avoid common pitfalls such as not cleaning up resources after using an API (in JDBC its the connection, statement and resultset). Why bother when the template can do this for you. Same holds true for LDAP queries.     &lt;br /&gt;For this example I had the following setup:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Apache Directory Server 1.5.2. I decided to use the sample directory data. &lt;/li&gt;    &lt;li&gt;Installed the Apache Directory Studio eclipse plugin. &lt;/li&gt; &lt;/ul&gt; To confirm your setup. Open eclipse and go to the LDAP perspective. Create a new connection with following information:   &lt;ul&gt;   &lt;li&gt;hostname - localhost &lt;/li&gt;    &lt;li&gt;port - 10389 &lt;/li&gt;    &lt;li&gt;Bind DN or user - uid=admin,ou=system &lt;/li&gt;    &lt;li&gt;password - secret (this is the default password for apache ds) &lt;/li&gt; &lt;/ul&gt; This should let you into the directory. Under dc=example,dc=com I added two organizations (asia and americas).   &lt;br /&gt;&lt;img src="http://images.quickblogcast.com/26522-25187/ldapeclipse.jpg" width="289" border="0" /&gt;   &lt;br /&gt;Now for the Spring stuff.&amp;#160; &lt;p&gt;&lt;b&gt;package&lt;/b&gt; trial;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;import&lt;/b&gt; java.util.List;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.springframework.beans.factory.annotation.Autowired;&lt;b&gt;      &lt;br /&gt;import&lt;/b&gt; org.springframework.ldap.core.LdapTemplate;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.springframework.stereotype.Service;     &lt;br /&gt;@Service     &lt;br /&gt;&lt;b&gt;public&lt;/b&gt; &lt;b&gt;class&lt;/b&gt; LDAPSampleImpl &lt;b&gt;implements&lt;/b&gt; LDAPSample {&lt;/p&gt;  &lt;p&gt;@Autowired    &lt;br /&gt;&lt;b&gt;private&lt;/b&gt; LdapTemplate ldapTemplate;&lt;/p&gt;  &lt;p&gt;@Override    &lt;br /&gt;&lt;b&gt;public&lt;/b&gt; List getOrgNames() {     &lt;br /&gt;&lt;b&gt;return&lt;/b&gt; ldapTemplate.list(&amp;quot;&amp;quot;);     &lt;br /&gt;}     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;The spring XML file looks like:&lt;/p&gt;  &lt;p&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;    &lt;br /&gt;xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;     &lt;br /&gt;xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;     &lt;br /&gt;xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;     &lt;br /&gt;xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans     &lt;br /&gt;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     &lt;br /&gt;http://www.springframework.org/schema/aop     &lt;br /&gt;http://www.springframework.org/schema/aop/spring-aop-2.5.xsd     &lt;br /&gt;http://www.springframework.org/schema/context     &lt;br /&gt;http://www.springframework.org/schema/context/spring-context-2.5.xsd&amp;quot;&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;context:annotation-config /&amp;gt;    &lt;br /&gt;&amp;lt;context:component-scan base-package=&amp;quot;trial&amp;quot; /&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id=&amp;quot;ldapContextSource&amp;quot;    &lt;br /&gt;class=&amp;quot;org.springframework.ldap.core.support.LdapContextSource&amp;quot;&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;url&amp;quot; value=&amp;quot;ldap://localhost:10389&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;base&amp;quot; value=&amp;quot;dc=example,dc=com&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;userDn&amp;quot; value=&amp;quot;uid=admin,ou=system&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;secret&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;bean id=&amp;quot;ldapTemplate&amp;quot; class=&amp;quot;org.springframework.ldap.core.LdapTemplate&amp;quot;&amp;gt;    &lt;br /&gt;&amp;lt;constructor-arg ref=&amp;quot;ldapContextSource&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;     &lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/p&gt;  &lt;p&gt;Everything above is self explanatory. Now for the test case to execute all of this.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;package&lt;/b&gt; trial;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;import&lt;/b&gt; org.junit.Test;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.junit.runner.RunWith;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.springframework.beans.factory.annotation.Autowired;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.springframework.test.context.ContextConfiguration;     &lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.springframework.test.context.junit4.SpringJUnit4ClassRunner;&lt;/p&gt;  &lt;p&gt;@RunWith(SpringJUnit4ClassRunner.&lt;b&gt;class&lt;/b&gt;)     &lt;br /&gt;@ContextConfiguration(locations = { &amp;quot;classpath:spring-context.xml&amp;quot; })     &lt;br /&gt;&lt;b&gt;public&lt;/b&gt; &lt;b&gt;class&lt;/b&gt; DriverTestCase {&lt;/p&gt;  &lt;p&gt;@Autowired    &lt;br /&gt;&lt;b&gt;private&lt;/b&gt; LDAPSample ldap;     &lt;br /&gt;@Test     &lt;br /&gt;&lt;b&gt;public&lt;/b&gt; &lt;b&gt;void&lt;/b&gt; testGreeting() {     &lt;br /&gt;System.&lt;i&gt;out&lt;/i&gt;.println(ldap.getOrgNames());     &lt;br /&gt;}     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Running this unit test results in output    &lt;br /&gt;&amp;gt;&amp;gt; [ou=asia, ou=americas]&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-4690675216025374980?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lGB_fHF-y6SFCUEb1eh6n5AP-8c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lGB_fHF-y6SFCUEb1eh6n5AP-8c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lGB_fHF-y6SFCUEb1eh6n5AP-8c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lGB_fHF-y6SFCUEb1eh6n5AP-8c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/SUHP_9353RU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/4690675216025374980/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=4690675216025374980" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/4690675216025374980?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/4690675216025374980?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/SUHP_9353RU/spring-ldap.html" title="Spring &amp;amp; LDAP" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/spring-ldap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAHQXg8fyp7ImA9WxdRFU4.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-4420667664215517524</id><published>2008-06-04T00:38:00.001+02:00</published><updated>2008-06-04T00:38:50.677+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-04T00:38:50.677+02:00</app:edited><title>Send E-mail Using Spring and JavaMail</title><content type="html">&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This brief tutorial will show how to send e-mail using Spring and JavaMail. JavaMail can handle e-mail storage as well, but here we're just worrying about sending e-mail.&lt;/p&gt;  &lt;p&gt;I happen to be using Spring 2.5 but this ought to work for earlier versions of Spring as well (at least Spring 2.0 I think).&lt;/p&gt;  &lt;p&gt;Let's jump right in. You can configure your JavaMail session either in Spring itself or with JNDI. We'll look at both alternatives.&lt;/p&gt;  &lt;h4&gt;Alternative 1: Configuring JavaMail with Spring&lt;/h4&gt;  &lt;p&gt;You may be operating in an environment where you don't have a JNDI enterprise naming context (ENC) available. Or you may have some reason not to use it even if you do have a JNDI ENC. For example, I've written a &lt;a href="http://wheelersoftware.com/software/downloads.html"&gt;simple application monitor&lt;/a&gt;, and I'll be adding e-mail alerting shortly. This is a standalone app and so there's no JNDI ENC. No problem; I can just configure JavaMail in the Spring application context configuration as shown below.&lt;/p&gt;  &lt;pre&gt;&amp;lt;!-- Mail service --&amp;gt;
&amp;lt;bean id=&amp;quot;mailSender&amp;quot; class=&amp;quot;org.springframework.mail.javamail.JavaMailSenderImpl&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;host&amp;quot; value=&amp;quot;your.smtphost.com&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;port&amp;quot; value=&amp;quot;25&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;username&amp;quot; value=&amp;quot;yourusername&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;yourpassword&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;javaMailProperties&amp;quot;&amp;gt;
        &amp;lt;props&amp;gt;
            &amp;lt;!-- Use SMTP-AUTH to authenticate to SMTP server --&amp;gt;
            &amp;lt;prop key=&amp;quot;mail.smtp.auth&amp;quot;&amp;gt;true&amp;lt;/prop&amp;gt;
            &amp;lt;!-- Use TLS to encrypt communication with SMTP server --&amp;gt;
            &amp;lt;prop key=&amp;quot;mail.smtp.starttls.enable&amp;quot;&amp;gt;true&amp;lt;/prop&amp;gt;
        &amp;lt;/props&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;This bean is, as its name suggests, a mail sender. It is basically a wrapper around JavaMail SMTP, and the configuration reflects that. In the example I'm showing how you would enable SMTP-AUTH (supports authentication to the SMTP server) and TLS (supports message encryption), assuming your SMTP server has those capabilities. For more information see my article &lt;a href="http://wheelersoftware.com/articles/smtp-and-smtp-auth.html"&gt;SMTP and SMTP-AUTH&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; You will need to inject &lt;code&gt;mailSender&lt;/code&gt; into your mail-sending service bean.&lt;/p&gt;

&lt;p&gt;So that's how to configure JavaMail from Spring. Now here's how to do the same thing with JNDI, which you may want to do if you're running in an environment with a JNDI ENC (like an app server or a servlet container).&lt;/p&gt;

&lt;h4&gt;Alternative 2: Configuring JavaMail with JNDI&lt;/h4&gt;

&lt;h5&gt;Server JNDI configuration (using Tomcat 6 as an example)&lt;/h5&gt;

&lt;p&gt;First you will need to expose a JavaMail session factory through JNDI in your server environment. This is environment-dependent, but let's look at an example.&lt;/p&gt;

&lt;p&gt;Say you're using Tomcat 6. There are a couple things you must do. First, move &lt;code&gt;mail.jar&lt;/code&gt; and &lt;code&gt;activation.jar&lt;/code&gt; to your &lt;code&gt;tomcat/lib&lt;/code&gt; directory. I say &amp;quot;move&amp;quot; rather than &amp;quot;copy&amp;quot; because you will get an odd error if you leave the two JARs in your application classpath. The error is&lt;/p&gt;

&lt;pre&gt;java.lang.IllegalArgumentException: 
    Cannot convert value of type [javax.mail.Session] to required type
    [javax.mail.Session] for property 'session': no matching editors
    or conversion strategy found&lt;/pre&gt;

&lt;p&gt;Second, define your Tomcat JNDI configuration, which might look like this (e.g. in your &lt;code&gt;context.xml&lt;/code&gt; file):&lt;/p&gt;

&lt;p&gt;Code listing: &lt;code&gt;/META-INF/context.xml&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;

&amp;lt;Context path=&amp;quot;/myapp&amp;quot; docBase=&amp;quot;myapp&amp;quot; debug=&amp;quot;5&amp;quot; crossContext=&amp;quot;false&amp;quot;&amp;gt;

    &amp;lt;!-- JavaMail session factory --&amp;gt;
    &amp;lt;Resource name=&amp;quot;mail/Session&amp;quot;
              auth=&amp;quot;Container&amp;quot;
              type=&amp;quot;javax.mail.Session&amp;quot;
              username=&amp;quot;yourusername&amp;quot;
              password=&amp;quot;yourpassword&amp;quot;
              mail.debug=&amp;quot;true&amp;quot;
              mail.user=&amp;quot;yourusername&amp;quot;
              mail.password=&amp;quot;yourpassword&amp;quot;
              mail.transport.protocol=&amp;quot;smtp&amp;quot;
              mail.smtp.host=&amp;quot;your.smtphost.com&amp;quot;
              mail.smtp.auth=&amp;quot;true&amp;quot;
              mail.smtp.port=&amp;quot;25&amp;quot;
              mail.smtp.starttls.enable=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;/Context&amp;gt;&lt;/pre&gt;

&lt;p&gt;As with the non-JNDI example, I'm configuring for SMTP-AUTH and TLS. If you are using SMTP-AUTH (authenticated SMTP sessions, which you activate using &lt;code&gt;mail.smtp.auth=&amp;quot;true&amp;quot;&lt;/code&gt;), then you will need to specify the username and password twice, as shown above. Also, if your SMTP server supports it, you can tell JavaMail to encrypt sessions using TLS by setting &lt;code&gt;mail.smtp.starttls.enable=true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The above discussion applies only to Tomcat 6 (see &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html"&gt;Apache Tomcat 6.0 JNDI Resources HOWTO&lt;/a&gt; for detailed instructions); you'll need to consult your server docs to expose a JavaMail session factory through JNDI in your environment.&lt;/p&gt;

&lt;h5&gt;Spring configuration&lt;/h5&gt;

&lt;p&gt;We still need to create a mail sender, but the configuration is simpler since we did all the heavy lifting in &lt;code&gt;context.xml&lt;/code&gt; (or whatever, depending on your server environment). So for the Spring application context, all we need is:&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean id=&amp;quot;mailSender&amp;quot; class=&amp;quot;org.springframework.mail.javamail.JavaMailSenderImpl&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;session&amp;quot; ref=&amp;quot;mailSession&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; As before, you will need to inject &lt;code&gt;mailSender&lt;/code&gt; into your mail-sending service bean.&lt;/p&gt;

&lt;p&gt;So that takes care of configuring the mail sender, and also the JavaMail session factory if you are using JNDI. Let's visit one more topic before we dive into the code itself.&lt;/p&gt;

&lt;h4&gt;Creating an E-mail Template (Optional)&lt;/h4&gt;

&lt;p&gt;Sometimes the e-mail you want to send fits inside a standard template (e.g., maybe it always has the same sender, or maybe the same recipient, or whatever). You can define a template using Spring. Here's an example:&lt;/p&gt;

&lt;p&gt;Code listing: &lt;code&gt;Spring app context config file&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- Mail message --&amp;gt;
&amp;lt;bean id=&amp;quot;mailMessage&amp;quot; class=&amp;quot;org.springframework.mail.SimpleMailMessage&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;from&amp;quot;&amp;gt;
        &amp;lt;value&amp;gt;&amp;lt;![CDATA[Simple Application Monitor &amp;lt;noreply@somehost.com&amp;gt;]]&amp;gt;&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;to&amp;quot;&amp;gt;
        &amp;lt;value&amp;gt;&amp;lt;![CDATA[System Administrator &amp;lt;sysadmin@somehost.com&amp;gt;]]&amp;gt;&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;subject&amp;quot; value=&amp;quot;SAM Alert&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;You can include as many e-mail templates in a Spring app context configuration, including none if you don't need a template. Here I've defined a template that specifies a &amp;quot;from&amp;quot; field, a &amp;quot;to&amp;quot; field and a &amp;quot;subject&amp;quot; field. It doesn't specify the date or the body. That template works say for an application monitoring system but it wouldn't work for an e-commerce site's order confirmation e-mail, which would need to have a variable &amp;quot;to&amp;quot; field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; I didn't show it above, but you will need to inject any e-mail templates (i.e. mail messages) you create into your mail-sending service bean. Otherwise the service bean has no way to use the template.&lt;/p&gt;

&lt;p&gt;So that's that. Time for the Java code that actually sends the e-mail.&lt;/p&gt;

&lt;h4&gt;How to Send the E-mail from Your Service Bean&lt;/h4&gt;

&lt;p&gt;It turns out that the coding part is much simpler than the configuration (not that the config was too bad). Let's suppose for the sake of example that we want to send an e-mail based on the template that we defined above, and that you've injected that template into your service bean as &lt;code&gt;mailMessage&lt;/code&gt;. Then here's the service bean code that allows you to use the template to send an e-mail:&lt;/p&gt;

&lt;p&gt;Code listing: &lt;code&gt;Your service bean&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;SimpleMailMessage message = new SimpleMailMessage(mailMessage);
message.setSentDate(new Date());
message.setText(&amp;quot;Blah blah blah...&amp;quot;);
mailSender.send(message);&lt;/pre&gt;

&lt;p&gt;You can see we're creating a new message based on the &lt;code&gt;mailMessage&lt;/code&gt; e-mail template and &lt;code&gt;mailSender&lt;/code&gt; that we injected into said service bean.&lt;/p&gt;

&lt;p&gt;And that's it! Not too painful, right?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Willie Wheeler&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-4420667664215517524?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/b__VNNtPn-JrfKr_KTBNy69ZgR0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b__VNNtPn-JrfKr_KTBNy69ZgR0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/b__VNNtPn-JrfKr_KTBNy69ZgR0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b__VNNtPn-JrfKr_KTBNy69ZgR0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/35XspdJuRUc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/4420667664215517524/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=4420667664215517524" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/4420667664215517524?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/4420667664215517524?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/35XspdJuRUc/send-e-mail-using-spring-and-javamail.html" title="Send E-mail Using Spring and JavaMail" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/send-e-mail-using-spring-and-javamail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MARXYyfSp7ImA9WxdRFE0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-5708802037949962085</id><published>2008-06-02T14:24:00.001+02:00</published><updated>2008-06-02T14:24:04.895+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-02T14:24:04.895+02:00</app:edited><title>Spring Batch - Hello World</title><content type="html">&lt;p&gt;This is an introductory tutorial to Spring Batch. It does not aim to provide a complete guide to the framework but rather to facilitate the first contact. Spring Batch is quite rich in functionalities, and this is basically how I started learning it. Keep in mind that we will only be scratching the surface. &lt;/p&gt;  &lt;h5&gt;Before we start&lt;/h5&gt;  &lt;p&gt;All the examples will have the lofty task of printing &amp;quot;Hello World!&amp;quot; though in different ways. They were developed with Spring Batch 1.0. I'll provide a Maven 2 project and I'll run the examples with Maven but of course it is not a requirement to work with Spring Batch. &lt;/p&gt;  &lt;h5&gt;Spring Batch in 2 Words&lt;/h5&gt;  &lt;p&gt;Fortunately, Spring Batch model objects have self-explanatory names. Let's try to enumerate the most important and to link them together: &lt;/p&gt;  &lt;p&gt;A batch &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/Job.html"&gt;Job&lt;/a&gt; is composed of one or more &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/Step.html"&gt;Step&lt;/a&gt;s. A &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobInstance.html"&gt;JobInstance&lt;/a&gt; represents a given Job, parametrized with a set of typed properties called &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobParameters.html"&gt;JobParameters&lt;/a&gt;. Each run of of a JobInstance is a &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobExecution.html"&gt;JobExecution&lt;/a&gt;. Imagine a job reading entries from a data base and generating an xml representation of it and then doing some clean-up. We have a Job composed of 2 steps: reading/writing and clean-up. If we parametrize this job by the date of the generated data then our Friday the 13th job is a JobInstance. Each time we run this instance (if a failure occurs for instance) is a JobExecution. This model gives a great flexibility regarding how jobs are launched and run. This naturally brings us to launching jobs with their job parameters, which is the responsibility of &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/launch/JobLauncher.html"&gt;JobLauncher&lt;/a&gt;. Finally, various objects in the framework require a &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/repository/JobRepository.html"&gt;JobRepository&lt;/a&gt; to store runtime information related to the batch execution. In fact, Spring Batch domain model is much more elaborate but this will suffice for our purpose. &lt;/p&gt;  &lt;p&gt;Well, it took more than 2 words and I feel compelled to make a joke about it, but I won't. So let's move to the next section.&lt;/p&gt;  &lt;h5&gt;Common Objects&lt;/h5&gt;  &lt;p&gt;For each job, we will use a separate xml context definition file. However there is a number of common objects that we will need recurrently. I will group them in an applicationContext.xml which will be imported from within job definitions. Let's go through these common objects: &lt;/p&gt;  &lt;h5&gt;JobLauncher&lt;/h5&gt;  &lt;p&gt;JobLaunchers are responsible for starting a Job with a given job parameters. The provided implementation, &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/launch/support/SimpleJobLauncher.html"&gt;SimpleJobLauncher&lt;/a&gt;, relies on a &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/core/task/TaskExecutor.html"&gt;TaskExecutor&lt;/a&gt; to launch the jobs. If no specific TaskExecutor is set then a &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/core/task/SyncTaskExecutor.html"&gt;SyncTaskExecutor&lt;/a&gt; is used. &lt;/p&gt;  &lt;h5&gt;JobRepository&lt;/h5&gt;  &lt;p&gt;We will use the &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/repository/support/SimpleJobRepository.html"&gt;SimpleJobRepository&lt;/a&gt; implementation which requires a set of execution Daos to store its information. &lt;/p&gt;  &lt;h5&gt;JobInstanceDao, JobExecutionDao, StepExecutionDao&lt;/h5&gt;  &lt;p&gt;These data access objects are used by SimpleJobRepository to store execution related information. Two sets of implementations are provided by Spring Batch: Map based (in-memory) and Jdbc based. In a real application the Jdbc variants are more suitable but we will use the simpler in-memory alternative in this example. &lt;/p&gt;  &lt;p&gt;Here's our applicationContext.xml:&lt;/p&gt;  &lt;pre&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
	xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd&amp;quot;&amp;gt;

  &amp;lt;bean id=&amp;quot;jobLauncher&amp;quot; class=&amp;quot;org.springframework.batch.core.launch.support.SimpleJobLauncher&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;
    
  &amp;lt;bean id=&amp;quot;jobRepository&amp;quot; class=&amp;quot;org.springframework.batch.core.repository.support.SimpleJobRepository&amp;quot;&amp;gt;
      &amp;lt;constructor-arg&amp;gt;
          &amp;lt;bean class=&amp;quot;org.springframework.batch.core.repository.dao.MapJobInstanceDao&amp;quot;/&amp;gt;
      &amp;lt;/constructor-arg&amp;gt;
      &amp;lt;constructor-arg&amp;gt;
          &amp;lt;bean class=&amp;quot;org.springframework.batch.core.repository.dao.MapJobExecutionDao&amp;quot; /&amp;gt;
      &amp;lt;/constructor-arg&amp;gt;
      &amp;lt;constructor-arg&amp;gt;
          &amp;lt;bean class=&amp;quot;org.springframework.batch.core.repository.dao.MapStepExecutionDao&amp;quot;/&amp;gt;
      &amp;lt;/constructor-arg&amp;gt;
  &amp;lt;/bean&amp;gt;

&amp;lt;/beans&amp;gt;&lt;/pre&gt;

&lt;h5&gt;Hello World with Tasklets&lt;/h5&gt;

&lt;p&gt;A tasklet is an object containing any custom logic to be executed as a part of a job. Tasklets are built by implementing the &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/step/tasklet/Tasklet.html"&gt;Tasklet&lt;/a&gt; interface. Let's implement a simple tasklet that simply prints a message:&lt;/p&gt;

&lt;pre&gt;public class PrintTasklet implements Tasklet{

  private String message;

  public void setMessage(String message) {
      this.message = message;
  }
    
  public ExitStatus execute() throws Exception {
      System.out.print(message);
      return ExitStatus.FINISHED;
  }
}&lt;/pre&gt;

&lt;p&gt;Notice that the execute method returns an &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/repeat/ExitStatus.html"&gt;ExitStatus&lt;/a&gt; to indicate the status of the execution of the tasklet.&lt;/p&gt;

&lt;p&gt;We will define our first job now in a simpleJob.xml application context. We will use the &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/job/SimpleJob.html"&gt;SimpleJob&lt;/a&gt; implementation which executes all of its steps sequentailly. In order to plug a tasklet into a job, we need a &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/step/tasklet/TaskletStep.html"&gt;TaskletStep&lt;/a&gt;. I also added an abstract bean definition for tasklet steps in order to simplify the configuration:&lt;/p&gt;

&lt;pre&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
	xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd&amp;quot;&amp;gt;
                                
  &amp;lt;import resource=&amp;quot;applicationContext.xml&amp;quot;/&amp;gt;
    
  &amp;lt;bean id=&amp;quot;hello&amp;quot; class=&amp;quot;helloworld.PrintTasklet&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;message&amp;quot; value=&amp;quot;Hello&amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;
    
  &amp;lt;bean id=&amp;quot;space&amp;quot; class=&amp;quot;helloworld.PrintTasklet&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;message&amp;quot; value=&amp;quot; &amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;
   
  &amp;lt;bean id=&amp;quot;world&amp;quot; class=&amp;quot;helloworld.PrintTasklet&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;message&amp;quot; value=&amp;quot;World!&amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;

  &amp;lt;bean id=&amp;quot;taskletStep&amp;quot; abstract=&amp;quot;true&amp;quot;
      class=&amp;quot;org.springframework.batch.core.step.tasklet.TaskletStep&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;
    
  &amp;lt;bean id=&amp;quot;simpleJob&amp;quot; class=&amp;quot;org.springframework.batch.core.job.SimpleJob&amp;quot;&amp;gt;
      &amp;lt;property name=&amp;quot;name&amp;quot; value=&amp;quot;simpleJob&amp;quot; /&amp;gt;
      &amp;lt;property name=&amp;quot;steps&amp;quot;&amp;gt;
          &amp;lt;list&amp;gt;
              &amp;lt;bean parent=&amp;quot;taskletStep&amp;quot;&amp;gt;
                  &amp;lt;property name=&amp;quot;tasklet&amp;quot; ref=&amp;quot;hello&amp;quot;/&amp;gt;
              &amp;lt;/bean&amp;gt;
              &amp;lt;bean parent=&amp;quot;taskletStep&amp;quot;&amp;gt;
                  &amp;lt;property name=&amp;quot;tasklet&amp;quot; ref=&amp;quot;space&amp;quot;/&amp;gt;
              &amp;lt;/bean&amp;gt;
              &amp;lt;bean parent=&amp;quot;taskletStep&amp;quot;&amp;gt;;
                  &amp;lt;property name=&amp;quot;tasklet&amp;quot; ref=&amp;quot;world&amp;quot;/&amp;gt;
              &amp;lt;/bean&amp;gt;
          &amp;lt;/list&amp;gt;
      &amp;lt;/property&amp;gt;
      &amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot;/&amp;gt;
  &amp;lt;/bean&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/pre&gt;

&lt;h5&gt;Running the Job&lt;/h5&gt;

&lt;p&gt;Now we need something to kick-start the execution of our jobs. Spring Batch provides a convenient class to achieve that from the command line: &lt;a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/launch/support/CommandLineJobRunner.html"&gt;CommandLineJobRunner&lt;/a&gt;. In its simplest form this class takes 2 arguments: the xml application context containing the job to launch and the bean id of that job. It naturally requires a JobLauncher to be configured in the application context. Here's how to launch the job with Maven. Of course, it can be run with the java command directly (you need to specify the class path then): &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
mvn exec:java -Dexec.mainClass=org.springframework.batch.core.launch.support.CommandLineJobRunner 
-Dexec.args=&amp;quot;simpleJob.xml simpleJob&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hopefully, your efforts will be rewarded with a &amp;quot;Hello World!&amp;quot; printed on the console.&lt;/p&gt;

&lt;p&gt;The code source can be downloaded &lt;a href="http://jroller.com/resources/0/0xcafebabe/Spring-Batch-Hello-World1.jar"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Tareq Abed Rabbo&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-5708802037949962085?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JABE9D0cOHFtGw9-jBhvyC3GF_c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JABE9D0cOHFtGw9-jBhvyC3GF_c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JABE9D0cOHFtGw9-jBhvyC3GF_c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JABE9D0cOHFtGw9-jBhvyC3GF_c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/TnT5a92IX6U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/5708802037949962085/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=5708802037949962085" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5708802037949962085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/5708802037949962085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/TnT5a92IX6U/spring-batch-hello-world.html" title="Spring Batch - Hello World" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/06/spring-batch-hello-world.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EERX8zfyp7ImA9WxdREEU.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-813430420522131295</id><published>2008-05-29T21:33:00.001+02:00</published><updated>2008-05-29T21:33:24.187+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-29T21:33:24.187+02:00</app:edited><title>REST 0.7, now with Spring support</title><content type="html">&lt;p&gt;REST 0.7 is out and now includes support for the Spring framework. Peter Liu has written a nice example that uses NetBeans 6.1 to create a web application that contains a Spring-aware servlet, a singleton resource, and a request resource. His example is derived from a &lt;a href="http://blogs.sun.com/sandoz/entry/integrating_jersey_and_spring_take"&gt;blog post by Paul Sandoz&lt;/a&gt; showing how to manually integrate Spring and Jersey (and predating REST 0.7). &lt;/p&gt;  &lt;p&gt;Note that in REST 0.8, Spring support will be enhanced so that the user does not have to create a Spring-aware servlet. &lt;/p&gt;  &lt;p&gt;This is Peter's example. It requires NetBeans IDE Web and Java EE distribution 6.1 and REST plugin 0.7. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a Web Application project and name it SpringRestWebApp. On the Frameworks page of the project creation wizard, select Spring Web MVC 2.5. &lt;/li&gt;    &lt;li&gt;Right-click the SpringRestWebApp node and choose New &amp;gt; RESTful Web Services from Patterns. Select the Singleton pattern and name the resource Singleton (class name will then be SingletonResource). Create the test.servlet package to contain the resource. &lt;/li&gt;    &lt;li&gt;Replace the code in SingletonResource with the following. Right-click in the code and select Fix Imports after replacing the code.      &lt;pre&gt;@Path(&amp;quot;singleton&amp;quot;)
@Singleton
public class SingletonResource {
    
    private String name;
    
    private int uses = 0;
    
    private synchronized int getCount() {
        return ++uses;
    }
    
    public SingletonResource() {
        name = &amp;quot;unset&amp;quot;;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @GET
    @ProduceMime(&amp;quot;text/plain&amp;quot;)
    public String getDescription() {
        return &amp;quot;Name: &amp;quot; + getName() + &amp;quot;, Uses: &amp;quot; + Integer.toString(getCount());
    }
}&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;Create another RESTful Web Service using the Singleton pattern. Name the resource PerRequest and create it in the same test.servlet package. &lt;/li&gt;

  &lt;li&gt;Replace the code in PerRequestResource with the following. Right-click in the code and select Fix Imports when you are done. 
    &lt;pre&gt;@Path(&amp;quot;request&amp;quot;)
public class PerRequestResource {
    
    private String name;
    
    private int uses = 0;
    
    private synchronized int getCount() {
        return ++uses;
    }
    
    public PerRequestResource() {
        name = &amp;quot;unset&amp;quot;;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @GET
    @ProduceMime(&amp;quot;text/plain&amp;quot;)
    public String getDescription() {
        return &amp;quot;Name: &amp;quot; + getName() + &amp;quot;, Uses: &amp;quot; + Integer.toString(getCount());
    }
}&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;Right-click the SpringRestWebApp node and choose New &amp;gt; Servlet. Name the servlet SpringServlet and create it in the test.servlet package. &lt;/li&gt;

  &lt;li&gt;Replace the code in SpringServlet with the following. Right-click in the code and select Fix Imports when done. 
    &lt;pre&gt;public class SpringServlet extends ServletContainer {
    
    private static class SpringComponentProvider implements ComponentProvider {
        private ApplicationContext springContext;

        SpringComponentProvider(ApplicationContext springContext) {
            this.springContext = springContext;
        }
        
        private String getBeanName(Class c) {
            String names[] = springContext.getBeanNamesForType(c);
            if (names.length == 0) {
                return null;
            } else if (names.length &amp;gt; 1) {
                throw new RuntimeException(&amp;quot;Multiple configured beans for &amp;quot; 
                        + c.getName());
            }
            return names[0];            
        }
        
        public Object getInstance(Scope scope, Class c) 
                throws InstantiationException, IllegalAccessException {            
            String beanName = getBeanName(c);
            if (beanName == null) return null;
            
            if (scope == Scope.WebApplication &amp;amp;&amp;amp; 
                    springContext.isSingleton(beanName)) { 
                return springContext.getBean(beanName, c);
            } else if (scope == Scope.ApplicationDefined &amp;amp;&amp;amp;
                    springContext.isPrototype(beanName) &amp;amp;&amp;amp;
                    !springContext.isSingleton(beanName)) {
                return springContext.getBean(beanName, c);
            } else {
                return null;
            }
        }

        public Object getInstance(Scope scope, Constructor contructor, 
                Object[] parameters) 
                throws InstantiationException, IllegalArgumentException, 
                IllegalAccessException, InvocationTargetException {
            return null;
        }

        public Object getInjectableInstance(Object instance) {
           return instance;
        }
        
        public void inject(Object instance) {
        }        
    };
    
    @Override
    protected void initiate(ResourceConfig rc, WebApplication wa) {
        ApplicationContext springContext = WebApplicationContextUtils.
                getRequiredWebApplicationContext(getServletContext());
        
        wa.initiate(rc, new SpringComponentProvider(springContext));
    }        
}&lt;/pre&gt;

    &lt;p&gt;Paul Sandoz writes &amp;quot;Notice that SpringServlet extends ServletContainer and the initiate method is overridden. This method creates an ApplicationContext and then initiates the WebApplication by passing in an instance of the static inner class SpringComponentProvider. This class implements ComponentProvider and the getInstance method will attempt to obtain a Spring bean that is present and matches the requested scope, if so then the bean instance is returned otherwise null is returned. (Note that the getInstance method with a Constructor type parameter is not implemented, this is because we have not determined how to support constructors with Spring beans).&amp;quot;&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;Open the project's web.xml file. Replace &lt;tt&gt;com.sun.ws.rest.impl.container.servlet.ServletAdaptor&lt;/tt&gt; with &lt;tt&gt;test.servlet.SpringServlet&lt;/tt&gt;. &lt;/li&gt;

  &lt;li&gt;Add the following to the project's applicationContext.xml file, to initialize the resources: 
    &lt;pre&gt;&amp;lt;bean id=&amp;quot;bean1&amp;quot; scope=&amp;quot;singleton&amp;quot; class=&amp;quot;test.servlet.SingletonResource&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;name&amp;quot; value=&amp;quot;Mr. Singleton Bean&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;bean id=&amp;quot;bean2&amp;quot; scope=&amp;quot;prototype&amp;quot; class=&amp;quot;test.servlet.PerRequestResource&amp;quot;&amp;gt;
     &amp;lt;property name=&amp;quot;name&amp;quot; value=&amp;quot;Mr. PerRequest Bean&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;Right-click the project node and select Test RESTful Web Services. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you test the Singleton path, the service returns the Mr. Singleton Bean property and the Uses value increments for every request. When you test the PerRequest path, the service returns the Mr. PerRequest Bean property and the Uses value does not increment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by: Jeffrey Rubinoff&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-813430420522131295?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sH25f7c9zIrSHVg0_gFRACjEqJo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sH25f7c9zIrSHVg0_gFRACjEqJo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sH25f7c9zIrSHVg0_gFRACjEqJo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sH25f7c9zIrSHVg0_gFRACjEqJo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/RtC5Oy4v0Qw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/813430420522131295/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=813430420522131295" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/813430420522131295?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/813430420522131295?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/RtC5Oy4v0Qw/rest-07-now-with-spring-support.html" title="REST 0.7, now with Spring support" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/rest-07-now-with-spring-support.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QBQ3s5fyp7ImA9WxdSGE8.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-9155934688227340294</id><published>2008-05-26T20:09:00.001+02:00</published><updated>2008-05-26T20:09:12.527+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-26T20:09:12.527+02:00</app:edited><title>Lessons Learned From Spring’s @Autowired</title><content type="html">&lt;p&gt;Last &lt;a href="http://blog.rainer.eschen.name/2007/11/27/spring-25-its-time-for-annotation-driven-injection/"&gt;November&lt;/a&gt; we got &lt;a href="http://blog.rainer.eschen.name/tag/spring/"&gt;Spring&lt;/a&gt; 2.5 and with it the possibility to use annotations for &lt;a href="http://blog.rainer.eschen.name/tag/dependency-injection/"&gt;dependency injection&lt;/a&gt; (DI). Annotations can be used instead or mixed with the classic &lt;a href="http://blog.rainer.eschen.name/tag/application-context/"&gt;application context&lt;/a&gt; file(s) based on XML.&lt;/p&gt;  &lt;p&gt;If you compare the former more complex XML configurations with what you still have to keep, after using annotations, it&amp;#8217;s quite amazing how straightforward the XML becomes. For projects with complex DI configurations it is possible to transfer the configuration in steps. &lt;/p&gt;  &lt;p&gt;For our ICEfaces Web application e.g. we started with something like this:&lt;/p&gt;  &lt;pre&gt;&amp;lt;bean id=&amp;quot;businessObject&amp;quot;
    class=&amp;quot;com.test.BusinessObject&amp;quot;
    scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
    &amp;lt;property name=&amp;quot;simpleProperty&amp;quot;&amp;gt;
        &amp;lt;value&amp;gt;Hello World&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;businessObjectAdministration&amp;quot;
    class=&amp;quot;com.test.BusinessObjectAdministration&amp;quot;
    scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
    &amp;lt;property name=&amp;quot;simpleProperty&amp;quot;&amp;gt;
        &amp;lt;value&amp;gt;Hello Administrators&amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;backingBean&amp;quot;
    class=&amp;quot;com.test.BackingBean&amp;quot; scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
        &amp;lt;property name=&amp;quot;businessObject&amp;quot;&amp;gt;
            &amp;lt;ref bean=&amp;quot;businessObject&amp;quot; /&amp;gt;
        &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;backingBeanAdministration&amp;quot;
    class=&amp;quot;com.test.BackingBeanAdministration&amp;quot;
    scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
        &amp;lt;property name=&amp;quot;businessObjectAdministration&amp;quot;&amp;gt;
            &amp;lt;ref bean=&amp;quot;businessObjectAdministration&amp;quot; /&amp;gt;
        &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;This is pretty verbose. The references can also be written in compact syntax, like this:&lt;/p&gt;

&lt;pre&gt;&amp;lt;property name=&amp;quot;businessObject&amp;quot; ref=&amp;quot;businessObject&amp;quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;Here are the corresponding classes:&lt;/p&gt;

&lt;pre&gt;package com.test;
public class BusinessObject {

    String simpleProperty;

    public void setSimpleProperty(String simpleProperty) {
        this.simpleProperty = simpleProperty;
    }
    public String getSimpleProperty() {
        return this.simpleProperty;
    }
}

package com.test;
public class BusinessObjectAdministration extends
    BusinessObject {

}

package com.test;
public class BackingBean {

    BusinessObject businessObject;

    public void setBusinessObject(BusinessObject businessObject) {
        this.businessObject = businessObject;
    }
    public String getBusinessObject() {
        return this.businessObject;
    }
}

package com.test;
public class BackingBeanAdministration {

    BusinessObjectAdministration businessObjectAdministration;

    public void setBusinessObjectAdministration(
        BusinessObjectAdministration businessObjectAdministration) {
        this.businessObjectAdministration = businessObjectAdministration;
    }
    public String getBusinessObjectAdministration() {
        return this.businessObjectAdministration;
    }
}&lt;/pre&gt;

&lt;p&gt;Each backing bean in this example uses a corresponding business object, whereas &lt;code&gt;BusinessObjectAdministration&lt;/code&gt; is a child of &lt;code&gt;BusinessObject&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;Adding Annotations&lt;/h5&gt;

&lt;p&gt;So, what do we have to change to get this &lt;a href="http://blog.rainer.eschen.name/tag/annotation/"&gt;annotation&lt;/a&gt; stuff working? The reference attributes in the backing beans get an &lt;code&gt;@Autowired&lt;/code&gt;. With this a corresponding &lt;a href="http://blog.rainer.eschen.name/tag/spring/"&gt;Spring&lt;/a&gt; bean with the same type is searched during the &lt;a href="http://blog.rainer.eschen.name/tag/dependency-injection/"&gt;dependency injection&lt;/a&gt;. Additionally, we can skip getter and setter for the reference attributes.&lt;/p&gt;

&lt;pre&gt;public class BackingBean {

    @Autowired
    BusinessObject businessObject;

    ...
}

public class BackingBeanAdministration {

    @Autowired
    BusinessObjectAdministration businessObjectAdministration;

    ...
}&lt;/pre&gt;

&lt;p&gt;With this we can also skip the corresponding properties in the &lt;a href="http://blog.rainer.eschen.name/tag/application-context/"&gt;application context&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&amp;lt;bean id=&amp;quot;backingBean&amp;quot;
    class=&amp;quot;com.test.BackingBean&amp;quot; scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;backingBeanAdministration&amp;quot;
    class=&amp;quot;com.test.BackingBeanAdministration&amp;quot;
    scope=&amp;quot;session&amp;quot;&amp;gt;
    &amp;lt;aop :scoped-proxy/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/pre&gt;

&lt;p&gt;Pretty simple. But, when you deploy this you get an exception. &lt;a href="http://blog.rainer.eschen.name/tag/spring/"&gt;Spring&lt;/a&gt; will tell you that it has problems to inject the &lt;code&gt;businessObject&lt;/code&gt; reference into &lt;code&gt;backingBean.BusinessObject&lt;/code&gt;, because there are &lt;em&gt;two&lt;/em&gt; matches. We&amp;#8217;ve an &lt;a href="http://blog.rainer.eschen.name/tag/inheritance/"&gt;inheritance&lt;/a&gt; between &lt;code&gt;BusinessObject&lt;/code&gt; and &lt;code&gt;BusinessObjectAdministration&lt;/code&gt;. So, both are matched in this case.&lt;/p&gt;

&lt;p&gt;Matching via type is not the best solution here. But, there&amp;#8217;s another &lt;a href="http://blog.rainer.eschen.name/tag/annotation/"&gt;annotation&lt;/a&gt; that allows to name the &lt;a href="http://blog.rainer.eschen.name/tag/spring/"&gt;Spring&lt;/a&gt; bean we wanna be used during the &lt;a href="http://blog.rainer.eschen.name/tag/dependency-injection/"&gt;dependency injection&lt;/a&gt;, called &lt;code&gt;@Qualifier&lt;/code&gt;. It has a parameter, that allows to set the bean&amp;#8217;s name.&lt;/p&gt;

&lt;p&gt;When we add this to the backing beans everything works fine.&lt;/p&gt;

&lt;pre&gt;public class BackingBean {

    @Autowired
    @Qualifier(&amp;quot;businessObject&amp;quot;)
    BusinessObject businessObject;

    ...
}

public class BackingBeanAdministration {

    @Autowired
    @Qualifier(&amp;quot;businessObjectAdministration&amp;quot;)
    BusinessObjectAdministration businessObjectAdministration;

    ...
}&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-9155934688227340294?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m_zhOJHp5cpU2gOHmQjg-j5h6YM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m_zhOJHp5cpU2gOHmQjg-j5h6YM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m_zhOJHp5cpU2gOHmQjg-j5h6YM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m_zhOJHp5cpU2gOHmQjg-j5h6YM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/hP0cOrHJGm4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/9155934688227340294/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=9155934688227340294" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/9155934688227340294?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/9155934688227340294?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/hP0cOrHJGm4/lessons-learned-from-springs-autowired.html" title="Lessons Learned From Spring’s @Autowired" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/lessons-learned-from-springs-autowired.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YFSXkyeyp7ImA9WxdSF08.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-6045118022764274749</id><published>2008-05-25T16:18:00.001+02:00</published><updated>2008-05-25T16:18:38.793+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-25T16:18:38.793+02:00</app:edited><title>SpringSource Application Platform</title><content type="html">&lt;p&gt;So, &lt;a href="http://www.springsource.com/web/guest/home"&gt;Spring Source&lt;/a&gt; has been able to keep a secret from us &lt;img alt=":-)" src="http://www.techper.net/blog/wp-includes/images/smilies/icon_smile.gif" /&gt; Secretly, they have been developing what looks a lot like &lt;a href="http://www.springsource.com/web/guest/products/suite/applicationplatform"&gt;a new application server&lt;/a&gt;, not like the &lt;a href="http://java.sun.com/javaee/"&gt;JEE&lt;/a&gt; market, but with the &lt;a href="http://www.springframework.org/"&gt;springframework&lt;/a&gt; at its core. A well kept secret, which I did not see coming, even though we might have been able to, given the portfolio of products and people now employed at &lt;a href="http://www.springsource.com/web/guest/home"&gt;Spring Source&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;And what are we to say to that? Me, personally, I welcome it. Yeah yeah, it is a non-standard, proprietary way to go, when compared to JEE servers. But, I am already utilizing the &lt;a href="http://www.springframework.org/"&gt;springframework&lt;/a&gt; as my main engine and have long time gone the POJO ORM way. All this way before JEE5 and JPA. And I like it. I have even ditched using JEE5 EJBs on new products, because I find the spring model superior in many ways.&lt;/p&gt;  &lt;p&gt;And about it being proprietary. The platform is GPLv3 licensed, which I really like. In my eyes, &lt;strong&gt;&lt;em&gt;the GPL license model is good for exactly this kind of product&lt;/em&gt;&lt;/strong&gt;. It ensures openness, also when utilized by others, which adds or enhances it. We will have to give our contributions back! And that is good, for something that acts as a platform. Just like the Linux kernel, actually.&lt;/p&gt;  &lt;h4&gt;What Is It?&lt;/h4&gt;  &lt;p&gt;At a first glance, it looked to me as a lot like a server like the JBoss micro kernel architecture, which could (can) be tailored to only run the exact parts of JEE, that your application needs. No need to start JMS servers and EJB containers, if you ain&amp;#8217;t gonna need it. I never got to like JBoss, though.&lt;/p&gt;  &lt;p&gt;At a second glance, this is actually just a minor part of the Spring Source Application Platform (as I see the benefits to me). They are using &lt;a href="http://www.osgi.org/"&gt;OSGi&lt;/a&gt; (through a Spring Dynamic Modules kernel), to control their &amp;#8220;services when needed&amp;#8221; in the server, &lt;strong&gt;&lt;em&gt;but they are also using it (OSGi) as the technology for deployment units for the applications running on it&lt;/em&gt;&lt;/strong&gt;. Our applications! And that is where I see some benefits for me, as an application developer.&lt;/p&gt;  &lt;h4&gt;What Is the OSGi Part All About?&lt;/h4&gt;  &lt;p&gt;SpringSource consider war-deployment as not good enough and suggests the use of OSGi as deployment modules instead. I agree, that this might be a good choice, I just &lt;em&gt;hope it will be simple enough to use&lt;/em&gt;. I do not agree totally, on the points of &lt;a href="http://java.dzone.com/news/interview-rod-johnson-springso"&gt;Rod Johnson here&lt;/a&gt;, where he states this about war deployment:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;#8230;the great deal of duplication going on with web.xml files, Spring configuration file, and so on. Also, the Java EE web-inf folder is unversioned and messy. It has problems with dependencies and potential duplications&amp;#8230;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The war deployment unit (web.xml) is nice and simple. I for one, don&amp;#8217;t mind putting the configuration data in there. Actually, I recently saw, that the expert group on the next servlet spec are working on features to make this easier. They are talking about &lt;a href="http://blogs.webtide.com/gregw/2008/04/25/1209090806878.html"&gt;auto-discovery of configuration data from web frameworks&lt;/a&gt;, so the need to edit web.xml becomes minor or vanishes.&lt;/p&gt;  &lt;p&gt;What I like about the OSGi way of deployment, is the tight control on dependencies, that your can utilize. One example is how you tightly control which packages, a given (deployed) component, exports to other deployed components. I hope to see this solve the jar dependencies hell. Something that upcoming Java versions, &lt;a href="http://jcp.org/en/jsr/detail?id=294"&gt;JSR-294&lt;/a&gt; and &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;JSR-277&lt;/a&gt; is also seeking to solve, albeit with a far too long time frame. OSGi is here today and works.&lt;/p&gt;  &lt;p&gt;What&amp;#8217;s more is, that OSGi is not only used to implement the micro kernel in the Spring DM kernel, but is also exposed to us developers, to use when deploying. I have recently battled an issue with hibernate using cglib and an old asm library, while at the same time needing CXF 2.1 which in turn needs asm lib 2.x. The problem was, that the two asm lib versions where binary incompatible. This can be solved elegantly with OSGi, by deploying each part of the application as separately packages groups, and not exposing the asm libs from these modules. Each group can then have their own asm library jar. Something which we, today, are trying to solve by re-packaging libraries under other package names, using tools like &lt;a href="http://code.google.com/p/jarjar/"&gt;JarJar Links&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Everyday Development&lt;/h4&gt;  &lt;p&gt;So, what does working with Spring Source Application Platform actually mean to us developers then, in our daily work?&lt;/p&gt;  &lt;h5&gt;The Server&lt;/h5&gt;  &lt;p&gt;Well, I like the idea of a spring-powered environment, where the need for configuration is far less. I hope it will be as easy as it is to start with EJB3, but with the power to extend with all the extra &amp;#8220;magic&amp;#8221;. I think JEE5 has had one good thing going for it, and that is it being easier to get started with. No need to know about and correctly configure the spring bean context.&lt;/p&gt;  &lt;h5&gt;The Need for OSGi Bundles&lt;/h5&gt;  &lt;p&gt;The libraries that our application depends upon, such as hibernate, spring, commons, etc., &lt;em&gt;must&lt;/em&gt; be available as an OSGi bundle or library. This is the way of expressing dependencies in SpringSource Application Platform. What did we do before? Well, most of us just expressed our dependencies in the maven POM and let it (maven) download the proper jars from a maven repository. The maven repository has grown up to be very important, hence just about all java libraries are published in it. &lt;em&gt;But not as OSGi bundles&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;To address the need for OSGi packaged versions of libraries , SpringSource has made available &lt;a href="http://www.springsource.com/repository/"&gt;their own repository of OSGi bundles here&lt;/a&gt;. Naturally, this repository is only a fraction of what is in the maven repository, and this will be a nuisance in the beginning. Frankly, I can only see that nuisance going away, if the SpringSource Application Platform becomes world popular, as they (SpringSource) will need community contributions from framework/lib developers themselves, to keep up with the steady flow of new versions.&lt;/p&gt;  &lt;p&gt;Maybe the maven repository should be extended, to include such bundles. It seems to be the packaging of tomorrow. Not just because of OSGi becoming more and more popular and the Spring Source Application Platform, but also because of the &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;upcoming work on modularity in the Java platform&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Sun &amp;#8220;Answering&amp;#8221;&lt;/h4&gt;  &lt;p&gt;I do not know, if it is stuff like SpringSource Application Platform, that is pushing &lt;a href="http://jcp.org/en/jsr/detail?id=294"&gt;JSR-294&lt;/a&gt; and &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;JSR-277&lt;/a&gt; to &amp;#8220;merge&amp;#8221;. It is a fact, that the springframework, together with powerfull POJO ORM frameworks, have threatened the JEE world heavily the last couple of years. Sun has had work on modularity going on for quite some time now (in &lt;a href="http://jcp.org/en/jsr/detail?id=294"&gt;JSR-294&lt;/a&gt; and &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;JSR-277&lt;/a&gt;), but it has also received a lot of heat. Mostly for &lt;em&gt;not&lt;/em&gt; leaning to just accept the existing de-facto standard, OSGi, and go with that. Well, it seems they (Sun) might be shaping up. &lt;a href="http://weblogs.java.net/blog/stanleyh/"&gt;Stanley Ho&lt;/a&gt;, spec lead of &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;JSR-277&lt;/a&gt;, &lt;a href="http://weblogs.java.net/blog/stanleyh/archive/2008/05/updates_on_modu.html"&gt;announces&lt;/a&gt; that &lt;a href="http://www.doc.ic.ac.uk/%7Eabuckley/"&gt;Alex Buckley&lt;/a&gt; (the spec lead on the other JSR on modularity, &lt;a href="http://jcp.org/en/jsr/detail?id=294"&gt;JSR-294&lt;/a&gt;) will join &lt;a href="http://jcp.org/en/jsr/detail?id=277"&gt;JSR-277&lt;/a&gt; and bring the language level module specs into that JSR group.&lt;/p&gt;  &lt;p&gt;All good stuff.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-6045118022764274749?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4GkGJ0fRNvxvfxkynoORC4hqGDA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4GkGJ0fRNvxvfxkynoORC4hqGDA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4GkGJ0fRNvxvfxkynoORC4hqGDA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4GkGJ0fRNvxvfxkynoORC4hqGDA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/TZRCnXvt8q8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/6045118022764274749/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=6045118022764274749" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/6045118022764274749?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/6045118022764274749?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/TZRCnXvt8q8/springsource-application-platform.html" title="SpringSource Application Platform" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/springsource-application-platform.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cGQHc4eCp7ImA9WxdSF08.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-1864907158363895807</id><published>2008-05-25T16:17:00.001+02:00</published><updated>2008-05-25T16:17:01.930+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-25T16:17:01.930+02:00</app:edited><title>OSGi and Spring</title><content type="html">&lt;p&gt;It&amp;#8217;s time to move on and show the simple elegance Spring brings to OSGi development using the HelloWorldSpec sample from the &lt;a href="http://java.dzone.com/articles/osgi-modularity"&gt;OSGi &amp;amp; Modularity post&lt;/a&gt;. But first, a little primer on &lt;a href="http://www.springframework.org/osgi"&gt;Spring Dynamic Modules&lt;/a&gt;. Spring DM is not an OSGi implementation. Instead, Spring DM aims to make working with OSGi easier just as Spring makes the world of Enterprise Java simpler. One of the more striking characteristics of Spring DM is that it removes most your code&amp;#8217;s dependencies on OSGi by taking care of the OSGi plumbing. To function in an OSGi runtime environment, the Spring .jars have been packaged as OSGi bundles.&lt;/p&gt;  &lt;p&gt;The easiest way to show this is by expanding on the HelloWorldSpec sample from &lt;a href="http://java.dzone.com/articles/osgi-modularity"&gt;my previous post&lt;/a&gt;. Reviewing the &lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpec/client/src/com/extensiblejava/hello/client/HelloConsumer.java"&gt;HelloConsumer &lt;/a&gt;and &lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpec/service/src/com/extensiblejava/hello/service/impl/HelloServiceImpl.java"&gt;HelloServiceImpl &lt;/a&gt;classes reveal that each are rather tightly coupled to the OSGi API. As we&amp;#8217;ll soon see, using Spring removes those dependencies, making the Spring edition of &lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpecSpring/client/src/com/extensiblejava/hello/client/HelloConsumer.java"&gt;HelloConsumer &lt;/a&gt;and &lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpecSpring/service/src/com/extensiblejava/hello/service/impl/HelloServiceImpl.java"&gt;HelloServiceImpl &lt;/a&gt;simple POJOs. Of course, the dependency on OSGi has to live somewhere, and for those familiar with Spring, we know it lives in the Spring configuration files.&lt;/p&gt;  &lt;p&gt;The Spring DM configuration files live in a META-INF/Spring directory, which you can see in &lt;a href="http://code.google.com/p/kcode/source/browse"&gt;my Google Code Repository&lt;/a&gt; for the HelloWorldSpecSpring project. There are two files, and each are described below:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpecSpring/service/META-INF/spring/helloservice.xml"&gt;helloservice.xml&lt;/a&gt; - Defines the helloService bean. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpecSpring/service/META-INF/spring/helloservice-osgi.xml"&gt;helloservice-osgi.xml&lt;/a&gt; - Exports the helloService bean as an OSGi service. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It isn&amp;#8217;t necessary to separate the configuration into two separate files. However, experienced Spring users typically separate configuration elements to making management and testing easier. In this case, the two configuration files allows me to test the helloService bean outside of the OSGi runtime.&lt;/p&gt;  &lt;p&gt;Since Spring is now managing the service within the Felix runtime, I have to install the necessary Spring bundles to Felix. As with the other examples, I&amp;#8217;ve done this for you within the HelloWorldSpecSpring project. Of course, when starting Felix, you can always create a new profile by entering a different profile name and install the bundles yourself. The bundles within the SpringLib directory are those I found were required to ensure the Spring DM modules resolvd correctly. If you do choose to create your own profile, it&amp;#8217;s likely you&amp;#8217;ll have to modify the &lt;a href="http://code.google.com/p/kcode/source/browse/trunk/osgi/HelloWorldSpecSpring/config.properties"&gt;&lt;strong&gt;config.properties&lt;/strong&gt;&lt;/a&gt; file to point to the location of your Felix runtime, which means you&amp;#8217;ll have to download Felix to get these bundles since I only include the Felix runtime in the HelloWorldSpecSpring distribution, not the bundles. You won&amp;#8217;t have to do this if you use the HelloWorldSpecSpring profile because the bundles have already been installed.&lt;/p&gt;  &lt;p&gt;After installing the client.jar and service.jar, I should be able to perform the execute same start, stop, and install sequence described in my earlier post on OSGi &amp;amp; Modularity, and receive the exact same results. Except this time, Spring is managing the dependencies on the OSGi API and my classes remain simple POJOs. Spring&amp;#8217;s simple elegance helping yield a higher quality design with fewer dependencies on the OSGi API.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;by Kirk Knoernschild&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-1864907158363895807?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5S2Gsof1uktJ9Ge3_7RZwRgTCZU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5S2Gsof1uktJ9Ge3_7RZwRgTCZU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5S2Gsof1uktJ9Ge3_7RZwRgTCZU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5S2Gsof1uktJ9Ge3_7RZwRgTCZU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/4rF796-ejfw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/1864907158363895807/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=1864907158363895807" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/1864907158363895807?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/1864907158363895807?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/4rF796-ejfw/osgi-and-spring.html" title="OSGi and Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/osgi-and-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EBQXYycCp7ImA9WxdTFE0.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-7575183768419750889</id><published>2008-05-10T10:54:00.001+02:00</published><updated>2008-05-10T10:54:10.898+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-10T10:54:10.898+02:00</app:edited><title>Presenting the version number on a web front end with spring and maven</title><content type="html">&lt;p&gt;This entry will describe how to present a application version number in the pom.xml on a web front end by using spring and maven. Maven generates by default a pom.properties file in the META-INF folder when generating a war. This file holds the following fields; version, groupId, artifactId    &lt;br /&gt;The exact location from your context root is;&lt;/p&gt;  &lt;blockquote&gt;META-INF/maven/&amp;lt;groupId&amp;gt;/&amp;lt;artifactId&amp;gt;/pom.properties&lt;/blockquote&gt;  &lt;br /&gt;by specifying the following bean in your spring config; (REPLACE &amp;lt;groupId&amp;gt; and &amp;lt;artifactId&amp;gt; with what you have defined in your pom.xml)   &lt;blockquote&gt;&amp;lt;bean id=&amp;quot;messageSource&amp;quot; class=&amp;quot;org.springframework.context.support.ReloadableResourceBundleMessageSource&amp;quot;&amp;gt;    &lt;br /&gt;&amp;lt;property name=&amp;quot;basenames&amp;quot;&amp;gt;     &lt;br /&gt;&amp;lt;list&amp;gt;     &lt;br /&gt;&amp;lt;value&amp;gt;META-INF/maven/&amp;lt;groupId&amp;gt;/&amp;lt;artifactId&amp;gt;/pom&amp;lt;/value&amp;gt;     &lt;br /&gt;&amp;lt;/list&amp;gt;     &lt;br /&gt;&amp;lt;/property&amp;gt;     &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/blockquote&gt;  &lt;br /&gt;Now the properties in this file can be used in your font-end by using   &lt;br /&gt;the standard spring tags for example to print the version number in a   &lt;br /&gt;jsp file use the following line;   &lt;blockquote&gt;&amp;lt;b&amp;gt;Version:&amp;lt;/b&amp;gt; &amp;lt;spring:message code=&amp;quot;version&amp;quot;/&amp;gt;&lt;/blockquote&gt;  &lt;br /&gt;REMARK don't forget to add the spring tag definition to your jsp file;   &lt;blockquote&gt;&amp;lt;%@ taglib prefix=&amp;quot;spring&amp;quot; uri=&amp;quot;http://www.springframework.org/tags&amp;quot; %&amp;gt; &lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-7575183768419750889?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hmZM8SePzZb4-QC1VybN53HDn8U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hmZM8SePzZb4-QC1VybN53HDn8U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hmZM8SePzZb4-QC1VybN53HDn8U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hmZM8SePzZb4-QC1VybN53HDn8U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/lbWgCFZnYF4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/7575183768419750889/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=7575183768419750889" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/7575183768419750889?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/7575183768419750889?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/lbWgCFZnYF4/presenting-version-number-on-web-front.html" title="Presenting the version number on a web front end with spring and maven" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/presenting-version-number-on-web-front.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4HRn04fCp7ImA9WxdTEkg.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-3142743194879185615</id><published>2008-05-08T15:22:00.001+02:00</published><updated>2008-05-08T15:22:17.334+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-08T15:22:17.334+02:00</app:edited><title>Pragmatic Caching - a simple Cache Configuration Model for Spring</title><content type="html">&lt;p&gt;Caching is a widely used instrument when it comes to performance tuning a given application (of course not until you&amp;#8217;ve measured the real bottlenecks). For example, you may want to cache objects that are expensive to fetch (i.e. an object graph from database) or to calculate. Whereas most of us have used a kind of Map to &amp;#8216;cache&amp;#8217; some data on ad hoc basis in the past, there are a couple of mature caching solutions at the market in the meantime that offer sophisticated features for caching, which goes beyond simply holding objects in memory (e.g. Thread pool controls, Element grouping, Remote server chaining (or clustering), failover, &amp;#8230;) Deciding to use such a cache solution always comes with the question of the resulting complexity impact when applying &amp;#8216;cache logic&amp;#8217; to your application.&lt;/p&gt;  &lt;h4&gt;Caching is an Aspect&lt;/h4&gt;  &lt;p&gt;One could rightly say, that caching is a cross cutting concern, that shouldn&amp;#8217;t be intermingled with the rest of your business or application logic. Especially the Spring framework provides different options to cope with cross cutting concerns. &lt;a href="https://springmodules.dev.java.net/"&gt;Spring Modules&lt;/a&gt; - a sub project of the Spring framework - offers Support for declarative caching that uses Springs AOP capabilities. It provides a generic &amp;#8216;API&amp;#8217; while supporting a bunch of different cache solutions (e.g. EHCache, JCS, OSCache, GigaSpaces, &amp;#8230;) under the hood.&lt;/p&gt;  &lt;h4&gt;Pragmatic Caching&lt;/h4&gt;  &lt;p&gt;While its very easy to declare caching models (resp. flushing models) in a declarative (and more abstract) style with Spring Modules Caching, you sometimes may want to do it in a more programatic way due to some specific caching behaviour that&amp;#8217;s difficult to reflect by using generic, declarative expressions. For example you may want to build a more complex cache key or decide which object to cache due to runtime conditions. In this case it may be better (and simpler) to handle caching in a more programmatic way, still treating caching as a cross cutting concern. The following solution is by far not comparable with Spring Modules Caching, yet provides a slightly different model for declaring and using a Cache. Only the core configuration and instantiation of the Cache will be managed by Spring. Caching and Flushing can be managed programmatically, giving you the full power of expressing &amp;#8216;caching logic&amp;#8217; by the underlying language.&lt;/p&gt;  &lt;h4&gt;Pragmatic Desicions&lt;/h4&gt;  &lt;p&gt;We will use only a particular Cache solution - for example the &lt;em&gt;&lt;a href="http://jakarta.apache.org/jcs/"&gt;Java Caching System&lt;/a&gt;&lt;/em&gt; (JCS), so we don&amp;#8217;t have to cope with a variety of different Cache APIs. While Spring Modules Caching have to provide a more abstract API which is able to handle different Cache solutions, focussing on a specific solution allows us to manage cache configuration with far less code (We could of course come up with a similar abstraction of caches which allows us to write Adapters for different Cache solutions - but that&amp;#8217;s not in the focus of this post).&lt;/p&gt;  &lt;h4&gt;Programmatic Interception&lt;/h4&gt;  &lt;p&gt;The basic concept of AOP (remember - caching is an Aspect) is method interception. In our case we want to intercept calls to service methods that provide expensive to fetch or expensive to calculate objects (and thus separating business or application logic from caching logic).    &lt;br /&gt;Interception is done in order to deliver objects that were cached due to prior calls (once delegated to the intercepted service).&lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s imagine a CustomerDAO interface, which is implemented by    &lt;br /&gt;HibernateCustomerDAO. In order to intercept arbitrary calls to HibernateCustomerDAO, we&amp;#8217;ll define CustomerDAOCacheInterceptor for which we&amp;#8217;ll provide a readily configured Cache instance:&lt;/p&gt;  &lt;p&gt;public class CustomerDAOCacheInterceptor implements CustomerDAO{   &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private static final String CACHE_GROUP_VIP = &amp;quot;VIP&amp;quot;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private JCS customerCache = null;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private CustomerDAO target = null;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void setTarget( CustomerDAO target ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.target = target;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void setCustomerCache( JCS cache ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.customerCache = cache;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public Customer loadCustomerByLogin( String loginId ) {    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String cacheKey = calculateCacheKey( loginId );    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String cacheGroup = getCacheGroup( loginId );    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Customer customer = (Customer)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; customerCache.getFromGroup( cacheKey, cacheGroup );    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if( customer == null ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; customer = target.loadCustomerByLogin( loginId );    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if( customer != null ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; customerCache.putInGroup( cacheKey, cacheGroup, customer );    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; catch ( CacheException e ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new RuntimeException(    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;exception while trying to store Customer to cache (JCS)&amp;quot;, e );    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return customer;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void update( Customer customer ) {    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; target.update( Customer );    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if( someCondtionsMetOn( customer ) ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; invalidateGroup( CACHE_GROUP_VIP );    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; catch ( CacheException e ){    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new RuntimeException( &amp;quot;exception while invalidating VIP cache (JCS)&amp;quot;, e );    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;As you&amp;#8217;ve seen, the Interceptor is provided with a target - the CustomerDAO implementation which is asked for a Customer in case the affected Customer isn&amp;#8217;t cached yet (normally our HibernateCustomerDAO).    &lt;br /&gt;Further on, a readily configured JCS Cache instance is injected (as said before, we could easily come up a cache abstraction by shielding the Intercepor from the concrete cache instance with an appropriate cache interface), so the Interceptor doesn&amp;#8217;t have to cope with Cache configuration and cache creation itself (maybe there are other DAOs that will use the same cache instance, so we have to come up with a central cache configuration and instantiation mechanism anyway).&lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s say that the cache key is calculated by a more or less complex logic, that&amp;#8217;s better described within Java. Same goes for using cache groups within the &amp;#8216;customer cache&amp;#8217;. Handling different cache groups and detecting the right cache group for a certain customer may be better placed inside the Interceptor using the full power of the language (again, the same might be true for determining conditions under which the cache or a certain cache group have to be flushed as shown in method &lt;em&gt;update()&lt;/em&gt; ).     &lt;br /&gt;Note, that the demonstration doesn&amp;#8217;t include logic to handle concurrent access - this &amp;#8216;exercise&amp;#8217; is left to you since we only want to take a look at the caching logic.&lt;/p&gt;  &lt;h4&gt;Basic cache configuration&lt;/h4&gt;  &lt;p&gt;JCS (like most of the other cache solutions) provides a way to configure caches by using a cache configuration file (*.ccf). In it, we&amp;#8217;ll describe the different caches which are supposed to be used within our application (for further information, please refer to the documentation):&lt;/p&gt;  &lt;pre&gt;# DEFAULT CACHE REGION
jcs.default=DC
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=100
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

# PRE-DEFINED CACHE REGIONS
jcs.region.customerCache=DC
jcs.region.customerCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.customerCache.cacheattributes.MaxObjects=200
jcs.region.customerCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.customerCache.elementattributes.MaxLifeSeconds=2400

jcs.region.priceCache=DC
jcs.region.priceCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.priceCache.cacheattributes.MaxObjects=100
jcs.region.priceCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.priceCache.elementattributes.MaxLifeSeconds=1200&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ve defined a default configuration and a cache coniguration for our customer cache. We could of course could have defined some more cache regions in order to cache other objects or object categories within our application (e.g. a particular region for caching Articles or calculated Prices). 
  &lt;br /&gt;That&amp;#8217;s all we need to start. The last question (and most interesting for this post) is who&amp;#8217;s responsible for instantiating and managing the different &amp;#8216;caches&amp;#8217; (resp. cache regions)?&lt;/p&gt;

&lt;h4&gt;Say it with a FactoryBean&lt;/h4&gt;

&lt;p&gt;Within an application context, all we want to do is pointing to the underlying cache configuration file and choose a particular cache region (defined within the cache configuration file) by its name to bring the different cache instances to life. 
  &lt;br /&gt;This is easily done by leveraging a FactoryBean, which is responsible for the creation and management of our caches. By Injecting the path and name of the cache configuration file and the name of the cache region the FactoryBean should deliver the corresponding cache instance.&lt;/p&gt;

&lt;pre&gt;package org.common.cache;

import java.util.HashMap;
import java.util.Map;

import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import org.springframework.beans.factory.FactoryBean;

public class JCSCacheFactoryBean implements FactoryBean {

    private Map&amp;lt;String,JCS&amp;gt; caches = new HashMap&amp;lt;String,JCS&amp;gt;();

    private String configLocation = null;
    private String region = null;

    public void setConfigLocation(String configLocation) {
        this.configLocation = configLocation;
    }

    public void setRegion(String region) {
        this.region = region;
    }    

    public Object getObject() throws Exception {
        try{
            String cacheRegionKey =
                new StringBuffer( configLocation )
                    .append( &amp;quot;.&amp;quot; ).append( &amp;quot;region&amp;quot; ).toString();

            JCS cache = null;

            if( caches.containsKey( cacheRegionKey ) ){
                cache = caches.get( cacheRegionKey );
            }
            else{
                JCS.setConfigFilename( configLocation );
                cache = JCS.getInstance( region );
                caches.put( cacheRegionKey, cache );
            }

            return cache;
        }
        catch ( CacheException e ){
            throw new RuntimeException( &amp;quot;exception while initializing cache (JCS)&amp;quot;, e );
        }
    }

    public Class getObjectType() {
        return JCS.class;
    }

    public boolean isSingleton() {
        return true;
    }
}&lt;/pre&gt;

&lt;p&gt;As you&amp;#8217;ve seen, the implementation is very straightforward. Every time a cache instance is requested, the FactoryBean will look for an appropriate cache which is already created and in memory or is creating a new instance according to the current property values &lt;em&gt;configLocation &lt;/em&gt;and &lt;em&gt;region&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;A cache bean&lt;/h4&gt;

&lt;p&gt;With the given FactoryBean, it&amp;#8217;s easy to define a &amp;#8216;cache bean&amp;#8217; simply by providing the cache configuration file and the name of a defined cache region. 
  &lt;br /&gt;Now you can wire up dependend beans (e.g. CustomerDAOInterceptor) simply by injecting the cache bean.&lt;/p&gt;

&lt;pre&gt;    &amp;lt;bean id=&amp;quot;customerDAO&amp;quot; class=&amp;quot;org.sample.intercept.&amp;lt;span&amp;gt;&amp;lt;span&amp;gt;CustomerDAOCacheInterceptor&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;&amp;gt;
        &amp;lt;property name=&amp;quot;target&amp;quot;&amp;gt;
            &amp;lt;bean class=&amp;quot;org.sample.CustomerDAO&amp;quot;&amp;gt;
                &amp;lt;property name=&amp;quot;sessionFactory&amp;quot;&amp;gt;&amp;lt;ref local=&amp;quot;hibernateSessionFactory&amp;quot;/&amp;gt;&amp;lt;/property&amp;gt;
            &amp;lt;/bean&amp;gt;
        &amp;lt;/property&amp;gt;
        &amp;lt;property name=&amp;quot;customerCache&amp;quot;&amp;gt;&amp;lt;ref bean=&amp;quot;customerCache&amp;quot;/&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;/bean&amp;gt;

    &amp;lt;bean id=&amp;quot;customerCache&amp;quot; class=&amp;quot;org.sample.cache.JCSCacheFactoryBean&amp;quot;&amp;gt;
        &amp;lt;property name=&amp;quot;configLocation&amp;quot;&amp;gt;&amp;lt;value&amp;gt;/cache.ccf&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;
        &amp;lt;property name=&amp;quot;region&amp;quot;&amp;gt;&amp;lt;value&amp;gt;customerCache&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;/bean&amp;gt;

    &amp;lt;bean id=&amp;quot;priceCache&amp;quot; class=&amp;quot;org.sample.cache.JCSCacheFactoryBean&amp;quot;&amp;gt;
        &amp;lt;property name=&amp;quot;configLocation&amp;quot;&amp;gt;&amp;lt;value&amp;gt;/cache.ccf&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;
        &amp;lt;property name=&amp;quot;region&amp;quot;&amp;gt;&amp;lt;value&amp;gt;priceCache&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;/bean&amp;gt;
    ....&lt;/pre&gt;

&lt;p&gt;It&amp;#8217;s of course possible to wire up more than one bean with a needed cache bean just as well as you can define arbitrary cache beans which represent different cache regions.&lt;/p&gt;

&lt;h4&gt;Summary&lt;/h4&gt;

&lt;p&gt;We&amp;#8217;ve come up with a very pragmatic solution with a declarative style for cache configuration and a more programmatic style for handling caching behaviour. As always, the usefulness of such a solution depends on the given problem space and the surrounding forces. 
  &lt;br /&gt;While Spring Modules Caching allows for a more generic style for all aspects of cache confiuration and cache processing (with less code to write!) the given solution is only half-declarative (only for the configuration part) providing more power in expressing the cache processing part.&lt;/p&gt;

&lt;p&gt;As always, its a kind of trade off - you&amp;#8217;ll have to choose the right tool for the right situation &amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;by Mario Gleichmann&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-3142743194879185615?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ag68Gwv9YdDH5YwzhIf7Y1Og_9A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ag68Gwv9YdDH5YwzhIf7Y1Og_9A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ag68Gwv9YdDH5YwzhIf7Y1Og_9A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ag68Gwv9YdDH5YwzhIf7Y1Og_9A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/2d5ZwS2b1RA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/3142743194879185615/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=3142743194879185615" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3142743194879185615?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/3142743194879185615?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/2d5ZwS2b1RA/pragmatic-caching-simple-cache.html" title="Pragmatic Caching - a simple Cache Configuration Model for Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/05/pragmatic-caching-simple-cache.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUADQn47eip7ImA9WxZWE0s.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-8035013615975718759</id><published>2008-03-13T00:17:00.000+01:00</published><updated>2008-03-13T00:16:13.002+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-13T00:16:13.002+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="tips" /><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="log4j" /><title>A better configuration with Spring MVC</title><content type="html">&lt;p&gt;Configuration management&amp;#160; involve&amp;#160; many aspects&amp;#160; on&amp;#160; how the application has to spread in several environments for integration pourpose, QA testing, pre-production, and final production.    &lt;br /&gt;Said elements&amp;#160; affect the configuration regarding information systems addresses as database, jndi and sockets and ldap.     &lt;br /&gt;Let me&amp;#160; talk about a java project, at a certain point it will be promoted to integration then test environment.     &lt;br /&gt;During these stages, problems and suggestions raise up, many enhancements are made and pushed along the delivery chain. As usual it would happen that these recycles increase sharply as the timeline is getting uncomfortably tight. Managing&amp;#160; these releases and synchronizing the environments with the incoming changes is a error prone and time consuming task.     &lt;br /&gt;Best pratices suggest &lt;a href="http://www.martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt; as the way to manage build artifacts and deliver the applications among different environments. An external tool as would be apache continuum and maven that can deploy, setup, start the application in a completely automatic way, freeing the developers to directly handle this task.     &lt;br /&gt;These tools start to work from the source repository which is the ultimate source traceability hub and may say the last word about the state of the project as regarding setups and branches.&lt;/p&gt;  &lt;p&gt;Our starting&amp;#160; point is always the central repository, so &lt;u&gt;how to track the setup&lt;/u&gt; configuration for different places where the webapp will be deployed?&lt;/p&gt;  &lt;p&gt;Suppose we are working on a Spring enabled web application, and you may take advantages&amp;#160; from the dynamic setting up of configuration files&amp;#160; path with the PropertyPlaceholderConfigurer which handle &lt;i&gt;${system-property}&lt;/i&gt; tags and they are filled by the Spring MVC layer.     &lt;br /&gt;You may create several sub folder for each config environment, for instance :&lt;/p&gt;  &lt;p&gt;&lt;i&gt;WEB-INF/local/applicationContext.xml      &lt;br /&gt;WEB-INF/local/log4j.properties       &lt;br /&gt;WEB-INF/test/applicationContext.xml       &lt;br /&gt;WEB-INF/test/log4j.properties&lt;/i&gt;     &lt;br /&gt;Now the application context setup is easy,&amp;#160; it simply tells Spring how to find the proper configuration files as the example:     &lt;br /&gt;&amp;lt;servlet&amp;gt;     &lt;br /&gt;&amp;lt;servlet-name&amp;gt;dispatch&amp;lt;/servlet-name&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;init-param&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;param-value&amp;gt;WEB-INF/${environment}/applicationContext.xml&amp;lt;/param-value&amp;gt;     &lt;br /&gt;&amp;#160; &amp;lt;/init-param&amp;gt;     &lt;br /&gt;&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;     &lt;br /&gt;&amp;lt;/servlet&amp;gt;     &lt;br /&gt;You may also specify in the same way the log4j enviroment-specific configuration:&lt;/p&gt;  &lt;p&gt;&amp;lt;context-param&amp;gt;    &lt;br /&gt;&amp;lt;param-name&amp;gt;log4jConfigLocation&amp;lt;/param-name&amp;gt;     &lt;br /&gt;&amp;lt;param-value&amp;gt;WEB-INF/${environment}/log4j.properties&amp;lt;/param-value&amp;gt;     &lt;br /&gt;&amp;lt;/context-param&amp;gt;     &lt;br /&gt;&amp;lt;listener&amp;gt;     &lt;br /&gt;&amp;lt;listener-class&amp;gt;org.springframework.web.util.Log4jConfigListener&amp;lt;/listener-class&amp;gt;     &lt;br /&gt;&amp;lt;/listener&amp;gt;     &lt;br /&gt;Afterwards, setup the system variable in your web container adding the &amp;quot;-Denvironment=[local,test]&amp;quot; in the JVM parameter. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-8035013615975718759?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HCpau4NCq-K1PnaLDuEBu-kOv-A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HCpau4NCq-K1PnaLDuEBu-kOv-A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HCpau4NCq-K1PnaLDuEBu-kOv-A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HCpau4NCq-K1PnaLDuEBu-kOv-A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/kzQtD6o_s1Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/8035013615975718759/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=8035013615975718759" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8035013615975718759?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8035013615975718759?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/kzQtD6o_s1Y/better-configuration-with-spring-mvc.html" title="A better configuration with Spring MVC" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/03/better-configuration-with-spring-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MCSX0_fip7ImA9WxZWEEQ.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-8109289414782440640</id><published>2008-03-09T21:45:00.000+01:00</published><updated>2008-03-09T21:44:28.346+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-09T21:44:28.346+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jmx" /><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><title>JMX Annotations in Spring</title><content type="html">&lt;p&gt;Wow. Over a month without writing anything to this blog. Seems that the days over christmas blocked a lot of time as well as other things that happened around that time. But now i am back with something to share. I really like the new JMX annotations Spring recognizes. In a new project i have to write a small server that should be managed via JMX and i really like springs way of handling it with annotations. In Principle its the same as the transaction annotation. You simple tell spring via:&lt;/p&gt;  &lt;pre&gt;&lt;em&gt;&lt;em&gt;&amp;lt;bean id=&amp;#8221;attributeSource&amp;#8221;

        class=&amp;#8221;org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource&amp;#8221;/&amp;gt;&lt;/em&gt;&lt;/em&gt;&lt;/pre&gt;

&lt;p&gt;and a few lines more spring config that you want to export all annotated beans as Mbeans.&lt;/p&gt;

&lt;p&gt;Its really interessting to see that more and more of the features around classes like webservices, transactions and now jmx are annotation based. This makes the code much more readable in my oppinion. When i have some more time, i will also convert to define the spring config itself via annotations, but that will be quite a lot of work.&lt;/p&gt;

&lt;p&gt;Apart from that, i will leaving for ski vacation in 2 days. Yipeee. I am really looking forward to be 4 days in Austria at the Zillertal valley. With one skipass you can ride more than 600 km trails. Check &lt;a href="http://www.zillertal.at/listedetail1.php?content=wintersport&amp;amp;id=2&amp;lang;=en"&gt;this&lt;/a&gt; if you want to see more. Boy, i like skiing.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-8109289414782440640?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kemQfjI_v4NPr7EdGuv8J8G7pq8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kemQfjI_v4NPr7EdGuv8J8G7pq8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kemQfjI_v4NPr7EdGuv8J8G7pq8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kemQfjI_v4NPr7EdGuv8J8G7pq8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/xRHURWTDoa4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/8109289414782440640/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=8109289414782440640" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8109289414782440640?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/8109289414782440640?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/xRHURWTDoa4/jmx-annotations-in-spring.html" title="JMX Annotations in Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/03/jmx-annotations-in-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQDQH04eCp7ImA9WxZXE0o.&quot;"><id>tag:blogger.com,1999:blog-1066920359387515642.post-726303555685699889</id><published>2008-03-01T13:10:00.000+01:00</published><updated>2008-03-01T13:09:31.330+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-01T13:09:31.330+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="remoting" /><category scheme="http://www.blogger.com/atom/ns#" term="webapp" /><title>What's new with DWR3 &amp; Spring</title><content type="html">&lt;p&gt;With &lt;a href="http://www.directwebremoting.com"&gt;DWR&lt;/a&gt; 3 around the corner (the first milestone is available right now) is time to have a look at the new features it brings to the table. In fact, it packs so many, that I'm going to talk just about those related to Spring.     &lt;br /&gt;As you know (or should :-), by now DWR has a nice integration with Spring and specially Spring MVC, thanks to the custom namespace it provides. Nonetheless the team has make an effort to improve it. And the results are astounding! Let's review the new features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Remoting beans from a parent (root) context&lt;/b&gt;       &lt;br /&gt;Until now, when using &amp;lt;dwr:controller&amp;gt; just the beans in the same context where proxied. From now on, the root context can define candidate beans as well. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;New defaults&lt;/b&gt;       &lt;br /&gt;DWR will offer default names for your controller and remoted beans. In the former case the bean will be called dwrController. In the later, the bean will be available in your client code with the same name as the bean, capitalized. So &lt;i&gt;&amp;lt;bean id=&amp;quot;sample&amp;quot; class=&amp;quot;...&amp;quot;&amp;gt;&lt;/i&gt; will be remoted as Sample.js &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Explicitly setting an application context&lt;/b&gt;       &lt;br /&gt;As of now, the default web application context was always used. The new version allows a developer to set a specific application context in the DWR Spring servlet. DWR will scan this context looking for candidate beans. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Namespace support improved&lt;/b&gt;       &lt;br /&gt;Release 3 will add the &amp;lt;dwr:url-mapping /&amp;gt; tag. If declared in your XML (along with a &amp;lt;dwr:controller /&amp;gt;) all the needed mappings will be automatically created and handled. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Configure everything using annotations&lt;/b&gt;       &lt;br /&gt;Spring beans annotated with @RemoteProxy and @RemoteMethod will be automatically proxied and available in the browser. To activate this feature a new &amp;lt;dwr:annotation-config /&amp;gt; tag has been developed. Just one caveat, this kind of configuration does not work for advised / scoped proxies for the time being. You have to revert to the common &amp;amp;ltdwr:remote /&amp;gt; and &amp;lt;aop:scoped-proxy /&amp;gt; in that case. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Classpath scanning&lt;/b&gt;       &lt;br /&gt;DWR will scan the classpath looking for classes annotated with @RemoteProxy and create the bean definitions directly (so you can ommit the @Component annotation). A new &amp;lt;dwr:component-scan/&amp;gt; tag has been created for it. A side note here, the code is not yet available (it's not in the milestone) because it requires Spring 2.5.2+ which has not been publicly released yet. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Several other minor changes and bug fixes&lt;/b&gt;       &lt;br /&gt;A lot of work behind the scenes. For example, a bean name can now be preceded by a slash so it's automatically mapped. &lt;/li&gt; &lt;/ul&gt; All in all, a lot of good work. And the best of all, it's just the beginning! Other areas, like file handling or reverse AJAX, pack even more interesting features. I can only recommend that you &lt;a href="https://dwr.dev.java.net/servlets/ProjectDocumentList?folderID=8738"&gt;give it a try&lt;/a&gt; today.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1066920359387515642-726303555685699889?l=springtips.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nOEZZX5UCmeib1EN4yVMD29IDiU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nOEZZX5UCmeib1EN4yVMD29IDiU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nOEZZX5UCmeib1EN4yVMD29IDiU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nOEZZX5UCmeib1EN4yVMD29IDiU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpringTips/~4/osVOh8d3ZBA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://springtips.blogspot.com/feeds/726303555685699889/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1066920359387515642&amp;postID=726303555685699889" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/726303555685699889?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1066920359387515642/posts/default/726303555685699889?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SpringTips/~3/osVOh8d3ZBA/what-new-with-dwr3-spring.html" title="What&amp;#39;s new with DWR3 &amp;amp; Spring" /><author><name>Cloogy</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://springtips.blogspot.com/2008/03/what-new-with-dwr3-spring.html</feedburner:origLink></entry></feed>

