如何解决为什么 Glassfish 服务器在使用 ZoneId 创建 java.time.LocalDate 实例时抛出 NoSuchMethodError
我有这段代码可以创建 java.time.LocalDate 的一个实例。我用 JDK 14 编译它,它运行没有任何错误:
public void foo(Date d){
LocalDate d1 = LocalDate.ofInstant(d.toInstant(),ZoneId.systemDefault());
System.out.println("Created LocalDate from Date: "+d1);
}
当我尝试在 Glassfish 服务器 5.1 上运行的 JSF 页面的支持 bean 中执行相同的操作时,它会引发 NoSuchMethodError。
public void validateDateTimeLine(FacesContext fc,UIComponent ui,Object value) {
Date then = (Date) value;
try {
LocalDate dthen = LocalDate.ofInstant(then.toInstant(),ZoneId.systemDefault());
LocalDate Now = LocalDate.ofInstant(Instant.Now(),ZoneId.systemDefault());
....................................
} catch (Exception | NoSuchMethodError e) {
}
}
堆栈跟踪:
java.lang.NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;)Ljava/time/LocalDate;
at org.me.mavenlistservicedb.bean.LoginManagment.validateDateTimeLine(LoginManagment.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.module.web.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.module.web.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:107)
at javax.faces.validator.MethodExpressionValidator.validate(MethodExpressionValidator.java:109)
at javax.faces.component.UIInput.validateValue(UIInput.java:1248)
at javax.faces.component.UIInput.validate(UIInput.java:1037)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1334)
at javax.faces.component.UIInput.processValidators(UIInput.java:757)
at javax.faces.component.UIData.iterate(UIData.java:2150)
at javax.faces.component.UIData.processValidators(UIData.java:1273)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1298)
at javax.faces.component.UIForm.processValidators(UIForm.java:269)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1298)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1332)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:77)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:201)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:670)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1540)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:119)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:611)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:550)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:114)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:199)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadioStrategy.run0(WorkerThreadioStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadioStrategy.access$100(WorkerThreadioStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadioStrategy$WorkerThreadRunnable.run(WorkerThreadioStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
任何的想法?
谢谢
解决方法
虽然 LocalDate.ofInstant 方法存在于 Java 14 中,但它不在 Java 8 的 LocalDate 类中。我希望您使用 JDK 14 进行编译,但在较低版本上运行它
,如果您阅读文档,即 LocalDate.ofInstant(Instant,ZoneId)
的 javadoc,您会发现:
因为:
9
代码是针对 Java 9+ 运行时库编译的,但使用 -target 1.8
编译,而您使用的是 Java 8。
不要这样做,即始终确保您编译的运行时库版本与生成的字节码版本相同。
解决方案:使用编译器选项 --release 8
而不是 -source 8 -target 8
。该选项专门添加到 Java 9+ 编译器中,以便更轻松地针对旧版本的 Java 针对正确版本的运行时库进行编译。
推荐:请参阅JEP 247: Compile for Older Platform Versions了解更多详情。
更新
aran's answer 的注释中提到 NetBeans 用于编译代码。我没有 NetBeans,但我相信它的功能与我使用的 Eclipse 非常相似,因此我将展示如何在 Eclipse 中解决此问题,希望您可以将其应用到 NetBeans。
在 Eclipse 中,您需要在 2 个地方指定目标 Java 版本:
在过去,这两个应该总是指同一个版本,例如如此处所示,其中构建路径是指安装 JDK 15 的位置,并且合规性级别设置为 15。
从 Java 9 和新的 --release
编译器选项开始,您可以针对较旧版本的 Java,而无需安装此类较旧版本。
让构建路径指向 JDK 15,您可以将合规版本更改为例如8、如果您还选中 Use '--release' option
复选框(蓝色圆圈)。
如果您不更改构建路径以匹配合规版本,则选中 Use '--release' option
复选框非常重要。
这样做将确保编译器在调用 LocalDate.ofInstant()
时失败,因为该方法在 JDK 8 中不存在,即使构建路径上仍有 JDK 15。
根据关于 LocalDate
和 LocalDateTime
的 Java8 和更高版本,GlassFish 使用的一个 (jre8) 和从 Java9 开始的下一个版本有一些变化。
-
Java8
上实现ofInstant
在LocalDateTime
-
Java9+
ofInstant
在LocalDate
上实现。
为了遵循您的逻辑,您可以这样做:
LocalDateTime dTime = LocalDateTime.ofInstant(then.toInstant(),ZoneId.systemDefault());
LocalDate dthen = dTime.toLocalDate();
LocalDateTime
的 toLocalDate()
将允许您获得适当的变量类型:LocalDate
public LocalDate toLocalDate()
获取其中的 LocalDate 部分 约会时间。这将返回具有相同年月日的 LocalDate 作为这个日期时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。