oracle / graaljs

GraalJS – A high-performance, ECMAScript compliant, and embeddable JavaScript runtime for Java
https://www.graalvm.org/javascript/
Universal Permissive License v1.0
1.82k stars 191 forks source link

Wildcards in classpath do not work anymore #834

Open j-ulrich opened 4 months ago

j-ulrich commented 4 months ago

It seems that since GraalJS 22.x, wildcards in the classpath do not work anymore.

Before (21.x), I got this behavior:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.3.1/Contents/Home/bin/js --version
GraalVM JavaScript (GraalVM CE Native 21.3.3.1)
$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.3.1/Contents/Home/bin/js --jvm "--vm.cp=/tmp/jackson/*" --vm.Dpolyglot.js.load-from-classpath=true --vm.Dpolyglot.js.load-from-url=true
> Java.type("com.fasterxml.jackson.core.JsonParser")
JavaClass[com.fasterxml.jackson.core.JsonParser]

with any later version (tested with 22.3.3, 23.0.2 and 24.0.1), I get this:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/bin/js --version
GraalVM JavaScript (GraalVM CE Native 22.3.3)
$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/bin/js --jvm "--vm.cp=/tmp/jackson/*" --vm.Dpolyglot.js.load-from-classpath=true --vm.Dpolyglot.js.load-from-url=true
> Java.type("com.fasterxml.jackson.core.JsonParser")
TypeError: Access to host class com.fasterxml.jackson.core.JsonParser is not allowed or does not exist.
    at <js> :program(<shell>:1:1:0-49)

Java.addToClasspath() with a wildcard does not work either:

> Java.addToClasspath("/tmp/jackson/*")
> Java.type("com.fasterxml.jackson.core.JsonParser")
TypeError: Access to host class com.fasterxml.jackson.core.JsonParser is not allowed or does not exist.
    at <js> :program(<shell>:3:1:0-49)


However, listing the jar files explicitly works:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/bin/js --jvm "--vm.cp=/tmp/jackson/jackson-core-2.17.2.jar" --vm.Dpolyglot.js.load-from-classpath=true --vm.Dpolyglot.js.load-from-url=true
> Java.type("com.fasterxml.jackson.core.JsonParser")
JavaClass[com.fasterxml.jackson.core.JsonParser]


It seems that before 22.x, the wildcard was expanded at some point:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.3.1/Contents/Home/bin/js --jvm "--vm.cp=/tmp/jackson/*" --vm.Dpolyglot.js.load-from-classpath=true --vm.Dpolyglot.js.load-from-url=true
> java.lang.System.getProperty("java.class.path")
/Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.3.1/Contents/Home/lib/graalvm/graaljs-launcher.jar:/Library/Java/JavaVirtualMachines/graalvm-ce-java17-21.3.3.1/Contents/Home/lib/graalvm/launcher-common.jar:/tmp/jackson/jackson-core-2.17.2.jar

After 22.x, the wildcard appears in the classpath as-is:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/bin/js --jvm "--vm.cp=/tmp/jackson/*" --vm.Dpolyglot.js.load-from-classpath=true --vm.Dpolyglot.js.load-from-url=true                      
> java.lang.System.getProperty("java.class.path")
/Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/languages/js/bin/../../../lib/graalvm/graaljs-launcher.jar:/Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/languages/js/bin/../../../lib/graalvm/launcher-common.jar:/tmp/jackson/*


It does not seem to be a problem with GraalVM in general because when printing out the java.class.path in a Java program, it still gets expanded (the program simply prints java.lang.System.getProperty("java.class.path")):

$ /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.3/Contents/Home/bin/java -cp '.:/tmp/jackson/*' GraalClassLoadTest
.:/tmp/jackson/jackson-core-2.17.2.jar
$ /Library/Java/JavaVirtualMachines/graalvm-jdk-17.0.11+7.1/Contents/Home/bin/java -cp '.:/tmp/jackson/*' GraalClassLoadTest
.:/tmp/jackson/jackson-core-2.17.2.jar
j-ulrich commented 4 months ago

Tested it on macOS and in GraalVM Docker containers.

woess commented 2 months ago

Confirmed. I think this was caused by the switch to thin language launchers. It was kind of working by accident before.

You can work around it by doing the expansion yourself (via command line (shell) or Java.addToClasspath + host interop). Or you could try to use module path.

We'll probably implement launcher support for this eventually, but it's not a priority for us right now.