File tree Expand file tree Collapse file tree
polyglot/src/main/java/org/restheart/polyglot Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -39,9 +39,12 @@ public abstract class JSPlugin {
3939
4040 static {
4141 try {
42- // Engine.create() touches Truffle thread locals, must run on a platform thread (see PolyglotThreadUtils)
43- // and needs PluginsClassloader so ServiceLoader can find js-language's TruffleLanguageProvider
44- engine = PolyglotThreadUtils .onPlatformThread (() -> PolyglotClassloaderHelper .withPluginsClassloaderResult (Engine ::create ));
42+ // Must be a plain method reference to a method NOT declared here: a lambda
43+ // body written inside this static initializer would become a private
44+ // synthetic method of JSPlugin, and invoking it from the platform thread
45+ // would then require JSPlugin's own <clinit> to finish -- which is exactly
46+ // what's blocked waiting for this platform thread, causing a deadlock.
47+ engine = PolyglotThreadUtils .onPlatformThread (PolyglotThreadUtils ::createEngine );
4548 } catch (Exception e ) {
4649 throw new IllegalStateException ("Error creating polyglot Engine" , e );
4750 }
Original file line number Diff line number Diff line change 2020 */
2121package org .restheart .polyglot ;
2222
23+ import java .io .IOException ;
2324import java .util .concurrent .Callable ;
2425import java .util .concurrent .ExecutionException ;
2526import java .util .concurrent .ExecutorService ;
2627import java .util .concurrent .Executors ;
2728
29+ import org .graalvm .polyglot .Engine ;
30+
2831/**
2932 * Runs GraalVM polyglot Context creation, enter/leave and eval on a platform thread.
3033 *
@@ -47,6 +50,20 @@ private PolyglotThreadUtils() {}
4750 * @return the result of the task
4851 * @throws Exception if the task throws an exception
4952 */
53+ /**
54+ * Creates a polyglot Engine with the PluginsClassloader as context classloader.
55+ *
56+ * <p>Declared here (not as a lambda body inside JSPlugin's static initializer)
57+ * so that invoking it from a platform thread never needs to wait on JSPlugin's
58+ * own class-initialization monitor, which would deadlock since JSPlugin's
59+ * <clinit> is the one submitting this task and blocking on its result.</p>
60+ *
61+ * @return a newly created Engine
62+ */
63+ public static Engine createEngine () throws IOException {
64+ return PolyglotClassloaderHelper .withPluginsClassloaderResult (Engine ::create );
65+ }
66+
5067 public static <T > T onPlatformThread (Callable <T > task ) throws Exception {
5168 try {
5269 return PLATFORM_EXECUTOR .submit (task ).get ();
You can’t perform that action at this time.
0 commit comments