简体   繁体   English

使用GraalVM在Java中读取/加载Javascript时如何退出无限JS执行循环?

[英]How to exit infinite JS execution loop when reading/loading Javascript in Java using GraalVM?

I found sandbox options as a way to set sandbox.MaxCPUTime in the graalVM documentation, to limit how long the thread runs - https://www.graalvm.org/reference-manual/embed-languages/我在 graalVM 文档中找到了沙箱选项作为设置 sandbox.MaxCPUTime 的一种方式,以限制线程运行的时间 - https://www.graalvm.org/reference-manual/embed-languages/

I've tried the following code -我试过以下代码 -

                try (Context context = Context.newBuilder("js")
                        .allowExperimentalOptions(true)
                        .option("sandbox.MaxCPUTime", "10s")
                        .option("sandbox.MaxCPUTimeCheckInterval", "5ms")
                        .build())
                {
                    try {
                        context.eval("js", "while(true);");
                        assert false;
                    } catch (PolyglotException e) {
                        // Triggered after 500ms;
                        // Context is closed and can no longer be used
                        // Error message: Maximum CPU time limit of 500ms exceeded.
                        assert e.isCancelled();
                        assert e.isResourceExhausted();
                    }
                    context.close(true);
                }

This has been failing for me with the error -由于错误,这对我来说一直失败 -

java.lang.IllegalArgumentException: Could not find option with name sandbox.MaxCPUTime.

Is there a better way to achieve this or a way I can make these sandbox options work?有没有更好的方法来实现这一点,或者我可以让这些沙箱选项起作用?

You may want to use a more generic solution, that could potentially work with other scripting engines (eg rhino or nashorn ), regardless of the built-in features:您可能想要使用更通用的解决方案,它可能与其他脚本引擎(例如rhinonashorn )一起使用,而不管内置功能如何:

final ExecutorService executor = Executors.newSingleThreadExecutor();

final Context context = Context.newBuilder("js").build();
final Future<Object> futureResult = executor.submit(() -> context.eval("js", "while(true);"));

try {
    final Object result = futureResult.get(10, TimeUnit.SECONDS);
    System.out.println("Script evaluated within 10 seconds, result: " + result);
} catch (TimeoutException e) {
    context.interrupt(Duration.ZERO);
    System.out.println("Script not evaluated within 10 seconds, interrupted.");
}

System.out.println("Done.");

Other advantage of this solution is that it allows you to use a thread-pool, hence giving you more control over how concurrent scripts are executed (eg you can limit the number of scripts being executed at the same time to one, or to the number of available CPU-cores, etc.).此解决方案的另一个优点是它允许您使用线程池,从而使您可以更好地控制并发脚本的执行方式(例如,您可以将同时执行的脚本数量限制为一个,或限制为可用的 CPU 内核等)。

Please note though, that the time limit specified in the example is the time that elapsed since the submission of the task, not the time that was actually spent on the execution of the given script.但请注意,示例中指定的时间限制是自提交任务以来经过的时间,而不是实际执行给定脚本所花费的时间。

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

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