Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mvc:annotation-driven intends to autodetect JodaTime 1.3 but accidentally includes earlier versions as well [SPR-7222] #11881

Closed
spring-projects-issues opened this issue May 19, 2010 · 4 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented May 19, 2010

Holger Brands opened SPR-7222 and commented

When using mvc:annotation-driven, Spring tries to register default formatters for JodaTime, when JodaTime is on the classpath (class org.joda.time.DateTime is searched for).
If it's found, formatters are registered, for example for LocalDate.
But LocalDate was added in JodaTime 1.3 AFAIK.
So when you have JodaTime 1.2,x on the classpath, the classpath check for DateTime is successful, but registering the default formatters fails with the appended root cause exception:

So, either the documentation should clearly state the supported JodaTime versions (excluding JodaTime < 1.3), or
mvc:annotation-driven should work for JodaTime 1.2 also, e.g. with more fine-grained checks for the available classes.


Exception trace:
java.lang.ClassNotFoundException: org.joda.time.LocalDate
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:95)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:107)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:31)
at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:50)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:120)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:31)
at sun.reflect.generics.repository.ClassRepository.getSuperInterfaces(ClassRepository.java:82)
at java.lang.Class.getGenericInterfaces(Class.java:794)
at org.springframework.core.GenericTypeResolver.doResolveTypeArguments(GenericTypeResolver.java:140)
at org.springframework.core.GenericTypeResolver.resolveTypeArguments(GenericTypeResolver.java:135)
at org.springframework.core.convert.support.GenericConversionService.getRequiredTypeInfo(GenericConversionService.java:220)
at org.springframework.core.convert.support.GenericConversionService.addConverter(GenericConversionService.java:81)
at org.springframework.format.datetime.joda.JodaTimeConverters.registerConverters(JodaTimeConverters.java:45)
at org.springframework.format.datetime.joda.JodaTimeFormattingConfigurer.installJodaTimeFormatting(JodaTimeFormattingConfigurer.java:97)
at org.springframework.format.support.FormattingConversionServiceFactoryBean.installFormatters(FormattingConversionServiceFactoryBean.java:101)
at org.springframework.format.support.FormattingConversionServiceFactoryBean.afterPropertiesSet(FormattingConversionServiceFactoryBean.java:73)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:603)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:144)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:993)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:897)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:603)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:144)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:993)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:897)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:387)
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1116)
at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:266)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.initInterceptors(AbstractUrlHandlerMapping.java:168)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.initApplicationContext(AbstractHandlerMapping.java:110)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:57)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:99)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:82)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1405)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:563)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:872)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1173)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:809)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:129)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)


Affects: 3.0.2

Referenced from: commits f9736ec, 6fe5871

@spring-projects-issues
Copy link
Collaborator Author

Holger Brands commented

Is there a workaround for using annotation-based controllers when we do not want to upgrade JodaTime?

Note, we also have custom SimpleUrlHandlerMapping defined, so we need to explicitly enable @Controller handling, right?
Is this possible without mvc:annotation-driven or can we disable JodaTime default handling?

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Indeed, our JodaTime support does require JodaTime 1.3 or higher. The bug here is that we are trying to auto-register our JodaTime support even if an earlier version is present. I've simply refined our classpath presence check to look for "org.joda.time.LocalDate" which should work reliably now. This will be available in tonight's Spring 3.0.3 snapshot.

Instead of using the mvc namespace, you may also define plain DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans (package org.springframework.web.servlet.mvc.annotation) in your DispatcherServlet context. Those will active the base @MVC support as well, without additional goodies (no formatting annotations etc).

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Holger Brands commented

Thanks for the really quick fix ;-)
Perhaps this requirement should also be documented, for example in section "15.12.1 mvc:annotation-driven" in the reference manual.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Good point - I've added the Joda Time version requirement to that paragraph in the ref docs.

Juergen

@spring-projects-issues spring-projects-issues added type: bug A general bug in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 3.0.3 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants