Hi,A short update on this. This is a known regression in more recent versions of Java: https://bugs.openjdk.org/browse/JDK-8226919
One of my colleagues (thanks, Sebastian!) managed to workaround this by patching the JDK 17 sources to make it use plain /tmp in this case (when ns_pid == pid), and also added some better error handling in case this fails.
We are currently working on getting this submitted upstream to OpenJDK, but I wanted to share it with you as well. One option would be to include this in Debian's set of local JDK patches (https://salsa.debian.org/openjdk-team/openjdk/-/tree/master/debian/patches), but I don't know how conservative the project is re. fixes like this? I'll leave this up to the debian-java maintainers to decide.
Best regards, Per
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -209,11 +209,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { } // Return the socket file for the given process. - private File findSocketFile(int pid, int ns_pid) { - // A process may not exist in the same mount namespace as the caller. - // Instead, attach relative to the target root filesystem as exposed by - // procfs regardless of namespaces. - String root = "/proc/" + pid + "/root/" + tmpdir; + private File findSocketFile(int pid, int ns_pid) throws IOException { + String root = findTargetProcessTmpDirectory(pid, ns_pid); return new File(root, ".java_pid" + ns_pid); } @@ -229,21 +226,33 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // Do not canonicalize the file path, or we will fail to attach to a VM in a container. f.createNewFile(); } catch (IOException x) { - String root; - if (pid != ns_pid) { - // A process may not exist in the same mount namespace as the caller. - // Instead, attach relative to the target root filesystem as exposed by - // procfs regardless of namespaces. - root = "/proc/" + pid + "/root/" + tmpdir; - } else { - root = tmpdir; - } + String root = findTargetProcessTmpDirectory(pid, ns_pid); f = new File(root, fn); f.createNewFile(); } return f; } + private String findTargetProcessTmpDirectory(int pid, int ns_pid) throws IOException { + String root; + if (pid != ns_pid) { + // A process may not exist in the same mount namespace as the caller. + // Instead, attach relative to the target root filesystem as exposed by + // procfs regardless of namespaces. + String procRootDirectory = "/proc/" + pid + "/root"; + if (!Files.isReadable(Path.of(procRootDirectory))) { + throw new IOException( + String.format("Unable to access root directory %s " + + "of target process %d", procRootDirectory, pid)); + } + + root = procRootDirectory + "/" + tmpdir; + } else { + root = tmpdir; + } + return root; + } + /* * Write/sends the given to the target VM. String is transmitted in * UTF-8 encoding.