Clone: $ git clone https://github.com/clojure/test.check.git && cd test.check
Make main class:
echo "(ns foo (:gen-class)) (require '[clojure.test.check.random :as r]) (defn -main [& args] (prn (r/rand-long (r/make-random))))" > src/main/clojure/foo.clj
Make classes dir: mkdir -p classes
AOT compile:
$ clojure -J-Dclojure.compiler.direct.linking=true -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.2-alpha1"}}}' -e "(require 'foo) (compile 'foo) (compile 'clojure.test.check.random)"
Run on JVM, observe that random works:
$ java -cp classes:$(clojure -Spath) foo
2641378700178763226
$ java -cp classes:$(clojure -Spath) foo
-8419687867193585516
Compile with GraalVM native-image:
$ $GRAALVM_HOME/bin/native-image foo --no-fallback --no-server --report-unsupported-elements-at-runtime --initialize-at-build-time -cp $(clojure -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.2-alpha1"}} :paths ["classes"]}' -Spath)
Run binary, observe that random doesn't work:
$ ./foo
-4433304172342098913
$ ./foo
-4433304172342098913
(def next-rng
"Returns a random-number generator. Successive calls should return
independent results."
(let [a (atom (delay (r/make-java-util-splittable-random (System/currentTimeMillis))))
thread-local
(proxy [ThreadLocal] []
(initialValue []
(first (r/split (swap! a #(second (r/split (force %))))))))]
(fn []
(let [rng (.get thread-local)
[rng1 rng2] (r/split rng)]
(.set thread-local rng2)
rng1))))
(defn make-random
"Given an optional Long seed, returns an object that satisfies the
IRandom protocol."
([] (next-rng))
([seed] (r/make-java-util-splittable-random seed)))
With this code patched (either directly or through alter-var-root
the GraalVM binary will work correctly.