java (and javac) are defined to treat empty path elements in -classpath as ".".
It looks like there is a regression in JDK 9 such that a trailing empty path element is lost (and thus not treated as ".").
This was detected by resuscitating the javac test
langtools/test/tools/javac/Paths/MineField.sh
which has been disabled for a while during Jigsaw development. (Sigh).
Here is a very stripped down version that demonstrates the bug:
----------------------------------
#!/bin/sh
JDK=/opt/jdk/1.9.0
mkdir -p MyDir
echo 'public class Lib {public static void f(){}}' > Lib.java
$JDK/bin/javac -d MyDir Lib.java
echo 'public class Main {public static void main(String[] a) {Lib.f();}}' > Main.java
$JDK/bin/javac -cp MyDir Main.java
cd MyDir
$JDK/bin/java -cp ..: Main
----------------------------------
Here is the result of running the script:
$ sh -x Bug.sh
+ JDK=/opt/jdk/1.9.0
+ mkdir -p MyDir
+ echo public class Lib {public static void f(){}}
+ /opt/jdk/1.9.0/bin/javac -d MyDir Lib.java
+ echo public class Main {public static void main(String[] a) {Lib.f();}}
+ /opt/jdk/1.9.0/bin/javac -cp MyDir Main.java
+ cd MyDir
+ /opt/jdk/1.9.0/bin/java -cp ..: Main
Exception in thread "main" java.lang.NoClassDefFoundError: Lib
at Main.main(Main.java:1)
Caused by: java.lang.ClassNotFoundException: Lib
at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base@9-ea/BuiltinClassLoader.java:366)
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base@9-ea/ClassLoaders.java:184)
at java.lang.ClassLoader.loadClass(java.base@9-ea/ClassLoader.java:419)
... 1 more
If you edit the script to run JDK 8, you get the following output (i.e. no error, as expected)
$ sh -x Bug.sh
+ JDK=/opt/jdk/1.8.0
+ mkdir -p MyDir
+ echo public class Lib {public static void f(){}}
+ /opt/jdk/1.8.0/bin/javac -d MyDir Lib.java
+ echo public class Main {public static void main(String[] a) {Lib.f();}}
+ /opt/jdk/1.8.0/bin/javac -cp MyDir Main.java
+ cd MyDir
+ /opt/jdk/1.8.0/bin/java -cp ..: Main