我们最近将应用程序从 Java 11 过渡到 Java 17。部署后,我们注意到某些记录存在差异,其中日期显示有一日差异 (+1)。这种情况尤其发生在 1940 年之前的记录中。我们的应用程序在 CEST 时区运行,日期在 MongoDB 中存储为 UTC。以下示例重点介绍了我们已发现问题的实例。
| D B | 爪哇11 | 爪哇17 |
|---|---|---|
| 1934-07-21T22:40:28.000+00:00 | 1934年7月22日 | 1934年7月21日 |
| 1897-08-06T23:40:28.000+00:00 | 1897-08-07 | 1897-08-06 |
提供的代码片段是用 Kotlin 编写的,在 Java 11 中产生令人满意的结果。但是,当使用 Java 17 执行时,相同的代码无法按预期运行。
fun main() { // Kotlin code
val date = Date(-1118625572000) //1934-07-21T22:40:28.000+00:00
println("Date: ${date.toInstant()?.atZone(ZoneId.of("Europe/Amsterdam"))!!.toLocalDate()}")
}
Run Code Online (Sandbox Code Playgroud)
Java 17 中是否有可用的解决方案来解决与这些类型的日期相关的问题?
我们尝试直接在数据库中更正这些记录,以确保有效日期的数量。
例如,
1934-07-21T22:40:28.000+00:00 --> 1934-07-22T00:00:00.000+00:00
1897-08-06T23:40:28.000+00:00 --> 1897-08-07T00:00:00.000+00:00
Run Code Online (Sandbox Code Playgroud)
然而,我们需要探索是否有一种方法可以在 Java 17 中专门处理这些类型的日期。
在我使用Microsoft OpenJDK升级到 Java 17 后,由于编码失败问题,所有使用非 ASCII 字符的测试都失败。
\n例如,我的一项测试使用以下 Unicode 字符(例如 U+2660 到 U+2663):
\nentityManager.persist(\n new Suit()\n .setName("Club")\n .setSymbol("\xe2\x99\xa3")\n);\n\nentityManager.persist(\n new Suit()\n .setName("Diamond")\n .setSymbol("\xe2\x99\xa6")\n);\n\nentityManager.persist(\n new Suit()\n .setName("Heart")\n .setSymbol("\xe2\x99\xa5")\n);\n\nentityManager.persist(\n new Suit()\n .setName("Spade")\n .setSymbol("\xe2\x99\xa0")\n);\nRun Code Online (Sandbox Code Playgroud)\n如何修复它?
\n我的任务是使用旧的 java 及其使用的库来升级旧的桌面应用rt.jar程序jfxrt.jar。我在网上搜索了有关库(rt.jar& jfxrt.jar)的信息,但显然,它在 Java 17 和 JavaFX 17 中不再存在。最新版本的 Java 17 和 JavaFX 17 的等效库是rt.jar什么?jfxrt.jar
我正在使用 IntelliJ IDEA 2021.2.3 ,JDK 17。我在 Java 17 中有代码片段
pom.xm
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>function_programming17</artifactId>
<version>1.0-SNAPSHOT</version>
<name>function_programming17</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, …Run Code Online (Sandbox Code Playgroud) 在将大型 JEE8 应用程序移植到 Java 17 时,我IllegalAccessException在渲染一个简单的 EL 表达式时偶然发现了一个:#{myWarBean.defaultTZ.rawOffset}。我设法在github 上的 SSCCE中重现了该问题。当您在 Wildfly 应用程序服务器(我使用的是 26.1.1.Final)上运行应用程序时,您会得到以下堆栈跟踪:
SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-1) Error Rendering View[/index.xhtml]: javax.el.ELException: /index.xhtml @23,74 value="raw offset=#{myWarBean.defaultTZ.rawOffset}": java.lang.IllegalAccessException: class javax.el.BeanELResolver cannot access class sun.util.calendar.ZoneInfo (in module java.base) because module java.base does not export sun.util.calendar to unnamed module @6a1cb0de
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:77)
at javax.faces.api@3.1.0.SP01//javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.api@3.1.0.SP01//javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:181)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIOutput.getValue(UIOutput.java:140)
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:198)
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:328)
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:143)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:600)
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:286)
at com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:90)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:571)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1648)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1651)
at javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1651) …Run Code Online (Sandbox Code Playgroud) 我想知道如何重写这个类
public class ClassA {
private final String foo;
private final String bar;
public ClassA(String foo) {
this.foo = foo;
this.bar = foo.toUpperCase();
}
// getters...
}
Run Code Online (Sandbox Code Playgroud)
作为记录类。
我能做到的最好的就是这个
public record ClassA(String foo, String bar) {
public ClassA(String foo) {
this(foo, foo.toUpperCase());
}
}
Run Code Online (Sandbox Code Playgroud)
问题是这个解决方案创建了两个构造函数,而我只想要一个接受字符串 foo 的构造函数
./mvnw clean package在 Docker 容器运行映像中运行命令时eclipse-temurin:17-jdk,出现以下错误(Maven 甚至不执行):
[0.002s][warning][os,thread] Failed to start thread "GC Thread#0" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create worker GC thread. Out of system resources.
# An error report file with more information is saved as:
# /home/myuser/hs_err_pid8.log
Run Code Online (Sandbox Code Playgroud)
文件中有更多信息hs_err_pid8.log:
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot …Run Code Online (Sandbox Code Playgroud) 我正在使用 Java 17,最后一行不应编译,但是当我使用 eclipse 时它会编译,现在我很困惑该值应该是子类型还是可以是任何东西?
Double value = 123.3;
if(value instanceof Double ) {}
if(value instanceof Double data) {} // DOES NOT COMPILE
Run Code Online (Sandbox Code Playgroud) 我已将我们公司应用程序的 Java 版本从 8 更新到 17。在本地计算机上,它在构建和运行时调用方面都运行良好。同样在 GitHub 上,它与 Junit 测试执行一起部署得很好。
问题是在我在 Heroku 上部署应用程序之后出现的。Heroku 构建成功,但在运行时,当我调用方法时,收到此错误:
"message": "Handler dispatch failed; nested exception is java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected a class type\n\tRemaining input: java/util/concurrent/CompletableFuture",
Run Code Online (Sandbox Code Playgroud)
它与java反射方法和方法的签名有关。我的控制器剩余方法返回一个 CompletableFuture 对象。CompletableFuture 有点不太好.........
有人可以告诉我 Java 17 接受最终表达式作为 switch-case-constructs 中的 case 表达式但不接受最终表达式作为参数传递的好处吗?
void test(int distinction, final int foo) {
final var bar = 2;
switch (distinction) {
case foo -> doSomething(); // does not compile -> case expressions must be constant expressions
case bar -> doSomething(); // does compile
case 3 -> doOtherThings(); // does compile
}
}
Run Code Online (Sandbox Code Playgroud)
尽管 foo 和 bar 一样是最终变量,为什么编译器不接受情况 1?
在我看来,案例 3 的可读性比案例 2 好得多。所以我没有看到新语言结构的好处。
java-17 ×10
java ×9
constructor ×1
docker ×1
eclipse ×1
el ×1
heroku ×1
java-module ×1
javafx ×1
javafx-17 ×1
jsf ×1
maven ×1
mongodb ×1
openjdk-17 ×1
record ×1
reflection ×1
timezone ×1
windows ×1