JDK-8202289 : Non-empty directory in module path is not handled properly at CDS/AppCDS dump time
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-04-26
  • Updated: 2018-06-05
  • Resolved: 2018-05-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11
11 b14Fixed
Related Reports
Relates :  
Description
CDS/AppCDS does not support archiving classes from directory. At dump time, non-empty directory in -Xbootclasspath/a path and -cp path is being detected and reported as a fatal error. However, it seems non-empty directory in module path is not reported at dump time.

Module classes in directory from --module-path are loaded at dump time, however the shared path index for those classes are not set correctly. The index values are -1 for those classes. As a result, theose archived classes cannot be used at runtime.


Comments
If there an extra-long path that might cause failure of canonize(), the failure happens before the CDS recording code is reached. So get_canonical_path() in record_result() should not see a failure caused by extra-long path. However, I agree it is still safer to check the result of get_canonical_path() and report fatal error.
10-05-2018

It would be difficult to test the failure case of get_canonical_path() like in the following code: if (!get_canonical_path(path, canonical_class_src_path, JVM_MAXPATHLEN)) { tty->print_cr("Bad pathname %s. CDS dump aborted.", path); vm_exit(1); } Attached test case attempts to test a -cp path which will expand to longer than 4096 chars. But it fails in the following: Files.copy(jarPath, longDirJar); Failed. Execution failed: `main' threw exception: java.nio.file.FileSystemException: <long path>/hello.jar: File name too long Running it via command line such as: java -cp <long path>/hello.jar -Xshare:dump -XX:ExtraSharedClassListFile=/tmp/my.classlist -XX:SharedArchiveFile=/tmp/calvin.jsa -Xlog:class+load -Xlog:exceptoin=trace The following exception was captured in a log: [0.154s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}> (0x0000000464250190) thrown [<repo top dir>/open/src/hotspot/share/prims/jni.cpp, line 615] for thread 0x00007f9a280195f0 [0.155s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}: File name too long> thrown in interpreter method <{method} {0x00007f99e96407e0} 'canonicalize0' '(Ljava/lang/String;)Ljava/lang/String;' in 'java/io/UnixFileSystem'> at bci 0 for thread 0x00007f9a280195f0 (main) [0.155s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}: File name too long> thrown in interpreter method <{method} {0x00007f99e9640718} 'canonicalize' '(Ljava/lang/String;)Ljava/lang/String;' in 'java/io/UnixFileSystem'> at bci 140 for thread 0x00007f9a280195f0 (main) [0.155s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}: File name too long> thrown in interpreter method <{method} {0x00007f99e9500df8} 'getCanonicalPath' '()Ljava/lang/String;' in 'java/io/File'> at bci 27 for thread 0x00007f9a280195f0 (main) [0.155s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}: File name too long> thrown in interpreter method <{method} {0x00007f99e9500ef0} 'getCanonicalFile' '()Ljava/io/File;' in 'java/io/File'> at bci 1 for thread 0x00007f9a280195f0 (main) [0.155s][info][exceptions] Exception <a 'java/io/IOException'{0x0000000464250190}: File name too long> thrown in interpreter method <{method} {0x00007f99e96ae6f8} 'toFileURL' '(Ljava/lang/String;)Ljava/net/URL;' in 'jdk/internal/loader/URLClassPath'> at bci 8 for thread 0x00007f9a280195f0 (main) So it seems jdk tried to canonicalize the path but failed. Substituting the above -cp arg with a directory containing the class file also resulting in the above exception. Since the jar or the class file cannot be found, the app class cannot be loaded: [0.455s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x00000004643fee48}: Hello> thrown in interpreter method <{method} {0x00007f99e9510690} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/BuiltinClassLoader'> at bci 19 for thread 0x00007f9a280195f0 (main) [0.455s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x00000004643fee48}: Hello> thrown in interpreter method <{method} {0x00007f99e950cd50} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/ClassLoaders$AppClassLoader'> at bci 36 for thread 0x00007f9a280195f0 (main) [0.455s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x00000004643fee48}: Hello> thrown in interpreter method <{method} {0x00007f99e943bb78} 'loadClass' '(Ljava/lang/String;)Ljava/lang/Class;' in 'java/lang/ClassLoader'> at bci 3 for thread 0x00007f9a280195f0 (main)
10-05-2018