Home > Enterprise >  Java 19 - FileChannelImpl.transferFrom0 - Function not implemented
Java 19 - FileChannelImpl.transferFrom0 - Function not implemented

Time:10-29

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"

CodePudding user response:

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 returns IOS_UNSUPPORTED otherwise (which is probably what happens).
  • my_copy_file_range_func is apparently initialized here by looking for the symbol copy_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).

  • Related