I add graal libs in my project to execute JavaScript in Java. My project worked on spingboot framework.
Java Jdk: 9.0.4
spingboot: 2.1.5.RELEASE
graalvm.version : 19.0.0
<dependency> <groupId>org.graalvm.js</groupId> <artifactId>js-scriptengine</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.sdk</groupId> <artifactId>graal-sdk</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.tools</groupId> <artifactId>chromeinspector</artifactId> <version>${graalvm.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.graalvm.tools</groupId> <artifactId>profiler</artifactId> <version>${graalvm.version}</version> </dependency>
If I run my project with IDEA directly, graal init success and work fine;
If I buid my project to a fat jar, which contains all libs in it, graal init failed and throw a FileSystemNotFoundException.
at jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem(Unknown Source) ~[jdk.zipfs:?]
at jdk.nio.zipfs.ZipFileSystemProvider.getPath(Unknown Source) ~[jdk.zipfs:?]
at java.nio.file.Paths.get(Unknown Source) ~[?:?]
at com.oracle.truffle.polyglot.LanguageCache.collectLanguages(LanguageCache.java:328) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.LanguageCache.createLanguages(LanguageCache.java:246) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.LanguageCache.languages(LanguageCache.java:236) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.PolyglotEngineImpl.languages(PolyglotEngineImpl.java:548) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.PolyglotEngineImpl.initializeLanguages(PolyglotEngineImpl.java:496) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.PolyglotEngineImpl.(PolyglotEngineImpl.java:190) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.PolyglotEngineImpl.(PolyglotEngineImpl.java:172) ~[truffle-api-19.0.0.jar!/:?]
at com.oracle.truffle.polyglot.PolyglotImpl.buildEngine(PolyglotImpl.java:214) ~[truffle-api-19.0.0.jar!/:?]
at org.graalvm.polyglot.Engine$Builder.build(Engine.java:505) ~[graal-sdk-19.0.0.jar!/:?]
at org.graalvm.polyglot.Context$Builder.build(Context.java:1304) ~[graal-sdk-19.0.0.jar!/:?]
at org.graalvm.polyglot.Context.create(Context.java:697) ~[graal-sdk-19.0.0.jar!/:?]
Hi @JoshuaChen
thanks for your report. I have not seen that specific failure, we had reports of troubles with fat jars before, e.g. https://github.com/graalvm/graaljs/issues/125 or https://github.com/graalvm/graaljs/issues/135
Can you please check if this might be similar?
Best,
Christian
I also have exact similar situation as mentioned by @JoshuaChen , instead of unknown source , i got
java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)
at com.oracle.truffle.polyglot.LanguageCache.collectLanguages(LanguageCache.java:328)
at com.oracle.truffle.polyglot.LanguageCache.createLanguages(LanguageCache.java:246)
at com.oracle.truffle.polyglot.LanguageCache.languages(LanguageCache.java:236)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.languages(PolyglotEngineImpl.java:548)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.initializeLanguages(PolyglotEngineImpl.java:496)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.
at com.oracle.truffle.polyglot.PolyglotEngineImpl.
at com.oracle.truffle.polyglot.PolyglotImpl.buildEngine(PolyglotImpl.java:214)
at org.graalvm.polyglot.Engine$Builder.build(Engine.java:505)
at com.oracle.truffle.js.scriptengine.GraalJSEngineFactory.
@wirthi
Thanks, "using the classpath" can work, but that's not a good solution. I don't want to use it.
I have further debugged issue of Jar and found issue with following jar
dummy-9.0.0-SNAPSHOT.jar!/BOOT-INF/lib/js-19.0.0.jar
Yes, the issue is probably that the path to the js-19.0.0.jar lies inside the fat jar. This causes an error when trying to retrieve the filesystem path.
We have the exact same issue with a Spring Boot application.
@wirthi
I'm facing a similar issue. Spring Boot Application works ok when started from IDE, but once I package application and run inside docker (openjdk:8u111-jdk-alpine) I get FileSystemNotFoundException see error log below.
@chumer based on your comment on https://github.com/graalvm/graaljs/issues/125, please when can we expect a fix on this issue?
springBootVersion: 2.1.5.RELEASE
graalVersion: 19.0.0
Dependencies: graal-sdk, truffle-api, js, js-scriptengine
java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171) ~[zipfs.jar:1.8.0_111-internal]
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157) ~[zipfs.jar:1.8.0_111-internal]
at java.nio.file.Paths.get(Paths.java:143) ~[na:1.8.0_111-internal]
at com.oracle.truffle.polyglot.LanguageCache.collectLanguages(LanguageCache.java:328) ~[truffle-api-19.0.0.jar!/:na]
at com.oracle.truffle.polyglot.LanguageCache.createLanguages(LanguageCache.java:246) ~[truffle-api-19.0.0.jar!/:na]
Hi all,
@pszalanski @chineduekwunife I'm facing the same problem on Springboot, in my case, using JS-19.1.1.
@JoshuaChen I actually tried the "classpath" approach and unfortunately it did not work. I got this error java.lang.NoClassDefFoundError: com/ibm/icu/text/DateFormat, even when I run it using my IDE, I need to investigate further.
I also tried the approach mentioned here but I didn't success. It runs in my IDE but as soon as I generate the jar, run it and the application hits the GraalJS code, the java.nio.file.FileSystemNotFoundException: null is thrown.
In case it is relevant, I created a tiny poc using springboot and GraalJS libraries here, I'm using OpenSDK11.
I had the same problem with a spring boot application.
This is my solution:
try {
URL res = com.oracle.js.parser.ScriptEnvironment.class.getClassLoader().getResource("/META-INF/truffle/language");
// initialize the file system for the language file
FileSystems.newFileSystem(res.toURI(), new HashMap<>());
} catch (Throwable ignored) {
// in case of starting without fat jar
}
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
That works for me with OpenJDK8 and 11 with the spring-boot-maven-plugin
The POM i used for testing:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>graal-js-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<graalvm.version>19.1.1</graalvm.version>
</properties>
<dependencies>
<!--
graalvm
-->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>${graalvm.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<!-- 1.8 works as well -->
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<folders>
<folder>
graalvm
</folder>
</folders>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
test.graaltest.MainApp
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Thanks @xarfai I tried on my POC and it worked
The System property for language home is unset, the code determining the language home using jar location should be more robust.
It seems that the jar is packed in ear (war) and the JarURLConnection.getJarFileURL is pointing into archive file.
Also experiencing this java.nio.file.FileSystemNotFoundException: null on 19.2.0 in a fat jar spring boot app.
@xarfai 's workaround also worked for me as well.
Fixed by: https://github.com/oracle/graal/commit/42180c5d084e5c8f413e90c98280c7f83e1163a8.
Targeted into GraalVM 20.0.
Regarding the workaround it's better to use the System.setProperty("js.home",<some_path>) as
the ScriptEnvironment.class.getClassLoader().getResource("/META-INF/truffle/language") will not work in GraalVM 19.3 which uses ServiceLoader based language registration.
@tzezula does that also mean your suggested new workaround would not work until using 19.3?
@tzezula What is the current workaround code in order to get this running with 19.3.0? Where is js.home coming from and being read?
@xarfai workaround helped me find the solution (thank you!). Debugged and found out in 19.3.1 that the path is different to get the JS jar.
/BOOT-INF/lib/js-19.3.1.jar!/com/oracle/truffle/js/lang/JavaScriptLanguage
Just provide the string /com/oracle/truffle/js/lang/JavaScriptLanguage.class instead of /META-INF/truffle/language.
try {
URL res = com.oracle.js.parser.ScriptEnvironment.class.getClassLoader().getResource("/com/oracle/truffle/js/lang/JavaScriptLanguage.class");
// initialize the file system for the language file
FileSystems.newFileSystem(res.toURI(), new HashMap<>());
} catch (Throwable ignored) {
// in case of starting without fat jar
}
Otherwise I was in the same boat and had to downgrade my graalvm dependencies to 19.2.1. Hope this helps.
Most helpful comment
Fixed by: https://github.com/oracle/graal/commit/42180c5d084e5c8f413e90c98280c7f83e1163a8.
Targeted into GraalVM 20.0.
Regarding the workaround it's better to use the
System.setProperty("js.home",<some_path>)asthe
ScriptEnvironment.class.getClassLoader().getResource("/META-INF/truffle/language")will not work in GraalVM 19.3 which usesServiceLoaderbased language registration.