【问题标题】:How does Spring use Java 8 classes, yet it runs on Java 7?Spring 如何使用 Java 8 类,但它在 Java 7 上运行?
【发布时间】:2014-03-26 11:39:58
【问题描述】:

我最近在 Spring Framework 中下载了 Spring MVC(版本 4.0.2.RELEASE)模块的源代码。我的意图是针对模块的实际源代码而不是实际的.jar 文件运行。 (长话短说,仅用于测试目的)。

下载源代码后,我从我的项目中删除了jar文件,编译并部署到服务器。当我点击调度程序 servlet 处理的 URL 之一时,我看到了错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0': Invocation of init method failed; nested exception is java.lang.Error: Unresolved compilation problems: 
    The import java.time cannot be resolved
    The method toZoneId() is undefined for the type TimeZone
    ZoneId cannot be resolved

经过一些研究和深入研究源代码后,我意识到错误中提到的类是 JDK/JRE 1.8 的一部分。在删除 .jar 文件之前,我的项目在 JDK/JRE 1.7 上运行没有问题。

我的问题是 Spring 如何包含 JDK 1.8 中的类,但仍设法在 JDK/JRE 1.7 下运行?为什么使用Spring的.jar文件时没有抛出异常,但是我提供源时却抛出异常(并且jar文件丢失)?

全栈跟踪

Mar 26, 2014 7:27:18 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Allocate exception for servlet dispatcher
java.lang.Error: Unresolved compilation problems: 
    The import java.time cannot be resolved
    The method toZoneId() is undefined for the type TimeZone
    ZoneId cannot be resolved

    at org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.<init>(ServletRequestMethodArgumentResolver.java:23)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getDefaultArgumentResolvers(RequestMappingHandlerAdapter.java:522)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.afterPropertiesSet(RequestMappingHandlerAdapter.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:624)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:672)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:543)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1274)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1186)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:858)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:136)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

【问题讨论】:

  • 你能发布完整的堆栈跟踪吗?该类似乎没有这些导入。
  • @SotiriosDelimanolis 班级是ServletRequestMethodArgumentResolver,我会发布stacktrace。

标签: java spring java-8


【解决方案1】:

标题问题的答案是:Spring 使用 Java 8 构建,但与 Java 7(和 6)兼容。

ServletRequestMethodArgumentResolver 确实导入了 java.time.ZoneId,但它仅引用嵌套类中的该类,除非 Java 8 在类路径上,否则该类不会被实例化。在 Spring 源代码中有很多这样的示例(例如,自从它开始支持 Java 5 以来一直如此)。

【讨论】:

  • 是的,很明显,如果你真的必须编译它。从 Spring 发货的 jar 有什么问题?
  • 正如我所说的长篇大论,我不宽恕这个!基本上,我被要求扫描 Spring Framework 以确保它是安全的。很想听听您对此的看法。
  • @KevinBowersox 扫描弹簧以确保其安全 :) 祝凯文好运
  • @AbdullahShaikh 再说一遍,不是我的主意!
  • @AbdullahShaikh 我并不嫉妒这份工作,但这正是开源软件的有趣之处。很高兴它不时发生。
猜你喜欢
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 2014-12-11
  • 2014-08-07
  • 2013-03-20
相关资源
最近更新 更多