0

我有这段代码可以创建 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)

任何想法?

谢谢

4

3 回答 3

3

虽然LocalDate.ofInstant方法存在于 Java 14 中,但它不存在于 Java 8 的LocalDate类中。我希望您使用 JDK 14 进行编译,但在较低版本的 Java 上运行它。

于 2021-01-16T19:28:50.553 回答
3

如果您阅读文档,即 的 javadoc LocalDate.ofInstant(Instant, ZoneId),您会发现:

自从:

9

该代码是针对 Java 9+ 运行时库编译的,但是是使用 Java 8 编译的,-target 1.8并且您正在使用 Java 8 运行。

不要那样做,即始终确保您编译的运行时库版本与生成的字节码版本相同。

解决方案:使用编译器选项--release 8而不是-source 8 -target 8. 该选项专门添加到 Java 9+ 编译器中,以便更轻松地针对运行时库的正确版本为旧版本的 Java 进行编译。

推荐:有关更多详细信息请参阅JEP 247:为旧平台版本编译。


更新

在对aran 的回答的评论中提到NetBeans 用于编译代码。我没有 NetBeans,但我相信它的功能与我使用的 Eclipse 非常相似,因此我将展示如何在 Eclipse 中解决此问题,并希望您可以自己将其应用到 NetBeans。

在 Eclipse 中,您需要在 2 个地方指定目标 Java 版本:

  • 类路径(或 Eclipse 中的构建路径):

    在此处输入图像描述

  • 编译器合规级别(-source-target命令行):

    在此处输入图像描述

在过去,这两个应该始终指代相同的版本,例如此处所示,其中构建路径指的是安装JDK 15的位置,并且合规级别设置为15

从 Java 9 和新的--release编译器选项开始,您可以针对 Java 的旧版本,而无需安装这样的旧版本。

让构建路径指向 JDK 15,您可以将合规版本更改为例如 8,如果您还选中Use '--release' option复选框(以蓝色圈出)。

Use '--release' option如果您不更改构建路径以匹配合规版本,则选中该复选框非常重要。

这样做将确保编译器在LocalDate.ofInstant()调用时失败,因为 JDK 8 中不存在该方法,即使构建路径上仍然有 JDK 15。

于 2021-01-16T19:30:23.647 回答
2

根据 Java8 和关于LocalDateand的进一步版本LocalDateTime,GlassFish 使用的一个 (jre8) 和从 Java9 开始的下一个有一些变化。

  • Java8
    ofInstant实现于LocalDateTime

  • Java9+

    ofInstant实施于LocalDate

为了遵循您的逻辑,您可以这样做:

LocalDateTime dTime = LocalDateTime.ofInstant(then.toInstant(),ZoneId.systemDefault());
LocalDate dthen = dTime.toLocalDate();

LocalDateTime'stoLocalDate()将允许您获得适当的变量类型:LocalDate

public LocalDate toLocalDate()

获取此日期时间的 LocalDate 部分。这将返回与此日期时间具有相同年、月和日的 LocalDate。

于 2021-01-16T19:31:12.893 回答