您可以在 Graal JVM 中远程调试 Graal.js 脚本 运行 吗?
Can you remotely debug Graal.js script running inside Graal JVM?
我在 Graal JVM (graalvm-ce-java8-19.3.0) 上 运行ning Java 程序,在那个程序里我 运行 JS 脚本通过 Graal.js 引擎。我想为那个 JS 脚本(不是 Java 程序)配置远程调试连接。我已经发现 Graal has support for that 通过 Chrome DevTools protocol/standard 进行调试。
文档解释了如何使用独立的 Graal.js 解释器,但是 also says 您可以在 JVM 中使用相同的选项,方法是在它们前面加上前缀 -Dpolyglot
。
所以您需要使用 -Dpolyglot.inspect
:
而不是 --inspect
java -Dpolyglot.inspect=9229 -jar app.jar
这非常适合本地调试 - 全部如所述here and here。
现在我尝试通过设置 -Dpolyglot.inspect=exampleHost:9229
将其用于远程调试,其中 exampleHost 解析为我的外部 ip。不幸的是,此设置会阻止 Graal.js 引擎正确初始化。没有太多关于真正错误的迹象,只是 stderr 上的这条消息:
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory:
Provider com.oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
意思是不支持远程配置?
这里有什么问题?
事实证明,对于远程连接,Graal 默认情况下希望使用安全调试通道,因此您需要通过 -Dpolyglot.inspect.Secure=false
禁用它或使用 -Dpolyglot.inspect.KeyStore*
switches 正确配置.
至于我的情况不需要安全性,所以我的配置变成:
java -Dpolyglot.inspect=exampleHost:9229 -Dpolyglot.inspect.Secure=false -jar app.jar
我只需要将 exampleHost:9229 添加到 chrome://inspect/#devices -> 配置...
并且远程调试有效!
TL;DR
这是我找到配置问题原因的方法。它可能对其他类似情况有用。
我调试了有问题的 Java 程序以查看 ScriptEngineManager
中出现了什么样的问题,我在包含消息 [=34= 的行的 javax.script.ScriptEngineManager#initEngines 中放置了一个断点].事实证明,这个 class 有一个内部 DEBUG 常量被硬编码为 false,这会阻止将任何堆栈跟踪打印到 stderr。我手动将异常转储到 stderr:
oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access0(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
at java.util.ServiceLoader$LazyIterator.access0(ServiceLoader.java:323)
at java.util.ServiceLoader$LazyIterator.run(ServiceLoader.java:407)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:409)
at java.util.ServiceLoader.next(ServiceLoader.java:480)
at javax.script.ScriptEngineManager.initEngines(ScriptEngineManager.java:122)
at javax.script.ScriptEngineManager.init(ScriptEngineManager.java:84)
at javax.script.ScriptEngineManager.<init>(ScriptEngineManager.java:61)
...
Caused by: org.graalvm.polyglot.PolyglotException: Starting inspector on exampleHost:9229 failed: Use options to specify the keystore
at org.graalvm.polyglot.Engine$Builder.build(Engine.java:506)
at com.oracle.truffle.js.scriptengine.GraalJSEngineFactory.<init>(GraalJSEngineFactory.java:95)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
... 17 more
现在这只是找出如何设置或禁用所需密钥库的问题。
我在 Graal JVM (graalvm-ce-java8-19.3.0) 上 运行ning Java 程序,在那个程序里我 运行 JS 脚本通过 Graal.js 引擎。我想为那个 JS 脚本(不是 Java 程序)配置远程调试连接。我已经发现 Graal has support for that 通过 Chrome DevTools protocol/standard 进行调试。
文档解释了如何使用独立的 Graal.js 解释器,但是 also says 您可以在 JVM 中使用相同的选项,方法是在它们前面加上前缀 -Dpolyglot
。
所以您需要使用 -Dpolyglot.inspect
:
--inspect
java -Dpolyglot.inspect=9229 -jar app.jar
这非常适合本地调试 - 全部如所述here and here。
现在我尝试通过设置 -Dpolyglot.inspect=exampleHost:9229
将其用于远程调试,其中 exampleHost 解析为我的外部 ip。不幸的是,此设置会阻止 Graal.js 引擎正确初始化。没有太多关于真正错误的迹象,只是 stderr 上的这条消息:
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory:
Provider com.oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
意思是不支持远程配置? 这里有什么问题?
事实证明,对于远程连接,Graal 默认情况下希望使用安全调试通道,因此您需要通过 -Dpolyglot.inspect.Secure=false
禁用它或使用 -Dpolyglot.inspect.KeyStore*
switches 正确配置.
至于我的情况不需要安全性,所以我的配置变成:
java -Dpolyglot.inspect=exampleHost:9229 -Dpolyglot.inspect.Secure=false -jar app.jar
我只需要将 exampleHost:9229 添加到 chrome://inspect/#devices -> 配置...
并且远程调试有效!
TL;DR
这是我找到配置问题原因的方法。它可能对其他类似情况有用。
我调试了有问题的 Java 程序以查看 ScriptEngineManager
中出现了什么样的问题,我在包含消息 [=34= 的行的 javax.script.ScriptEngineManager#initEngines 中放置了一个断点].事实证明,这个 class 有一个内部 DEBUG 常量被硬编码为 false,这会阻止将任何堆栈跟踪打印到 stderr。我手动将异常转储到 stderr:
oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access0(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
at java.util.ServiceLoader$LazyIterator.access0(ServiceLoader.java:323)
at java.util.ServiceLoader$LazyIterator.run(ServiceLoader.java:407)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:409)
at java.util.ServiceLoader.next(ServiceLoader.java:480)
at javax.script.ScriptEngineManager.initEngines(ScriptEngineManager.java:122)
at javax.script.ScriptEngineManager.init(ScriptEngineManager.java:84)
at javax.script.ScriptEngineManager.<init>(ScriptEngineManager.java:61)
...
Caused by: org.graalvm.polyglot.PolyglotException: Starting inspector on exampleHost:9229 failed: Use options to specify the keystore
at org.graalvm.polyglot.Engine$Builder.build(Engine.java:506)
at com.oracle.truffle.js.scriptengine.GraalJSEngineFactory.<init>(GraalJSEngineFactory.java:95)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
... 17 more
现在这只是找出如何设置或禁用所需密钥库的问题。