Java 19 - FileChannelImpl.transferFrom0 - 函数未实现

Nic*_*aux 1 java linux maven java-19

我在使用 Java 19 的 Maven 插件时遇到错误。Java 18 运行良好。我该如何解决这个问题?

我在 Centos 7.9.2009 上的 Docker 容器中运行。当在 Ubuntu 20.0 - kernel 5.15.0-52-generic 上的同一容器中进行测试时,它可以正常工作。

堆栈跟踪如下。

Caused by: java.io.IOException: Function not implemented
Oct 28 12:12:49     at sun.nio.ch.FileChannelImpl.transferFrom0 (Native Method)
Oct 28 12:12:49     at sun.nio.ch.FileChannelImpl.transferFromDirectlyInternal (FileChannelImpl.java:804)
Oct 28 12:12:49     at sun.nio.ch.FileChannelImpl.transferFromDirectly (FileChannelImpl.java:833)
Oct 28 12:12:49     at sun.nio.ch.FileChannelImpl.transferFrom (FileChannelImpl.java:935)
Oct 28 12:12:49     at org.codehaus.plexus.util.FileUtils.doCopyFile (FileUtils.java:1077)
Oct 28 12:12:49     at org.codehaus.plexus.util.FileUtils.copyFile (FileUtils.java:1049)
Run Code Online (Sandbox Code Playgroud)

使用的版本

Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Java version: 19, vendor: Eclipse Adoptium, runtime: /opt/java/openjdk
OS name: "linux", version: "3.10.0-1160.76.1.el7.x86_64", arch: "amd64", family: "unix"
Run Code Online (Sandbox Code Playgroud)

Joa*_*uer 6

我很好奇,所以我深入研究了这个问题。看来我原来的评论是正确的:你的内核版本对于这个特定功能来说太早了:

  • FileChannelImpl.transferFrom0在这里实现
  • 它首先检查是否my_copy_file_range_func为非空,IOS_UNSUPPORTED否则返回(这可能是发生的情况)。
  • my_copy_file_range_func显然是通过查找符号在这里初始化的copy_file_range
  • 根据这个手册页,系统调用被添加到 Linux 内核 4.5 中,但从 2.27 开始由 glibc 在用户空间中模拟。

Linux 4.5 于 2016 年 3 月发布,glibc 2.27 于 2018 年 2 月发布。

由于 libc实际上由容器提供的,因此在使用它时(请注意,像 Alpine 这样基于 musl 的容器可能有其他要求),确保您的容器包含比 2.27 更新的 glibc 版本就足够了。

请注意,该函数的用户空间模拟不会提供真正的内核实现可以提供的零复制效率增益(即,它将比在更新的内核上运行慢)。