Blogs

SpringSource Blog

Spring Framework 3.1 RC1 released

Juergen Hoeller

It is my pleasure to announce that the first Spring Framework 3.1 release candidate has – finally – been released this week! We have been working on this release for several months, completing our milestone work and recently adding support for Java SE 7 and for Hibernate 4.0 to the feature list.

Spring Framework 3.1 RC1 completes the 3.1 feature set:

* The environment abstraction and the environment profile mechanism for bean definitions.

* Comprehensive Java-based application configuration based on @Enable* annotations on @Configuration classes.

* An overhaul of the TestContext framework with first-class support for @Configuration classes and for environment profiles.

* Our new "c:" namespace for conveniently specifying constructor arguments by name in a concise inline style.

* The cache abstraction with our declarative caching solution (@Cacheable etc) on top.

* The Servlet 3.0 based WebApplicationInitializer mechanism for bootstrapping a Spring web application without web.xml!

* Revised MVC processing with flash attribute support, a new @RequestPart annotation, and REST support refinements.

* Refined JPA support: package scanning without persistence.xml; consistent configuration based on persistence unit names.

* Support for Hibernate 4.0 (CR4 at this time) as well as for Quartz 2.0, while preserving compatibility with older versions.

* Last but not least: a Java 7 theme, with JDBC 4.1 getting autodetected and with basic support for ForkJoinPool setup.

Note that we eventually dropped conversation support from the 3.1 feature set since there was stronger demand for other themes of the above. We will reconsider conversation support for Spring 3.2, based on further feedback and on concrete solutions demanded for the next-generation web application architectures that are being built today.

We are preparing for the 3.1 GA release in late November now, with an RC2 planned in between. Let us know how RC1 works for you in the meantime!

Similar Posts

Share this Post
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter
 

13 responses


  1. Congratulations for moving forward. It will be interesting to see more web.xml-less jars being injected.


  2. Hi, Does JPA package scanning already include Custom ORM.xml found in package? (like hbm.xml in Spring hibernate support)


  3. Hi Juergen,

    Has RC1 changed in terms of creating (automatic) JNDI template and using InitialContext?

    RC1 does not work on Google App Engine as InitialContext is a restricted class. M2 was working fine btw.

    java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.springframework.jndi.JndiTemplate.createInitialContext(JndiTemplate.java:136)
    at org.springframework.jndi.JndiTemplate.getContext(JndiTemplate.java:103)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:85)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:37)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:77)
    at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:32)
    at org.springframework.jndi.JndiPropertySource.getProperty(JndiPropertySource.java:82)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:73)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:59)
    at org.springframework.core.env.AbstractEnvironment.doGetDefaultProfiles(AbstractEnvironment.java:229)
    at org.springframework.core.env.AbstractEnvironment.acceptsProfiles(AbstractEnvironment.java:257)
    at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent(ClassPathScanningCandidateComponentProvider.java:303)
    at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:232)
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:218)
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan(ClassPathBeanDefinitionScanner.java:196)
    at org.springframework.web.context.support.AnnotationConfigWebApplicationContext.loadBeanDefinitions(AnnotationConfigWebApplicationContext.java:236)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
    at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:186)
    at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:182)
    at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:172)
    at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:164)
    at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
    at com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:113)
    at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
    at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:186)
    at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:182)
    at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:172)
    at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:164)
    at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
    at com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:113)
    at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
    Caused by: java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.springframework.jndi.JndiTemplate.createInitialContext(JndiTemplate.java:136)
    at org.springframework.jndi.JndiTemplate.getContext(JndiTemplate.java:103)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:85)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:37)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:77)
    at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:32)
    at org.springframework.jndi.JndiPropertySource.getProperty(JndiPropertySource.java:82)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:73)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:59)
    at org.springframework.core.env.AbstractEnvironment.doGetDefaultProfiles(AbstractEnvironment.java:229)
    at org.springframework.core.env.AbstractEnvironment.acceptsProfiles(AbstractEnvironment.java:257)
    at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent(ClassPathScanningCandidateComponentProvider.java:303)
    at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:232)
    … 27 more

    Cheers,
    Marcel


  4. Donny, even with Spring 3.1, orm.xml is just being discovered through a regular persistence.xml file. The JPA SPIs do not allow for individual loading of orm.xml files: They'll rather always get loaded within the persistence unit root URL, i.e. relative to the location of a persistence.xml file.

    As a consequence, you can either use orm.xml persistence.xml as usual, or no JPA XML files at all through Spring's "packagesToScan" feature.

    Juergen


  5. Marcel – oops, that wasn't quite the intention. Looks like we'll have to do the JNDI check in an optional manner, trying loadClass("javax.naming.InitialContext") first and seeing whether it fails. In any case, we'll fix this for 3.1 RC2.

    Juergen


  6. Thanks for reply Juergen, will rollback to M2 and wait for RC2 then I guess… (was really looking for RC1 especially because of new FlashScope)


  7. @Juergen: Thanks for the reply. I didn't know that JPA has this limitation.
    I only use mapping files for externalizing queries. It's quite troublesome to add the path to each mapping file on persistence.xml
    Maybe Spring Data JPA is the best place to solve this problem.


  8. @Juergen: to track progress about the InitialContext issue on GAE I created issue https://jira.springsource.org/browse/SPR-8781.


  9. thank you for share this


  10. Hello,

    I noticed that you dropped the SessionFactoryBuilder from RC1. So, what is the preferred way to expose a SessionFactory in JavaConfig? You cannot do this:

    @Bean
    public SessionFactory sessionFactory() {
    AnnotationSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
    sessionFactoryBean.setDataSource(dataSource());
    sessionFactoryBean
    .setPackagesToScan(new String[] { "de.package" });
    return sessionFactoryBean.getObject();
    }

    Mainly because the AnnotationSessionFactoryBean is an InitializingBean as well and afterPropertiesSet doesn't get called. I could call it myself in the code, but then I guess the destroy-method of the DisposableBean-Interface won't get called in the end.
    So, I guess I have to expose the FactoryBean itself as a Spring Bean and then call getObject on it when I need the SessionFactory, right?
    What do you suggest?


  11. Hi Jürgen,

    i'm using https://gist.github.com/861863 to replace the default mvc:annotation-driven tag to provide my own path matcher.

    Is it correct that i need to use org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping and org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter to make use of RedirectAttributes in @Controller methods?

    Thanks and kind regards,
    Michael


  12. Hi Jürgen,

    A long time ago, Keith Donald said that Spring Web Flow 3.0 was to be aligned with Spring 3.1 (http://bit.ly/sSsAms). Any news on that? Numerous forum threads are left unanswered. The community is longing for answers… Please give us some status.

    Kind regards,
    Runar


  13. Im testing Spring Toolsuit and Spring MVC.
    My feedback is:

    - The Project structure is very complicated and confusing (2 pom.xml files ?!?!? why?)

    - Configuration over XML files… welcome in 2012…

    - If u searching for Tutorials in the web u will find a lot of them. But you can not realy use them. The Rule is NEW SPRING VERSION -> NEW TUTORIAL. Why? Its simple. there is no JAR-Nameconvention, no XML-FileName Convention (app-context.xml or root-context.xml or servlet-context.xml)

4 trackbacks

Leave a Reply