最小 Graal 多语言示例将无法运行

问题描述 投票:0回答:2

我正在尝试运行一个非常简单的 GraalVM 示例,但遇到了困难。

我只是想使用 JavaScript 将两个值相加。

package com.example;

import org.graalvm.polyglot.*;

public final class App {
    private App() {
    }

    public static void main(String[] args) {

        System.out.println( "starting up" );

        try ( Context context = Context.create() ){
            Value val = context.eval( "js", "10 + 2" );

            System.out.println( val.asInt() );
        }
        catch( Exception e ){
            System.out.println( e );
        }
    
        System.out.println("Hello World!");
    }
}

程序编译得很好,但是当我运行它时,我得到以下输出。

starting up
[WARNING] 
java.lang.ExceptionInInitializerError
    at org.graalvm.polyglot.Engine.getImpl (Engine.java:438)
    at org.graalvm.polyglot.Engine$Builder.build (Engine.java:736)
    at org.graalvm.polyglot.Context$Builder.build (Context.java:1925)
    at org.graalvm.polyglot.Context.create (Context.java:979)
    at com.example.App.main (App.java:13)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:840)
Caused by: java.nio.file.InvalidPathException: Illegal char <:> at index 2: /C:/Users/jacob/Dev/cfwasmer/cfwasmjava/cfwasm/target/classes/
    at sun.nio.fs.WindowsPathParser.normalize (WindowsPathParser.java:182)
    at sun.nio.fs.WindowsPathParser.parse (WindowsPathParser.java:153)
    at sun.nio.fs.WindowsPathParser.parse (WindowsPathParser.java:77)
    at sun.nio.fs.WindowsPath.parse (WindowsPath.java:92)
    at sun.nio.fs.WindowsFileSystem.getPath (WindowsFileSystem.java:232)
    at java.nio.file.Path.of (Path.java:147)
    at org.graalvm.polyglot.Engine$ClassPathIsolation.collectClassPathJars (Engine.java:1988)
    at org.graalvm.polyglot.Engine$ClassPathIsolation.createIsolatedTruffleModule (Engine.java:1783)
    at org.graalvm.polyglot.Engine$ClassPathIsolation.createIsolatedTruffle (Engine.java:1723)
    at org.graalvm.polyglot.Engine$1.searchServiceLoader (Engine.java:1682)
    at org.graalvm.polyglot.Engine$1.run (Engine.java:1668)
    at org.graalvm.polyglot.Engine$1.run (Engine.java:1663)
    at java.security.AccessController.doPrivileged (AccessController.java:318)
    at org.graalvm.polyglot.Engine.initEngineImpl (Engine.java:1663)
    at org.graalvm.polyglot.Engine$ImplHolder.<clinit> (Engine.java:186)
    at org.graalvm.polyglot.Engine.getImpl (Engine.java:438)
    at org.graalvm.polyglot.Engine$Builder.build (Engine.java:736)
    at org.graalvm.polyglot.Context$Builder.build (Context.java:1925)
    at org.graalvm.polyglot.Context.create (Context.java:979)
    at com.example.App.main (App.java:13)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:840)

由于程序打印出“正在启动”,我知道它正在部分执行。当我不尝试访问任何文件时,为什么它会抱怨文件路径?我如何让它运行我的 JavaScript 代码?

编辑: 我刚刚尝试在 docker 容器中运行我的示例,并且程序正确执行。我最初的测试是在 Windows 中进行的。多语言可以在 Windows 上使用吗?我需要做一些事情来配置我的环境吗?

java graalvm
2个回答
0
投票

我认为您缺少上一个版本中引入的更改。现在所有语言都是 Maven 依赖项,你可以这样:

<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <artifactId>polyglot</artifactId> 
    <version>23.1.0</version> 
</dependency>
<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <artifactId>js</artifactId> 
    <version>23.1.0</version> 
    <type>pom</type>
</dependency>

然后你可以像这样使用它们

package org.example.embedding;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;

import java.io.IOException;
import java.nio.file.Files;
import java.util.Set;


public class Main {

    public static void main(String[] args) throws IOException {
        try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
            Set<String> languages = context.getEngine().getLanguages().keySet();
            for (String id : languages) {
                System.out.println("Initializing language " + id);
                context.initialize(id);
                switch (id) {
                    case "python":
                        context.eval("python", "print('Hello Python!')");
                        break;
                    case "js":
                        context.eval("js", "print('Hello JavaScript!');");
                        break;
                    case "ruby":
                        context.eval("ruby", "puts 'Hello Ruby!'");
                        break;
                    case "wasm":
                        // with wasm we compute factorial
                        context.eval(Source.newBuilder("wasm", Main.class.getResource("factorial.wasm")).build());
                        Value factorial = context.getBindings("wasm").getMember("main").getMember("fac");
                        System.out.println("wasm: factorial(20) = " + factorial.execute(20L));
                        break;
                    case "java":
                        // with Java we invoke System.out.println reflectively.
                        Value out = context.getBindings("java").getMember("java.lang.System").getMember("out");
                        out.invokeMember("println", "Hello Espresso Java!");
                        break;
                }
            }
        }
    }
}

您可以查看 https://github.com/graalvm/polyglot-embedding-demo 获取完整示例。


0
投票

这个问题最初是我们的类路径隔离中的一个错误,仅在 Windows 上触发。该错误已在 23.1.1 中修复,但在 23.1.2 中,类路径隔离代码也消失了,因此您应该不再遇到任何问题。

换句话说,只需使用这些依赖项即可:

<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <artifactId>polyglot</artifactId> 
    <version>23.1.2</version> 
</dependency>
<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <artifactId>js</artifactId> 
    <version>23.1.2</version> 
    <type>pom</type>
</dependency>
© www.soinside.com 2019 - 2024. All rights reserved.