为什么Glassfish服务器在使用ZoneId创建java.time.LocalDate实例时抛出NoSuchMethodError
我有这段代码,它创建了java.time.LocalDate的一个实例。我用JDK 14编译了它,它运行时没有任何错误:为什么Glassfish服务器在使用ZoneId创建java.time.LocalDate实例时抛出NoSuchMethodError,java,localdate,glassfish-5,Java,Localdate,Glassfish 5,我有这段代码,它创建了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服务
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)
有什么想法吗?
感谢虽然该方法存在于Java14中,但它不存在于Java8中的类中。我希望您使用JDK 14进行编译,但在较低版本的Java上运行它。如果您阅读文档,即的javadoc,您会发现: 自: 九, 代码是根据Java9+运行时库编译的,但是使用-target 1.8编译的,您使用的是Java8 不要这样做,也就是说,始终确保编译时使用的运行库版本与生成的字节码版本相同 解决方案:使用编译器选项-release8,而不是-source8-target8。该选项被特别添加到Java9+编译器中,以便于针对运行库的正确版本编译旧版本的Java 推荐:有关详细信息,请参阅 更新 注释中提到,NetBeans用于编译代码。我没有NetBeans,但我相信它的功能与我使用的Eclipse非常相似,因此我将展示如何在Eclipse中修复此问题,并希望您可以自己将其应用于NetBeans 在Eclipse中,您需要在两个位置指定目标Java版本: Eclipse中的类路径或构建路径: 命令行上的编译器符合性级别-源和目标: 在过去,这两个版本应该总是指同一个版本,例如,如图所示,其中构建路径指的是安装JDK 15的位置,并且符合性级别设置为15 从Java9和new-release编译器选项开始,您可以针对Java的旧版本,而无需安装这样的旧版本 让构建路径指向JDK 15,如果您还选中了用蓝色圈出的Use'-release'选项复选框,则可以将符合性版本更改为例如8 如果不更改生成路径以匹配法规遵从性版本,则选中“使用“-release”选项复选框非常重要
这样做将确保编译器在LocalDate.ofInstant调用上失败,因为该方法在JDK 8中不存在,即使构建路径上仍然有JDK 15。根据Java8和关于LocalDate和LocalDateTime的更高版本,GlassFish使用jre8的版本和下一个版本有一些更改,从Java9开始 爪哇8 ofInstant是在LocalDateTime上实现的 爪哇9+ ofInstant在LocalDate上实现 为了遵循您的逻辑,您可以执行以下操作:
LocalDateTime dTime = LocalDateTime.ofInstant(then.toInstant(),ZoneId.systemDefault());
LocalDate dthen = dTime.toLocalDate();
LocalDateTime允许您获得适当的变量类型:LocalDate
公共LocalDate toLocalDate
获取此文件的LocalDate部分
日期时间。这将返回具有相同年、月和日的LocalDate
和这个日期时间一样
如果代码只是用JDK14编译的,那么生成的字节码就不会用Java8运行。要比这复杂一点,请看。是的,整个Web应用程序代码都是用JDK 14编译的,然而,Glassfish 5.1容器是在JDK8的变体上运行的,这是一个很好的解决方案,但是如果Java 8不存在该方法,为什么代码要在Java 8上编译和运行呢?谢谢,aran,这可能就是解决方案。我明天会试试,然后告诉你结果。@aran-你非常擅长使用现有的API找到解决方案。我之前也给出过这样的反馈。坚持下去@LiveandLetLive我把感伤放在这里。。。非常感谢你的话!!你是我在max尊重的那些用户中的一员,你是顶级用户中的一员。你让我学到了新的东西,这是真诚的。谢谢你的现场直播Live@aran如果IDE的编译器是v14,那么代码就不会在Java8上运行。您必须告诉IDE使用-target 8或等效IDE生成与Java 8兼容的字节码。如果这样做,还必须更改类路径以使用JDK 8安装,否则会出现类似于本问题中所示的错误。显然没有这样做,因此错误的原因是IDE配置错误。有关如何修复的信息,请参阅。如果配置正确,代码将无法编译,需要这个答案来解决这个问题。非常感谢您如此详细地阐述了这个问题。Netbean设置与Eclipse略有不同,因为NB允许用户预先设置平台,即JDK 14、JDK 8、JDK 9等等。我已经将两个这样的平台JDK 14配置为默认平台和JDK-8-update-144-for-Glassfish。对于Web应用程序开发项目,没有其他构建选项,例如-release。这次,我选择了JDK-8-update-144-for-Glassfish t
o编译源代码,当然,它将LocalDate.ofInstant标记为错误,并在我挂断自己之前切断了连接。因为我需要这个LocalDate.ofInstant功能,所以我最终使用了Aran建议的方法。再次感谢