Fork me on GitHub
#graalvm
<
2023-05-16
>
Luciano Laratelli22:05:42

Hi all! I’m seeing some errors trying to make a native image for a project with a (transitive) dependency on https://github.com/vsch/flexmark-java. Would appreciate any pointers on resolving this issue. Detailed error messages and more context in 🧵

Luciano Laratelli22:05:58

command and error message:

18:17:11❯ clj -T:build uberjar && native-image -jar luciano-service.jar && ./luciano-service
Loading initial Timbre config from: :default
========================================================================================================================
GraalVM Native Image: Generating 'luciano-service' (executable)...
========================================================================================================================
Warning: Feature class InitAtBuildTimeFeature is annotated with the deprecated annotation @AutomaticFeature. Support for this annotation will be removed in a future version of GraalVM. Applications should register a feature using the option --features=InitAtBuildTimeFeature
[clj-easy/graal-build-time] Registering packages for build time initialization: clojure, clj_easy, cpath_clj, crypto, cybermonday, flatland.ordered, flatland.useful, hiccup, hickory, io.aviso, li.laratel, meta_merge, org.httpkit, quoin, reitit, ring.middleware, ring.util, taoensso, yaml
[1/7] Initializing...                                                                                   (12.4s @ 0.16GB)
 Version info: 'GraalVM 22.3.2 Java 17 CE'
 Java version info: '17.0.7+7-jvmci-22.3-b18'
 C compiler: cc (apple, x86_64, 14.0.3)
 Garbage collector: Serial GC
 1 user-specific feature(s)
 - InitAtBuildTimeFeature
Loading initial Timbre config from: :default
[2/7] Performing analysis...  []                                                                        (37.5s @ 0.61GB)
   7,080 (90.43%) of  7,829 classes reachable
   7,562 (35.71%) of 21,178 fields reachable
  25,702 (74.77%) of 34,375 methods reachable
      44 classes,     0 fields, and     0 methods registered for reflection

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing com.vladsch.flexmark.util.sequence.SequenceUtils.<clinit>() 
Parsing context: <no parsing context available> 

        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultAnalysisPolicy.staticRootMethodGraph(DefaultAnalysisPolicy.java:182)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis.lambda$addRootMethod$0(PointsToAnalysis.java:320)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$2.run(PointsToAnalysis.java:507)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: org.graalvm.compiler.java.BytecodeParser$BytecodeParserError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of com.vladsch.flexmark.util.sequence.SequenceUtils$$Lambda$803/0x00000007c1839580 are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=com.vladsch.flexmark.util.sequence.SequenceUtils$$Lambda$803/0x00000007c1839580.
        at parsing com.vladsch.flexmark.util.sequence.SequenceUtils.<clinit>(SequenceUtils.java:54)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.throwParserError(BytecodeParser.java:2518)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.throwParserError(SharedGraphBuilderPhase.java:110)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3393)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.handleBytecodeBlock(BytecodeParser.java:3345)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBlock(BytecodeParser.java:3190)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:1138)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:1030)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:97)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase.run(SharedGraphBuilderPhase.java:84)
        at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.run(Phase.java:49)
        at jdk.internal.vm.compiler/org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:446)
        at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
        at jdk.internal.vm.compiler/org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.AnalysisParsedGraph.parseBytecode(AnalysisParsedGraph.java:135)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsed(AnalysisMethod.java:685)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:171)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:349)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
        ... 13 more
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of com.vladsch.flexmark.util.sequence.SequenceUtils$$Lambda$803/0x00000007c1839580 are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=com.vladsch.flexmark.util.sequence.SequenceUtils$$Lambda$803/0x00000007c1839580.
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:132)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:595)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin$Transplanter.constant(IntrinsifyMethodHandlesInvocationPlugin.java:888)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin$Transplanter.node(IntrinsifyMethodHandlesInvocationPlugin.java:771)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin$Transplanter.graph(IntrinsifyMethodHandlesInvocationPlugin.java:630)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin.processInvokeWithMethodHandle(IntrinsifyMethodHandlesInvocationPlugin.java:564)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.IntrinsifyMethodHandlesInvocationPlugin.handleInvoke(IntrinsifyMethodHandlesInvocationPlugin.java:249)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.tryNodePluginForInvocation(BytecodeParser.java:2294)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.appendInvoke(BytecodeParser.java:1874)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genDynamicInvokeHelper(BytecodeParser.java:1760)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeDynamic(BytecodeParser.java:1711)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeDynamic(BytecodeParser.java:1707)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.AnalysisGraphBuilderPhase$AnalysisBytecodeParser.genInvokeDynamic(AnalysisGraphBuilderPhase.java:126)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5290)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3385)
        ... 28 more
------------------------------------------------------------------------------------------------------------------------
                        1.1s (2.1% of total time) in 19 GCs | Peak RSS: 2.42GB | CPU load: 2.89
========================================================================================================================
Failed generating 'luciano-service' after 50.5s.
Error: Image build request failed with exit status 1

Luciano Laratelli22:05:25

I’m including com.github.clj-easy/graal-build-time {:mvn/version "0.1.4"} in my deps.edn and am using io.github.clojure/tools.build {:mvn/version "0.9.4"}. build.clj is pretty simple:

(ns build
  (:require [clojure.tools.build.api :as b]))

(def class-dir "classes")

(def basis (b/create-basis {:project "deps.edn"}))

(def jar-file "luciano-service.jar")

(defn clean [_]
  (b/delete {:path "target"}))

#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn uberjar [_]
  (clean nil)
  (b/copy-dir {:src-dirs ["src" "resources"]
               :target-dir class-dir})
  (b/compile-clj {:basis basis
                  :src-dirs ["src" "resources"]
                  :class-dir class-dir})
  (b/uber {:class-dir class-dir
           :uber-file jar-file
           :basis basis
           :main 'li.laratel.core}))

👀 1
borkdude22:05:44

You need to initialize the Java classes that are used from Clojure also at build time.

borkdude22:05:02

I'll check back tomorrow but hopefully this will help you a bit.

Luciano Laratelli22:05:34

Thank you! I’ll see if I can make progress on that 🙂

borkdude22:05:47

Also see these docs: https://github.com/clj-easy/graal-docs and you can check babashka, clj-kondo, jet and other projects as examples

👀 3
gratitude-thank-you 1