<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tales From The Cloud &#187; JEE</title>
	<atom:link href="http://blog.newsplore.com/tag/jee/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.newsplore.com</link>
	<description>Everything beta</description>
	<lastBuildDate>Sun, 05 Feb 2012 09:03:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Upgrading to Spring 3.0.0.M3 and Spring Security 3.0.0.M1</title>
		<link>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1</link>
		<comments>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1#comments</comments>
		<pubDate>Fri, 05 Jun 2009 02:50:31 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Spring Security]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1224</guid>
		<description><![CDATA[A short two months back I posted an article describing how to upgrade to Spring 3.0 M2. Spring folks are releasing at breakneck speed and so I got busy again upgrading spincloud.com to Spring 3.0 M3 released at the beginning of May. Just yesterday (June 3rd) the team released Spring Security 3.0 M1 and I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F04%2Fupgrading-to-spring-300m3-and-spring-security-300m1"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F06%2F04%2Fupgrading-to-spring-300m3-and-spring-security-300m1" height="61" width="51" /></a></div><p>A short two months back I <a href='http://blog.newsplore.com/?p=773'>posted</a> an article describing how to upgrade to Spring 3.0 M2. Spring folks are releasing at breakneck speed and so I got busy again upgrading <a href='http://spincloud.com'>spincloud.com</a> to <a href='http://blog.springsource.com/2009/05/06/spring-framework-30-m3-released/'>Spring 3.0 M3</a> released at the beginning of May. Just yesterday (June 3rd) the team <a href='http://blog.springsource.com/2009/05/06/spring-framework-30-m3-released/'>released</a> Spring Security 3.0 M1 and I decided to roll this in Spincloud as well.</p>
<p><b>Upgrading Spring Security from 2.0.4 to 3.0.0 M1</b><br />
For Spring Security 3.0.0 M1 I&#8217;m doing a &#8220;soft&#8221; upgrade since I had done my homework when I migrated from Acegi. I won&#8217;t use any of the new 3.0 features, just getting ready to use them. </p>
<p>To digress a bit, Spring Security a technology that is harder to swallow due to its breadth. To simplify the picture, Spring Security (former Acegi) provides three major security concerns to enterprise applications:<br />
- Authorization of method execution (either through standard JSR-250 JEE security annotations or via specific <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-method-security'>annotation-based method security</a>).<br />
- HTTP Request authorization (mapping URLs to accessible roles using Ant style or regexp&#8217;ed paths,  dubbed <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/channel-security.html#channel-security-config'>channel security</a>).<br />
- Website authentication (integrating Single Sign On (SSO) services by supporting major SSO providers, HTTP BASIC authentication, OpenId authentication and other types).<br />
For Spincloud I&#8217;m using OpenId for authentication and Channel Security to secure website pages.<br />
<span id="more-1224"></span><br />
To perform the upgrade you have to first grab the new jars. Here&#8217;s the Maven config:</p>
<pre>
	&lt;repository&gt;
		&lt;id&gt;Springframework milestone&lt;/id&gt;
		&lt;url&gt;http://maven.springframework.org/milestone&lt;/url&gt;
	&lt;/repository&gt;
	&lt;properties&gt;
		&lt;spring.version&gt;3.0.0.M3&lt;/spring.version&gt;
		&lt;spring-security.version&gt;3.0.0.M1&lt;/spring-security.version&gt;
	&lt;/properties&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-core&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-config&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-openid&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-web&lt;/artifactId&gt;
			&lt;version&gt;${spring-security.version}&lt;/version&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
</pre>
<p>Make sure your build process refers only to these jars.<br />
in 3.0.0 M1, the package structure was changed. Here&#8217;s what I had to do to upgrade the packages:<br />
Before</p>
<pre>
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.openid.OpenIDAuthenticationStatus;
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
</pre>
<p>After:</p>
<pre>
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.openid.OpenIDAuthenticationStatus;
import org.springframework.security.openid.OpenIDAuthenticationToken;
</pre>
<p>The security namespace has <a href='http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html'>changed</a> too so I updated my security XML file namespace and I had only to change the packages for standard Spring Security beans defined  to match the new package structure.</p>
<p><b>Upgrading Spring from 3.0.0 M2 to M3</b><br />
This should be easy. First, grab the new jars through Maven by using the same Maven config I described at the beginning of <a href='http://blog.newsplore.com/?p=773'>this post</a> and change the spring.version to 3.0.0.M3. I&#8217;m planning to move more XML configuration to annotations and M3 enables more of that (@Lazy for instance). I&#8217;m still waiting for the scheduling namespace due to appear in this milestone but pushed to RC1 apparently. I&#8217;m craving for some annotation-based timer configuration too&#8230;</p>
<p><b>Build and deployment</b><br />
At first, the build failed on me with the follwing error:</p>
<pre>
java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
	at org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:205)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:125)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:419)
</pre>
<p>This is because M3 (finally) repackages asm. So I deleted the asm libraries I used to fix the M2 issues and added the repackaged Spring asm library:</p>
<pre>
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;org.springframework.asm&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;
</pre>
<p>If you&#8217;re getting this error on container start-up:</p>
<pre>
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/security]
Offending resource: ServletContext resource [/WEB-INF/classes/applicationContext-security.xml]
</pre>
<p>means you have forgotten to add security-config jar (see the Maven config in the Security section). </p>
<p>That&#8217;s all. Done in 3 hours with no problems at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/06/04/upgrading-to-spring-300m3-and-spring-security-300m1/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Proposal to standardize the Level 2 query cache configuration in JPA 2.0</title>
		<link>http://blog.newsplore.com/2009/05/28/a-call-to-standardize-level-2-cache-configuration-in-jpa-20</link>
		<comments>http://blog.newsplore.com/2009/05/28/a-call-to-standardize-level-2-cache-configuration-in-jpa-20#comments</comments>
		<pubDate>Thu, 28 May 2009 21:41:54 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[opinions]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JPA 2.0]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=1174</guid>
		<description><![CDATA[Level 2 cache is one of the most powerful features of the JPA spec. It&#8217;s a transparent layer that manages out-of-session data access and cranks-up the performance of the data access tier. To my knowledge it has been first seen in Hibernate and was later adopted by the then-emerging JPA spec (driven mostly by the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F05%2F28%2Fa-call-to-standardize-level-2-cache-configuration-in-jpa-20"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F05%2F28%2Fa-call-to-standardize-level-2-cache-configuration-in-jpa-20" height="61" width="51" /></a></div><p>Level 2 cache is one of the most powerful features of the JPA spec. It&#8217;s a transparent layer that manages out-of-session data access and cranks-up the performance of the data access tier. To my knowledge it has been first seen in Hibernate and was later adopted by the then-emerging JPA spec (driven mostly by the Hibernate guys back in the day).<br />
As annotations gained strength and adoption, L2 caching that was initially configured through XML or properties files, was brought closer to the source code, alas in different forms and shapes. This becomes apparent if you ever have to deploy your webapp across a multitude of containers as you have to painfully recode the cache configuration (or worse, <a href="http://blog.newsplore.com/?p=981">hand-coded cache access</a>). Why not standardizing the cache control in JPA? This seems to be simple enough to achieve and yet it isn&#8217;t there. Now that JPA 2.0 is standardizing on Level 2 cache access (See JSR 317 section 6.10) it is the natural thing to do.<br />
Every JPA provider has its own way of specifying cache access (both Entity and query cache).<br />
To grasp the extent of the various ways cache is configured, here are some examples:</p>
<p><b>Hibernate:</b><br />
Cache control for entities</p>
<pre>@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Employee {...</pre>
<p>Cache control for named queries:</p>
<pre>@javax.persistence.NamedQuery(name="findEmployeesInDept",
query="select emp from Employee emp where emp.department = ?1",
hints={@QueryHint(name="org.hibernate.cacheable",value="true")})

or

@org.hibernate.annotations.NamedQuery(cacheable=true, cacheRegion="employeeRegion")</pre>
<p><b>OpenJPA</b><br />
Cache control for entities</p>
<pre>@Entity
@org.apache.openjpa.persistence.DataCache(timeout=10000)
public class Employee {...</pre>
<p><a href="http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/ref_guide_caching.html#ref_guide_cache_query">Query cache</a> requires hand coded cache access:</p>
<pre>OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
QueryResultCache qcache = oemf.getQueryResultCache();</pre>
<p><span id="more-1174"></span><b>EclipseLink</b><br />
Cache control <a href="http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#How_to_Use_the_.40Cache_Annotation">for entities</a></p>
<pre>@Entity
@org.eclipse.persistence.annotations.Cache(expiry=10000,
    type=org.eclipse.persistence.annotations.CacheType.FULL)
public class Employee {...</pre>
<p>Query cache is hand coded (example from <a href="http://wiki.eclipse.org/Using_Advanced_Query_API_(ELUG)#Using_Queries_and_the_Cache">here</a>):</p>
<pre>ReadObjectQuery query = new ReadObjectQuery(Employee.class);

// Instruct the ReadQuery to cache its query results
query.cacheQueryResults();

// The first time you invoke it, the ReadQuery reads from the database, session
// cache, or both and stores the result set in its internal query cache
Employee employeeFirst = (Employee) session.executeQuery(query);</pre>
<p>Another JPA provider, <b>DataNucleus </b>is used by Google AppEngine for Java and they have thir own way of defining the cache access.<br />
Entity cache control in DataNucleus:</p>
<pre>@javax.jdo.annotations.Extension(vendorName="datanucleus", key="cacheable", value="false")
@Entity
public class Employee {...</pre>
<p>Query caching is again <a href="http://www.datanucleus.org/products/accessplatform/rdbms/query.html">manual</a>:</p>
<pre>query.setHint("datanucleus.query.resultCacheType", "weak");</pre>
<p>Looking at the above examples it looks to me that caching was an afterthought for most of the JPA providers. Let&#8217;s remember that the cache should be transparent and pluggable and the value that a cache provider delivers stays in performance and not in configuration.<br />
JPA cache configuration is in need of standardization and in my opinion the closest to a standard is (again) Hibernate.</p>
<p>A great addition to the JPA2 spec is the introduction of @Cacheable that controls entity caching but there&#8217;s still no standard on how to control query caching.<br />
Here are some enhancements that I&#8217;m proposing:</p>
<p>1. An enhancement to @NamedQuery and @NamedNativeQuery to allow explicit cache enablement through a boolean attribute called cacheable, the same way @org.hibernate.annotations.NamedQuery is defined.</p>
<pre>@NamedQuery(name="findEmployeesInDept", query="...", <span style="color: red;">cacheable=true</span>)
...
@Entity
public class Employee {...</pre>
<p>2. Both @javax.persistence.Cacheable and @NamedQuery to support optional attributes: <em>timeout</em> (in sec.)  and a <em>cacheRegion</em> attribute that in turn, will point to a cache policy where a more complex configuration can be used (to add the cache concurrency strategy and eviction policy for instance).</p>
<pre>@NamedQuery(name="findEmployeesInDepartment", query="...",
   <span style="color: red;">cacheRegion="DepartmentEmployeesCacheRegion"</span>)
@Entity
@javax.persistence.Cacheable(<span style="color: red;">cacheRegion="EmployeeCacheRegion"</span>)
public class Employee {...</pre>
<p>Cache regions can be configured through a new annotation, @java.persistence.annotation.CacheRegion.</p>
<pre>
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Cacheable {
    boolean value() default true;
    <font color='red'>int timeout();
    String cacheRegion();  //takes precedence if used</font>
}

package java.persistence.annotation;
@Target({TYPE, PACKAGE}) @Retention(RUNTIME)
public @interface CacheRegion {
    int timeout();   //i.e. 300 s
    javax.cache.EvictionStrategy evictionStrategy(); //EvictionPolicy.LRU, FIFO, etc
    String name();  //region name
    ConcurrencyStrategy concurrencyStrategy();
    String hints();  //vendor extensions
}</pre>
<p>If specified, a @CacheRegion exists either in-place along with the entity definition or separately through a new annotation @java.persistence.annotation.CacheRegions:</p>
<pre>package java.persistence.annotation;
@Target({TYPE, PACKAGE}) @Retention(RUNTIME)
public @interface CacheRegions {
	CacheRegion[] value();
}

example:
@CacheRegions ({
  CacheRegion(name="EmployeeCacheRegion", timeout=300, evictionPolicy=
EvictionStrategy.LRU, ConcurrencyStrategy.TRANSACTIONAL),
  CacheRegion(name="OfficeLocationsCacheRegion", timeout=-1, evictionPolicy=
EvictionStrategy.LRU, ConcurrencyStrategy.READ_ONLY),
})
public class OrganizationStructureDAO {...</pre>
<p>4. Sensible and well-defined defaults if some of the values are nor specified: default timeout, default eviction policy and default concurrency.</p>
<p>Vendor extensions of cache configurations will still be able to be deployed through the <em>hints</em> attribute both for @NamedQuery and @CacheRegion.</p>
<p>In the end, configuring the cache should be executed the same way across containers given that the cache providers that will be used will likely be the same. At least that&#8217;s what I&#8217;m hoping to see in JPA 2.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/05/28/a-call-to-standardize-level-2-cache-configuration-in-jpa-20/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evaluating EclipseLink 1.1</title>
		<link>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11</link>
		<comments>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11#comments</comments>
		<pubDate>Sun, 22 Mar 2009 00:34:53 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[opinions]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=981</guid>
		<description><![CDATA[As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for Spincloud, I decided to try out another one. I had tried OpenJPA (spawned from Kodo JDO) when they only supported build-time bytecode enhancement and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11" height="61" width="51" /></a></div><p align='justify'>As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for <a href="http://spincloud.com">Spincloud</a>, I decided to try out another one. I had tried <a href="http://openjpa.apache.org/">OpenJPA</a> (spawned from Kodo JDO) when they only supported <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_build">build-time bytecode enhancement</a> and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s  now an <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_runtime">agent</a> to provide on-the-fly enhancement but I&#8217;ll take transparent enhancement anytime.<br />
I&#8217;ve heard about EclipseLink before. The project started when Oracle donated the respectable <a href="http://www.oracle.com/technology/tech/java/newsletter/articles/toplink/history_of_toplink.html">TopLink project</a> to the Eclipse foundation. If the solid reputation behind TopLink was a good enough argument for me to try it, the announcement that <a href="http://eclipselink.blogspot.com/2008/03/eclipselink-to-provide-jpa-20-reference.html">it will be the JPA 2.0 reference implementation</a> convinced me that I should try it out.<br />
My goal is to evaluate if EclipseLink is production-ready. I&#8217;m applying a complex set of evaluation criteria (joking): if it can run Spincloud then it is (I was inspired by Seifer&#8217;s <a href="http://www.infoq.com/presentations/seifer-ruby-vm-comparison">interview on Infoq</a> about Ruby VMs; when asked what was the criteria for qualifying if a Ruby VM is production ready, he answered: if it runs Rails).</p>
<p>I have the following JPA requirements:<br />
- column mappings, one-to-one, one-to-many<br />
- supports BLOB fields<br />
- supports NamedQueries and NamedNativeQueries<br />
- support for object cache and query cache<br />
- deployment/operational nice to have: ease of maintaining compatibility with both  EclipseLink and Hibernate in the source code and runtime. Ideally I should plug-in any JPA provider without changing a single line of code. This was not attainable as I&#8217;ll explain below.</p>
<p>I started by downloading the binaries</a>. I&#8217;m using Maven to bring the jars so I&#8217;ve followed the instructions <a href="http://wiki.eclipse.org/EclipseLink/Maven">here</a>. I only changed the version since I wanted to use v1.1.0:</p>
<pre>
  &lt;dependency&gt;
    &lt;groupId&gt;org.eclipse.persistence&lt;/groupId&gt;
    &lt;artifactId&gt;eclipselink&lt;/artifactId&gt;
    &lt;version&gt;1.1.0&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
</pre>
<p>There&#8217;s a single jar file called eclipselink-1.1.0.jar downloaded which is a nice change from the multitude of Hibernate jars I was accustomed with.<br />
<span id="more-981"></span><br />
Next, I created a new persistence.xml file since I didn&#8217;t know how different it would be from the one tied to Hibernate. Initially I just changed the JPA provider to:</p>
<pre>
  &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
</pre>
<p>as the documentation stated.<br />
Then I had a look at my current NamedQueries and NamedNativeQueries that looked like this:</p>
<pre>
@org.hibernate.annotations.NamedQueries({
	@org.hibernate.annotations.NamedQuery(name="findStationByPK",
	        query="select station from Station station where station.id=:stationPK"
	        , cacheable=true, cacheRegion="weatherStationsRegion"),
...
</pre>
<p>and I recalled that I did this in order to make use of Hibernate&#8217;s Query cache facility, alas a non-standard way of cache enablement (not until JPA 2.0 anyway). I had to put query caching to rest and switched all my Named*Queries to standard JPA:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station where id=:stationPK"),
...
</pre>
<p> I&#8217;m not using the integration unit tests I have due to the issues I had with the <a href="http://static.springframework.org/spring/docs/2.0.x/reference/testing.html#integration-testing">Spring integration test framework</a> I&#8217;m using after switching to Spring 3.0 so I&#8217;m using ad-hoc testing for now.  After rebuilding/deploying the project I didn&#8217;t notice any error on Tomcat start-up so I just tried the GUI, displaying the weather in a map area. I hit the first error:</p>
<pre>
Exception [EclipseLink-7060] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [java:comp/env/ds/MeteoDS].
Internal Exception: javax.naming.NamingException: This context must be accessed
throughout a java: URL
</pre>
<p>I dug through the documentation (what&#8217;s with this documentation and what does <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Limitations_to_JPA">&#8220;No dynamic weaving (instrumentation) &#8211; static weaving of entities is still available via EclipseLink&#8221;</a> means, why JPAEclipseLinkSessionCustomizer example is broken and finally why use teh deprecated SessionCustomizer?) and found that I have to use a <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Session_Customizer">session customizer</a> to make it work in Tomcat. I didn&#8217;t like this one bit (it just works in Hibernate) but I followed the instructions and EclipseLink could establish the connection with the Tomcat-configured data source as expected. This was the first duly noted turn-off.<br />
I redeployed and browsed the weather map just to hit another problem:</p>
<pre>
  Exception Description: Syntax error parsing the query [findStationByPK:
    select station from   Station where id=:stationPK], line 1, column 28:
    syntax error at [where].
 Internal Exception: MismatchedTokenException(65!=66)
</pre>
<p>Hmm, no compile-time JPA query check. Not good. I checked the JPA query, it was:</p>
<pre>
  @javax.persistence.NamedQuery(name="findStationByPK",
       query="select station from Station where id=:stationPK"),
...
</pre>
<p>which looked OK but looking closely I realized that it was not. The correct syntax is (notice the <b>station.</b> indirection:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station <b>station</b> where <b>station</b>.id=:stationPK"),
	@javax.persistence.NamedQuery(name="findByStationId",
...
</pre>
<p>Hibernate was happy with the &#8220;non-standard&#8221; syntax while EclipseLink is not. No big deal, it wasn&#8217;t in many places anyway. I scanned all my queries and fixed them. Redeployed and hit this:</p>
<pre>
  Exception Description: Syntax error parsing the query [findByStationId: from
    Station station where station.stationId=:stationId], line 1, column 0:
    unexpected token [from].
</pre>
<p>My JPA query is:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="from Station station where station.stationId=:stationId")
</pre>
<p>Again a Hibernate artifact. H3 supports the convenience of using queries that start with &#8220;from entity&#8230;&#8221; if they return entities (single or lists). The fix was simply to add &#8220;select station&#8221; in front of the JPA QL:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="<b>select station</b> from Station station where
                station.stationId=:stationId")
</pre>
<p>Not a biggie either, standard is better and Hibernate can parse this kind of query. Again, rebuilt/redeployed and queried the map again. This time the error was this:</p>
<pre>
[EL Warning]: 2009-03-21 19:02:42.135--UnitOfWork(2001070194)--Exception [EclipseLink-4002]
(Eclipse Persistence Services -
 1.1.0.r3639-SNAPSHOT): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for the right syntax to use
near ':area) , LOCATION) and obs_time
&gt; :minSynopDateToConsiderStr UNION select distin' at line 1
Error Code: 1064
Call: <b>select distinct STATION_FK as STATION_IDENTIFIER, LOCATION,
obs_time as REPORT_TIME  from SYNOP where Contains(GeomFromText(:area) , LOCATION) and
obs_time &gt; :minSynopDateToConsiderStr UNION
select distinct STATION_FK as STATION_IDENTIFIER,
LOCATION, REPORT_TIME as REPORT_TIME from METAR where
Contains(GeomFromText(:area) , LOCATION) and REPORT_TIME &gt; :minMetarDateToConsiderStr</b>
</pre>
<p>I couldn&#8217;t find anything at first in the documentation (getting really pissed at the documentation style, can&#8217;t find anything useful) but I finally found <a href="//wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_Named_Parameters_in_a_Native_Query">this</a>:</p>
<pre>
Support for the EclipseLink # convention is helpful if you are already familiar with
EclipseLink queries or if you are migrating EclipseLink queries to a JPA application.
</pre>
<p>I&#8217;m not &#8220;already familiar with EclipseLink queries&#8221; and no, it&#8217;s not helpful. So now I have to use #area instead of :area named parameter. This is really smart. Why in the world would one want to change the column with sharp? I&#8217;m starting to suspect clumsiness or plain careless coding. I still want to maintain Hibernate/EclipseLink pluggability so I have no choice but creating a static class that holds all NamedNativeQueries and parametrizes the named parameter prefix:</p>
<pre>
class NativeQueries {
public final static String WEATHER_SNAPSHOT_IN_AREA_NATIVE_QUERY ="select distinct
STATION_FK as STATION_IDENTIFIER, LOCATION, obs_time as REPORT_TIME from SYNOP where
Contains (GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
 ", LOCATION) and obs_time &gt; <font color="red">@named-param-prefix@</font>minSynopDateToConsiderStr UNION " +
"select distinct STATION_FK as STATION_IDENTIFIER, LOCATION, REPORT_TIME
as REPORT_TIME from METAR where Contains(GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
", LOCATION) and REPORT_TIME &gt; <font color="red">@named-param-prefix@</font>minMetarDateToConsiderStr";
...
}
</pre>
<p>Then I have to use ant to perform a pre-compilation task that replaces <font color="red">@named-param-prefix@</font> with either : or #. This really got the best of me as I&#8217;ve hit a Java compilation quirk too: you have to delete all classes that rely on the NativeQueries class since they will not recompile if the values of the <b>public static final String</b> values change; you have to delete all .class files and force a full compilation for them.<br />
After I did this build change it all started working. Victory at last. Or was it? Well, no; I still have to add query caching as I heavily use spatial queries to fetch area weather (activated every time the map is dragged/zoomed). There&#8217;s the <a href="http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_EclipseLink_JPA_Extensions_for_Entity_Caching">@Cache</a> but it&#8217;s for entity caching which is good but what I also need is query caching à la Hibernate: </p>
<pre>
 @org.hibernate.annotations.NamedQuery(name="qName", query="&lt;query&gt;",
    <font color="red">cacheable=true, cacheRegion="some-cache-region"</font>)
</pre>
<p align='justify'>
After another round of thorough search of the documentation I <a href="http://wiki.eclipse.org/Using_Advanced_Query_API_%28ELUG%29#Using_Queries_and_the_Cache">found what I needed</a> but it wasn&#8217;t what I expected. EclipseLink doesn&#8217;t support annotation-level query cache configuration. Instead you have to code-in (or use AOP to) cache writes after the queries are executed, via its ReadQuery class.<br />
Needless to say I didn&#8217;t do it. I gave up on it right there.<br />
On a whole this felt a lot like my (undocumented) evaluation I did over a year ago with OpenJPA (no dice too). Poor documentation (worse than EL&#8217;s) and lack of (then) runtime weaving made it a nightmare to deploy. I haven&#8217;t tried it ever since.</p>
<p>Prognosis: negative</p>
<p>This is really a shame, EclipseLink seems to be quite fast and has a footprint similar to Hibernate but:<br />
- the documentation is awful. Guys, look at Hibernate and follow their lead. I badly need a single page HTML up-to-date documentation that I can freely browse. I can find almost anything in a matter of seconds using Hibernate&#8217;s single page HTML doc and Ctrl-F. I feel so strongly about this, I&#8217;d make an addition to the <a href="http://manifesto.softwarecraftsmanship.org/">Software Craftsmanship Manifesto:</a> <b>&#8220;Maintain top-notch documentation&#8221;</b>. Spring and Hibernate projects got it right and this is one of the secrets of their success. Take note.<br />
- Use : (column) for named parameters in NamedNativeQuery; it is consistent with NamedQuery syntax (and hopefully standardized in JPA 2.0).<br />
- Use compile-time Named*Query syntax check. It adds a great deal to predictability.<br />
- Add the Session Customizer fix into of the base platform and make it transparent to the user. Nobody wants to write integration code to fix oddities of popular containers. &#8220;Out of the box&#8221; is valuable.<br />
- Work on a better query caching support or push hard for a JPA 2.0 beta since there&#8217;s standardized second-level caching.</p>
<p>Oh and guys, <a href="http://wiki.eclipse.org/Introduction_to_EclipseLink_Queries_(ELUG)">some</a> documentation pages don&#8217;t render properly on Safari, the TOCs overlap the content. Unacceptable.</p>
<p>Until then I&#8217;m sticking with Hibernate 3.3. It just works.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Upgrading to Spring 3.0</title>
		<link>http://blog.newsplore.com/2009/03/07/upgrading-to-spring-30</link>
		<comments>http://blog.newsplore.com/2009/03/07/upgrading-to-spring-30#comments</comments>
		<pubDate>Sat, 07 Mar 2009 16:05:12 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=773</guid>
		<description><![CDATA[In the spirit of beta I&#8217;m upgrading spincloud.com to Spring 3.0. I&#8217;m using version 2.5.6 currently but it&#8217;s missing REST support and I had to use Carbonfive&#8217;s REST library which worked like a charm. Now it&#8217;s time to get back under Spring&#8217;s fold and use their built-in REST support. Spring 3 opens the door to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F07%2Fupgrading-to-spring-30"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F07%2Fupgrading-to-spring-30" height="61" width="51" /></a></div><p>
<div align='justify'>In the spirit of beta I&#8217;m upgrading <a href='http://spincloud.com'>spincloud.com</a> to Spring 3.0. I&#8217;m using version 2.5.6 currently but it&#8217;s missing REST support and I had to use Carbonfive&#8217;s <a href='http://www.carbonfive.com/community/archives/2007/06/parameterized_rest_urls_with_spring_mvc.html'>REST library</a> which worked like a charm. Now it&#8217;s time to get back under Spring&#8217;s fold and use their built-in REST support. Spring 3 opens the door to a lot of new features so I&#8217;m eager to try it.</p>
<p>I&#8217;m using Maven2 to get the jars and Ant to build the project. To fetch Spring 3.0 binaries, you have to add the following repository if you don&#8217;t have it:</p></div>
<pre>
&lt;repository&gt;
  &lt;id&gt;SpringSource Enterprise Bundle Repositorys&lt;/id&gt;
  &lt;url&gt;http://repository.springsource.com/maven/bundles/milestone&lt;/url&gt;
&lt;/repository&gt;
</pre>
<p>and the spring packages that you need since the packaging has changed from 2.5.x. Instead of a single spring.jar file, now there is one per feature so you have to sort out what jars to include in the project. I ended up with the following:</p>
<pre>
  &lt;properties&gt;
      &lt;spring.version&gt;3.0.0.M2&lt;/spring.version&gt;
  &lt;/properties&gt;
  &lt;dependencies&gt;
   ...
  &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.core&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.web&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.transaction&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.orm&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.jdbc&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.web.servlet&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.context&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.aop&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.expression&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;org.springframework.test&lt;/artifactId&gt;
      &lt;version&gt;${spring.version}&lt;/version&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
</pre>
<p>Once the jars are brought, I&#8217;ve replaced my old jarfiles with the all-new M2s then fired the build target.<br />
The first issue I found was with the asm version.<br />
  <span id="more-773"></span><br />
Spring 2.5 uses a repackaged asm version 2.2.3 (more info <a href='http://blog.springsource.com/2007/06/11/asm-version-incompatibilities-using-spring-autowired-with-hibernate/'>here</a>). The new Spring 3.0 M2 doesn&#8217;t package it anymore ( see <a href='http://blog.springsource.com/2009/02/25/spring-framework-30-m2-released/#comment-147950'>comment</a>) so I had to add it manually. I had to add the two asm 2.2.3 jars in order to resolve this dependency:</p>
<pre>
   &lt;dependency&gt;
     &lt;groupId&gt;asm&lt;/groupId&gt;
     &lt;artifactId&gt;asm-commons&lt;/artifactId&gt;
     &lt;version&gt;2.2.3&lt;/version&gt;
   &lt;/dependency&gt;
   &lt;dependency&gt;
     &lt;groupId&gt;asm&lt;/groupId&gt;
     &lt;artifactId&gt;asm&lt;/artifactId&gt;
     &lt;version&gt;2.2.3&lt;/version&gt;
   &lt;/dependency&gt;
</pre>
<p>After refreshing the jars and redeployed, I hit the first roadblock, a ClassNoDefFoundError:</p>
<pre>
Initialization of bean failed; nested exception is
java.lang.NoClassDefFoundError: Could not initialize class
net.sf.cglib.proxy.Enhancer
...
Caused by: java.lang.ClassNotFoundException:
org.objectweb.asm.CodeVisitor
</pre>
<p>Odd, I didn&#8217;t have this error before but as it turns out, I was using a cglib version 2.1.3 which has a hard dependency on asm and I actually had an asm jar version 1.5.3 packaged along with the other jar dependencies. On top of this, there is a problem with an <a href='http://www.antlr.org/'>antlr</a> version conflict. Different versions of antlr are required by Spring 3.0 and Hibernate 3.3.1 which I&#8217;m also using. This is Jar hell! So I put together a version requirment matrix to sort-out the dependencies between these libraries:</p>
<table border='1' style='text-align: center;' align='center'>
<tr>
<td></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;antlr&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;cglib&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;asm&nbsp;&nbsp;&nbsp;&nbsp;</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp;Spring 3.0 M2&nbsp;&nbsp;&nbsp;</td>
<td>3.0.1</td>
<td>&nbsp;&nbsp;2.1.x +, depends on asm 1.5.3&nbsp;&nbsp;</td>
<td>2.2.3</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp;Hibernate 3.3.1&nbsp;&nbsp;&nbsp;</td>
<td>2.7.x</td>
<td> none </td>
<td>2.2.3</td>
</tr>
</table>
<p>Fortunately the Hibernate folks have <a href='http://opensource.atlassian.com/projects/hibernate/browse/HHH-2506'>changed</a> the default bytecode generation library to javassist starting with v3.2.2. The bummer is the cglib dependency on asm 1.5.3 since this version is in conflict with asm 2.2.3 required by both Spring and Hibernate. The solution is to use a repackaged cglib as explained <a href='http://jira.springframework.org/browse/SPR-3856'>here</a>.<br />
To get the nodep version of cglib, I added the following snippet in my pom.xml file:</p>
<pre>
&lt;dependency&gt;
  &lt;groupId&gt;cglib&lt;/groupId&gt;
  &lt;artifactId&gt;cglib-nodep&lt;/artifactId&gt;
  &lt;version&gt;2.2&lt;/version&gt;
&lt;/dependency&gt;
</pre>
<p>I&#8217;m taking the opportunity and upgrade to the newer version 2.2 of cglib.<br />
Next is antlr. Spring requires a different version of antlr than Hibernate but fortunately antlr has changed the package notation from antlr.* in v2.x to org.antlr.* in v3.x so it&#8217;s safe to include both jars. Let&#8217;s get both versions through Maven:</p>
<pre>
   &lt;dependency&gt;
     &lt;groupId&gt;antlr&lt;/groupId&gt;
     &lt;artifactId&gt;antlr&lt;/artifactId&gt;
     &lt;version&gt;2.7.7&lt;/version&gt;
   &lt;/dependency&gt;
   &lt;dependency&gt;
     &lt;groupId&gt;org.antlr&lt;/groupId&gt;
     &lt;artifactId&gt;antlr&lt;/artifactId&gt;
     &lt;version&gt;3.0.1&lt;/version&gt;
   &lt;/dependency&gt;
</pre>
<p>Here&#8217;s the mix of jars that works for me with Spring &amp; Hibernate:</p>
<table border='1' style='text-align: center;' align='center'>
<tr>
<td></td>
<td>antlr</td>
<td>cglib</td>
<td>asm</td>
</tr>
<tr>
<td rowspan='2'>&nbsp;&nbsp;Spring 3.0 M2 &amp;<br />&nbsp;&nbsp;Hibernate 3.3.1&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;antlr-2.7.7.jar &amp; <br />&nbsp;&nbsp;antlr-3.0.1.jar&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;cglib-nodep-2.2.jar&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;asm-2.2.3.jar&nbsp;&nbsp;</td>
</tr>
</table>
<p>I can&#8217;t help but notice the compatibility problems with using the Spring &amp; Hibernate mix. It wasn&#8217;t easy to fix them and it still feels more of a hack than an actual solution. In Spring&#8217;s defense, this is a milestone version so I should expect some wrinkles. I had similar issues when upgrading Hibernate a while back. Hibernate was the first to change their packaging to use feature-centric jars (I think). I recall having issues around antlr and asm. I remember being reluctant at first about the new dependency to javassist but it worked just fine.</p>
<p>Next on the list is refactoring the controllers to use the new REST support of Spring. The majority of my controllers are extending from org.springframework.web.servlet.mvc.AbstractController so I&#8217;ll upgrade them to use <a href='http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html#mvc-ann-controller'>@Controller</a> stereotype. I&#8217;m already familiar with @Controller, I&#8217;m using it to route all top URLs found on Spincloud&#8217;s header (i.e. <a href='http://spincloud.com/features'>features</a>). I use a simple approach: drop the inheritance to <a href='http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/AbstractController.html'>AbstractController</a> and change handleRequestInternal:</p>
<pre>
@Controller
public class WeatherDetailsController extends AbstractController {
...
  @Override
   protected ModelAndView handleRequestInternal(HttpServletRequest request,
     HttpServletResponse response) throws Exception {
    //parse URI to extract stationIDs
...
  }
}
</pre>
<p>with the much cooler:</p>
<pre>
@Controller
public class WeatherDetailsController {
...
 @RequestMapping(value="/weather/{stationIds}", method = RequestMethod.GET)
 public ModelAndView displayWeather(@PathVariable("stationIds") String idz,
   HttpServletRequest request, HttpServletResponse response) {
...
  }
}
</pre>
<p>Last, remove the carbonfive HandlerMapping bean in the spring servlet XML which used to look like this:</p>
<pre>
 &lt;bean class="carbonfive.spring.web.pathparameter.ParameterizedUrlHandlerMapping"&gt;
  &lt;property name="alwaysUseFullPath" value="true"/&gt;
  &lt;property name="mappings"&gt;
   &lt;props&gt;
    &lt;prop key="/weather/*"&gt;weatherDetailsController&lt;/prop&gt;
   &lt;/props&gt;
  &lt;/property&gt;
 &lt;/bean&gt;
</pre>
<p>Deployed and started the container successfully but when I hit a URL that was supposed to be routed through the new controller, I got the following error:</p>
<pre>
2009-03-07 20:55:49,072: WARN  PageNotFound:1017
 No mapping found for HTTP request with URI [/weather/15150] in
DispatcherServlet with name 'weather'
</pre>
<p>Bummer: the URL is not routed to any controller. I initially suspected the DefaultAnnotationHandlerMapping I was using was to blame but after searching on the interweb and finding nothing else worthy and a couple of hours of research in my own code, I discovered that the problem was in web.xml. I had fine grained servlet-mapping URLs, including one that should have routed all URLs starting with /weather  that looked like this: </p>
<pre>
 &lt;servlet-mapping&gt;
   &lt;servlet-name&gt;weather&lt;/servlet-name&gt;
   &lt;url-pattern&gt;/weather/*&lt;/url-pattern&gt;
 &lt;/servlet-mapping&gt;
</pre>
<p>which is not good anymore. After checking the <a href='https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.M2/org.springframework.samples.petclinic/src/main/webapp/WEB-INF/web.xml'>web.xml</a> file in the Petstore example, I noticed that the servlet mappings can use the greedy &lt;url-pattern&gt;/&lt;/url-pattern&gt; to route to one controller then more specific patterns for routing to other controllers. Since I have more than one controller, I changed the mappings like below:</p>
<pre>
 &lt;servlet-mapping&gt;
   &lt;servlet-name&gt;weather&lt;/servlet-name&gt;
   &lt;url-pattern&gt;/&lt;/url-pattern&gt;
 &lt;/servlet-mapping&gt;
 &lt;servlet-mapping&gt;
   &lt;servlet-name&gt;tag&lt;/servlet-name&gt;
   &lt;url-pattern&gt;/tag/*&lt;/url-pattern&gt;
 &lt;/servlet-mapping&gt;
</pre>
<div align='justify'>
<p>Tested again the URL and it correctly routed to the right controller.<br />
I was home-free after this bump. Cleaned-up the code, removed lots of XML (always popular), dropped the -now obsolete- URL parsing and validation and now I&#8217;m contemplating a much cleaner and more concise code.</p>
<p></p>
<p>There are other features that come with this Spring upgrade, detailed <a href='http://blog.springsource.com/2009/02/25/spring-framework-30-m2-released/'>here</a> and <a href='http://springinpractice.com/2008/12/02/new-stuff-in-spring-30/'>here</a>. I especially like the sound of the promised scheduling namespace since I currently have to maintain long XML files to configure the timers that trigger the fetching of weather data. This will be one of the few remaining pieces of XML that I still have. A nice touch is the new <a href='http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/CookieValue.html'>@CookieValue</a>.<br />
Moving forward, Spring promises to deliver a host of exciting features:<br />
- Declarative validation (JSR 303). I&#8217;m really excited about this one having used Hibernate&#8217;s JSR 303 implementation. I love this JSR, it&#8217;s a step in the right direction!<br />
- JPA 2.0 support and early JEE 6 support. Details about what JEE6 will bring are available <a href='http://www.theserverside.com/tt/articles/article.tss?l=JavaEE6Overview'>here</a>.<br />
- Spring Portlet MVC, based on the Portlet 2.0 API (JSR-286)<br />
- Annotation based factory methods (working towards XML configuration obliteration). I use factory methods so I like this one too.<br />
- A rumor that a JSON view will be available. I&#8217;ve written my own JSONServiceExporter and a JSONView for <a href="http://spincloud.com">Spincloud</a> (I use JSON for all front-end data pipes) but I&#8217;d switch to a leaner solution if available.</p>
<p>&#8230;and much more.</p>
<p><del datetime="2009-03-10T23:13:09+00:00">I&#8217;d like to see the annotation-based </del><a href='http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes'><del datetime="2009-03-10T23:13:09+00:00">bean scopes</del></a>   (already available through Spring&#8217;s <a href='http://static.springframework.org/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html#scoped-proxy'>@ScopedProxy</a>,  part of the JavaConfig project). Also, better support for multiple data sources in a non-JTA environment (I&#8217;ll detail my problems with it in another post).</p>
<p>For now, I&#8217;m content. Except for a few (expected) wrinkles, Spring delivers again and it succeeds in keeping things exciting in the Java space. Way to go guys!
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/03/07/upgrading-to-spring-30/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

