我正在尝试将 Java 项目中的 Python 脚本执行从 Jython 迁移到 GraalVM Polyglot。我面临的问题是我不知道如何使我的 Java 类对于从这些 Python 脚本的导入可见。以下 JUnit 测试表明该脚本与 Jython 配合良好,但不适用于 GraalVM Pythong 支持:
package org.my.graalvm.python.issue;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.junit.jupiter.api.Test;
public class GraalVmPythonTests {
static final String SCRIPT = """
import org.my.graalvm.python.issue.GraalVmPythonTests.MyData as MyData
result=MyData('some data')
""";
@Test
void runPythonScriptWithJavaImportOnJython() throws ScriptException {
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("python");
Bindings bindings = new SimpleBindings();
scriptEngine.eval(SCRIPT, bindings);
System.out.println(bindings.get("result"));
}
@Test
void runPythonScriptWithJavaImportOnGraalVmPolyglot() {
try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
Source source = Source.create("python", SCRIPT);
Object result = context.eval(source).as(Object.class);
System.out.println(result);
}
}
public record MyData(String value) {
}
}
该项目的依赖项是:
dependencies {
testImplementation 'org.python:jython-standalone:2.7.4'
testImplementation 'org.graalvm.sdk:graal-sdk:24.0.2'
testImplementation 'org.graalvm.polyglot:python:24.0.2'
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.1'
}
根据官方 GraalVM docs,我们可以使用一些
--python.EmulateJython
命令行参数。但我不确定如何从 JUnit 测试中通过它。另外,由于我们完全放弃 Jython,因此感觉这个选项不太合适,因此预计会有一些更流畅的方法来配置 Polyglot Context
以了解我们的 Java 类。
所以,问题是:如何使用 Java 中的 GraalVM Polyglot 配置来使我们的 Java 类可通过 Python 脚本导入使用?
仅 java.* 包支持使用标准 Python import 语句导入 Java 类。通过使用 EmulateJython 选项,您可以为所有 Java 包启用此功能,但它会产生一些性能开销,因此默认情况下不启用它。有关 Jython 迁移的更多信息:https://www.graalvm.org/latest/reference-manual/python/Modern-Python-on-JVM/#importing-a-java-package
在您的示例中,您可以通过像这样传递它来启用该选项:
Context.newBuilder().option("python.EmulateJython", "true")
最终最好放弃 Jython 特定代码。如果没有 Jython 兼容模式,您可以使用
java.type(fullyQualifiedName)
访问 Java 类。有关更多信息,请参阅:https://www.graalvm.org/latest/reference-manual/python/Interoperability/#interacting-with-java-from-python-scripts