Wednesday, 20 March 2013

Creating a Spring 3.2 MVC Web App

A couple of days ago, I wrote a blog outlining how I upgraded my Spring sample code to version 3.2.1-RELEASE and demonstrated a few of the little 'gotchas' that arose. One of those 'gotchas' involved a Spring ContentNegotiationManagerFactoryBean error and I demonstrated a fix that involved declaring the spring-web module in your POM file, rather than relying on its import as a transient dependency, which I'm guessing pulled in the wrong version.

Since than I've been perusing Spring 3.2's new feature list, deciding which I thought were useful and would also make good blogs. When writing a blog, the first thing I like to do is to create a working sample and so I decided to create a new Spring MVC project using the Spring Project Template feature on the SpringSource Dashboard.



The first problem I came up against was the fact that the Guys at Spring who work on the MVC project template are a little behind the Guys at Spring who work on the actual Spring framework. I say this because, at the time of writing and even though I updated to the latest project template, on clicking new Spring MVC Project, I got an old Spring 3.1.1-RELEASE project. Fortunately its only a simple matter to manually upgrade to Spring 3.2.

The first thing is to change the Spring version number in the pom.xml file. In keeping with my previous blog, I changed the version number to 3.2.1-RELEASE and the Java version to 1.7 as shown in the snippet below:

<properties>
  <java-version>1.7</java-version>
  <org.springframework-version>3.2.1.RELEASE</org.springframework-version>
  <org.aspectj-version>1.6.10</org.aspectj-version>
  <org.slf4j-version>1.6.6</org.slf4j-version>
 </properties>

I also checked the Spring context XML files to ensure that they didn't mention Spring 3.1 and so far so good. However, on opening the servlet-context.xml file I again found the following error:


…which, when looking the STS error log was:

Error occured processing '/spring-3.2/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml'
java.lang.NoClassDefFoundError: org/springframework/web/accept/ContentNegotiationManagerFactoryBean
     at org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser.getContentNegotiationManager(AnnotationDrivenBeanDefinitionParser.java:293)
     at org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser.parse(AnnotationDrivenBeanDefinitionParser.java:151)
     at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:73)
     at org.springframework.ide.eclipse.beans.core.internal.model.namespaces.DelegatingNamespaceHandlerResolver$ElementTrackingNamespaceHandler.parse(DelegatingNamespaceHandlerResolver.java:177)
     at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1419)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$ErrorSuppressingBeanDefinitionParserDelegate.parseCustomElement(BeansConfig.java:1399)
     at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1409)
     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$ToolingFriendlyBeanDefinitionDocumentReader.doRegisterBeanDefinitions(BeansConfig.java:1329)
     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$2.registerBeanDefinitions(BeansConfig.java:401)
     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$2.loadBeanDefinitions(BeansConfig.java:387)
     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$3.call(BeansConfig.java:444)
     at org.springframework.ide.eclipse.beans.core.internal.model.BeansConfig$3.call(BeansConfig.java:1)
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
     at java.util.concurrent.FutureTask.run(FutureTask.java:166)
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
     at java.util.concurrent.FutureTask.run(FutureTask.java:166)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
     at java.lang.Thread.run(Thread.java:722) 

Now, I could have used the fix outlined in my previous blog; however, the Guys at Spring have been busy and now the solution to this problem is to simply upgrade to Spring version 3.2.2-RELEASE:

<properties>
  <java-version>1.7</java-version>
  <org.springframework-version>3.2.2.RELEASE</org.springframework-version>
  <org.aspectj-version>1.6.10</org.aspectj-version>
  <org.slf4j-version>1.6.6</org.slf4j-version>
 </properties>

More on Spring 3.2 later...


1 comment:

RafaƂ Borowiec said...

If you are interested in bootstrapping the Spring MVC 3.2 application with Maven, check this out: https://github.com/kolorobot/spring-mvc-quickstart-archetype