clj-easy / graal-docs

Scripts and tips to get Clojure latest working with GraalVM latest
Eclipse Public License 1.0
390 stars 20 forks source link

Why can't Clojure programs be compiled without --initialize-at-build-time? #51

Closed borkdude closed 3 years ago

borkdude commented 3 years ago

See https://github.com/oracle/graal/issues/3251#issuecomment-842305171

I'd like to find out more.

I have tried lots of variations but I end up initialization everything at build time every time before it works.

borkdude commented 3 years ago

Possible workaround around a dynamic var restriction:

package clojure.lang;
import clojure.lang.RT;
import clojure.lang.Var;
import java.util.HashMap;
public class ThreadBindings {
    static {
        HashMap bindings = new HashMap<Var,Object>();
        bindings.put(RT.WARN_ON_REFLECTION, true);
        clojure.lang.IPersistentMap map = clojure.lang.PersistentHashMap.create(bindings);
        clojure.lang.Var.pushThreadBindings(map);
    }
}
$GRAALVM_HOME/bin/native-image --no-server --no-fallback --initialize-at-build-time=clojure.lang.ThreadBindings --initialize-at-build-time=clojure.core.server__init --initialize-at-build-time=clojure --initialize-at-build-time=clojure.lang  -H:+ReportExceptionStackTraces -cp classes:$(clojure -Spath) mymain
borkdude commented 3 years ago

Workaround for class initialization deadlock:

One workaround you can do for class initialization deadlocks when you are already relying on the native image Feature API: in the Feature.beforeAnalysis method, you can manually trigger the class initialization of one of the affected classes. At this point, you are still single threaded. I used this for example recently to work around a JDK class initialization deadlock: 2c6bf3c

https://github.com/oracle/graal/issues/3251#issuecomment-842820130