Issue
I have an error using a Maven plugin with Java 19 specifically. Java 18 is working fine. How could I solve this issue?
I'm running within a Docker container on Centos 7.9.2009. When testing within the same container on Ubuntu 20.0 - kernel 5.15.0-52-generic, it works without issue.
The stacktrace is the following.
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)
Versions used
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"
Solution
I was curious so I dug into the matter. It seems my original comment is right: your kernel version is too early for this specific function:
FileChannelImpl.transferFrom0
is implemented here- it first checks if
my_copy_file_range_func
is non-null and returnsIOS_UNSUPPORTED
otherwise (which is probably what happens). my_copy_file_range_func
is apparently initialized here by looking for the symbolcopy_file_range
.- According to this man page that system call was added to the Linux kernel 4.5, but is emulated in userspace by glibc since 2.27.
Linux 4.5 was released in March 2016 and glibc 2.27 in February 2018.
Since the libc is in fact provided by the container, when it's used (note that a musl-based container like Alpine might have other requirements) it should be sufficient to make sure that your container contains a glibc version that's newer than 2.27.
Note that a userspace emulation of that function will not provide the zero-copy efficiency gain that a real kernel implementation can provide (i.e. it will be slower than running on a more recent kernel).
Answered By - Joachim Sauer
Answer Checked By - David Marino (JavaFixing Volunteer)