Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileSystemNotFoundException when init Graal in Springboot

I add graal libs in my project to execute JavaScript in Java. My project worked on spingboot framework.

compile group: 'org.graalvm.sdk', name: 'graal-sdk', version: '1.0.0-rc9'
compile group: 'org.graalvm.js', name: 'js', version: '1.0.0-rc9'
compile group: 'org.graalvm.js', name: 'js-scriptengine', version: '1.0.0-rc9'
compile group: 'org.graalvm.tools', name: 'profiler', version: '1.0.0-rc9'
compile group: 'org.graalvm.tools', name: 'chromeinspector', version: '1.0.0-rc9'
compile group: 'org.graalvm.truffle', name: 'truffle-api', version: '1.0.0-rc9'
  1. If I run my project with "gradle bootRun" or IDEA directly, graal init success and work fine;
  2. If I buid my project to a fat jar, which contains all libs in it, graal init failed and throw a FileSystemNotFoundException.

    java.nio.file.FileSystemNotFoundException: null
    at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:169)
    at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:155)
    at java.base/java.nio.file.Paths.get(Paths.java:143)
    at com.oracle.truffle.polyglot.LanguageCache.collectLanguages(LanguageCache.java:284)
    at com.oracle.truffle.polyglot.LanguageCache.createLanguages(LanguageCache.java:211)
    at com.oracle.truffle.polyglot.LanguageCache.languages(LanguageCache.java:201)
    at com.oracle.truffle.polyglot.PolyglotEngineImpl.initializeLanguages(PolyglotEngineImpl.java:480)
    at com.oracle.truffle.polyglot.PolyglotEngineImpl.<init>(PolyglotEngineImpl.java:168)
    at com.oracle.truffle.polyglot.PolyglotEngineImpl.<init>(PolyglotEngineImpl.java:152)
    at com.oracle.truffle.polyglot.PolyglotImpl.buildEngine(PolyglotImpl.java:197)
    at org.graalvm.polyglot.Engine$Builder.build(Engine.java:488)
    at org.graalvm.polyglot.Context$Builder.build(Context.java:1083)
    at org.graalvm.polyglot.Context.create(Context.java:660)
    at ocpm.pcf.policyengine.engine.cache.JavaScriptPolicyParser.graalParse(JavaScriptPolicyParser.java:48)
    

I debug the ponit in exception stack, and found that graal want to init "lauguage" configuration file in js-1.0.0-rc9.jar. But in the above scenarios, it used different URI schema.

 - In the first scenario, the URI is "jar:file:/C:/Users/texu/.gradle/caches/modules-2/files-2.1/org.graalvm.js/js/1.0.0-rc9/25f41dd171dfa5c5921bc1f6bbdf7860279fc43c/js-1.0.0-rc9.jar!/META-INF/truffle/language", which is a normal file path; 
 - In the second scenario, the URI is "jar:file:/app/policy-engine.jar!/BOOT-INF/lib/js-1.0.0-rc9.jar!/META-INF/truffle/language", which is a path of nested jar.

So, how can I init graal in springboot fat jar?

like image 599
texu Avatar asked Nov 28 '18 04:11

texu


People also ask

Does the Spring Framework support GraalVM Native Images?

Starting from Spring Framework 5.1, initial support for GraalVM native images was provided . The 5.2 development cycle is focusing on improving the integration and full support without requiring extra configuration or workarounds is one of the themes of the upcoming Spring Framework 5.3 release.

Why do I get a filenotfoundexception when I run the code?

So when the code executes, we'll see the FileNotFoundException. Even if we changed the path to /input.txt the original code could not load this file as resources are not usually addressable as files on disk. The resource files are packaged inside the JAR and so we need a different way of accessing them. 4. Resources

What is init method in Spring Boot?

In the real-world application init () method is the one you will find it everywhere. init-method is the attribute of the spring <bean> tag. It is utilized to declare a custom method for the bean that will act as the bean initialization method.

What is the use of initialization Bean in Spring Boot?

This initialization method is called after initializing bean properties. We can use such an initialization method to validate the value of bean properties or initialize any task. The InitializingBean interface in spring performs the same task but it is highly coupled to spring, so we should prefer the init-method.


1 Answers

As a workaround, I unpack graal related libs from fat jar, which is support by springboot. Then graal init successed. In runtime env, path of unpacked libs look like this:

/tmp/policy-engine.jar-spring-boot-libs-19affd93-0dd2-451a-b469-75fe0c4f458d/js-scriptengine-1.0.0-rc9.jar
/tmp/policy-engine.jar-spring-boot-libs-19affd93-0dd2-451a-b469-75fe0c4f458d/js-1.0.0-rc9.jar

In my project's build.gradle, below part need be added

bootJar {
    requiresUnpack '**/js-*.jar'
    requiresUnpack '**/regex-*.jar'
    requiresUnpack '**/truffle-api-*.jar'
    requiresUnpack '**/graal-sdk-*.jar'
}

More details ref: https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/gradle-plugin/reference/html/#packaging-executable-configuring-unpacking

like image 64
texu Avatar answered Oct 27 '22 10:10

texu