简体   繁体   English

使用 ES6 模块导入时 GraalVM 上下文中的错误

[英]Error in GraalVM Context when using ES6 module imports

I'm attempting to use GraalVM version 20.1.0 for Java 8 (graalvm-ce-java8-windows-amd64-20.1.0) to run some ES6 JavaScript from within Java. I'm attempting to use GraalVM version 20.1.0 for Java 8 (graalvm-ce-java8-windows-amd64-20.1.0) to run some ES6 JavaScript from within Java. I'm using Context like this:我正在使用这样的Context

try (final Context jsContext = Context.newBuilder("js").allowAllAccess(true).build()) {
    final URL resource = this.getClass().getClassLoader().getResource("index.js");
    final File file = Paths.get(resource.toURI()).toFile();
    final Source source = Source.newBuilder("js", file).mimeType("application/javascript+module").build();
    final Value value = jsContext.eval(source);

    System.out.println(value);
} catch (final IOException e) {
    e.printStackTrace();
} catch (final URISyntaxException e) {
    e.printStackTrace();
}

The JS files I'm using look like this:我正在使用的 JS 文件如下所示:

// index.js
import testFn from "./testFn";
testFn; // return value to Java

// testFn.js
function testFn() {
    print("Test!");
}

export default testFn;

Running this I get the very undescriptive error `运行这个我得到非常难以描述的错误`

Exception in thread "main" Error: C:/path/to/testFn.js
    at org.graalvm.polyglot.Context.eval(Context.java:345)
    // This error points to "final Value value = jsContext.eval(source);" in the Java code

However if I run testFn.js directly by replacing index.js with testFn.js in the Java code it works fine, It also works fine if I remove the import.但是,如果我通过在 Java 代码中将index.js替换为testFn.js直接运行testFn.js ,它可以正常工作,如果我删除导入它也可以正常工作。 so I assume something is buggy with ES6 imports.所以我认为 ES6 导入有问题。 Renaming the files to use *.mjs extension makes no difference.重命名文件以使用*.mjs扩展名没有区别。 Adding allowIO(true) to the Context config also changes nothing.allowIO(true)添加到Context配置也不会改变任何内容。

All of the code above is a MVCE that you can test, if needed.上面的所有代码都是一个 MVCE,如果需要,您可以对其进行测试。


I get the same error if I try to import a non-existent file as well ( import "./asdasd" ) so perhaps it's just not finding the file.如果我也尝试导入一个不存在的文件( import "./asdasd" ),我会得到同样的错误,所以它可能只是找不到文件。 Although I have double-checked that the file exists in the directory it lists so perhaps that's just a coincidence.尽管我已经仔细检查了该文件是否存在于它列出的目录中,所以这可能只是一个巧合。

You need to specify the file extension when importing in GraalVM :GraalVM中导入时需要指定文件扩展名:

import testFn from "./testFn.js"; // needs '.js' after file name!
testFn;

Note that the index file itself needs to have either the .mjs file extension, not .js , OR you need to use .mimeType("application/javascript+module") for imports to work.请注意,索引文件本身需要具有.mjs文件扩展名,而不是.js或者您需要使用.mimeType("application/javascript+module")才能进行导入。 The files you import, however, do not need a specific file extension.但是,您导入的文件不需要特定的文件扩展名。

I have identified this as a bug and have made a bug report here .我已将此确定为错误,并已在此处提交错误报告 Future readers check the link to see if this bug has been fixed.未来的读者检查链接以查看此错误是否已修复。

As I see (but not perfectly sure), GraalVM's Context.eval(Source source) method works the same way how JavaScript's eval() function does.正如我所见(但不完全确定),GraalVM 的Context.eval(Source source)方法的工作方式与 JavaScript 的eval() function 的工作方式相同。

That can cause the problem, as JS eval always treats its input as a Script, not as a Module, and static import s are allowed only inside Modules.这可能会导致问题,因为 JS eval总是将其输入视为脚本,而不是模块,并且 static import只允许在模块内部。

You could try to use the dynamic await import('./testFn') syntax instead, which is allowed inside Scripts as well (if GraalVM supports it), but unfortunately I can't tell if it will work, and I don't know how to pass back asynchronous resources to Java.您可以尝试使用动态await import('./testFn')语法,这在脚本中也是允许的(如果 GraalVM 支持它),但不幸的是我不知道它是否会工作,而且我不知道知道如何将异步资源回传给 Java。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM