H2DB breaks GraalVM native image production

547 views
Skip to first unread message

Behrang

unread,
Jan 5, 2022, 6:51:11 AM1/5/22
to H2 Database
Hi,

I am working on a small project where I use h2db as an embedded database. I want to compile this project using graalvm and use the produced binary.

However the dependency breaks the build. Are there any workarounds available?

Sample build log:

$ mvn -Pnative clean package
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< xyz.behrang:xyz-fs >-------------------------
[INFO] Building xyz-fs 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ xyz-fs ---
[INFO] Deleting /home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ xyz-fs ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ xyz-fs ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 4 source files to /home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ xyz-fs ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ xyz-fs ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ xyz-fs ---
[INFO] No tests to run.
[INFO]
[INFO] --- native-maven-plugin:0.9.9:test (test-native) @ xyz-fs ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ xyz-fs ---
[INFO] Building jar: /home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/xyz-fs-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- native-maven-plugin:0.9.9:build (build-native) @ xyz-fs ---
[INFO] ImageClasspath Entry: com.h2database:h2:jar:2.0.204:compile (file:///home/behrangsa/.m2/repository/com/h2database/h2/2.0.204/h2-2.0.204.jar)
[INFO] ImageClasspath Entry: commons-codec:commons-codec:jar:1.15:compile (file:///home/behrangsa/.m2/repository/commons-codec/commons-codec/1.15/commons-codec-1.15.jar)
[INFO] ImageClasspath Entry: commons-io:commons-io:jar:2.11.0:compile (file:///home/behrangsa/.m2/repository/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar)
[INFO] ImageClasspath Entry: xyz.behrang:xyz-fs:jar:1.0-SNAPSHOT (file:///home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/xyz-fs-1.0-SNAPSHOT.jar)
[INFO] Executing: /home/behrangsa/.sdkman/candidates/java/current/bin/native-image -cp /home/behrangsa/.m2/repository/com/h2database/h2/2.0.204/h2-2.0.204.jar:/home/behrangsa/.m2/repository/commons-codec/commons-codec/1.15/commons-codec-1.15.jar:/home/behrangsa/.m2/repository/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar:/home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/xyz-fs-1.0-SNAPSHOT.jar -H:Class=xyz.behrang.fs.Main -H:Name=findex
[findex:56102]    classlist:     614.69 ms,  0.96 GB
[findex:56102]        (cap):     377.03 ms,  0.96 GB
[findex:56102]        setup:   1,329.99 ms,  0.96 GB
[findex:56102]     analysis:   3,875.41 ms,  2.31 GB
Fatal error:com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing org.h2.value.ValueToObjectConverter.valueToObject(java.lang.Class, org.h2.value.Value, org.h2.jdbc.JdbcConnection)
Parsing context:
   at org.h2.value.ValueToObjectConverter.valueToObject(ValueToObjectConverter.java:281)
   at org.h2.schema.FunctionAlias$JavaMethod.execute(FunctionAlias.java:474)
   at org.h2.schema.FunctionAlias$JavaMethod.getValue(FunctionAlias.java:345)
   at org.h2.expression.function.JavaFunction.getValue(JavaFunction.java:40)
   at org.h2.command.dml.Call.update(Call.java:52)
   at org.h2.command.CommandList.executeRemaining(CommandList.java:49)
   at org.h2.command.CommandList.update(CommandList.java:66)
   at org.h2.command.Command.executeUpdate(Command.java:252)
   at org.h2.engine.Engine.openSession(Engine.java:258)
   at org.h2.engine.Engine.createSession(Engine.java:201)
   at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
   at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:117)
   at org.h2.Driver.connect(Driver.java:59)
   at java.sql.DriverManager.getConnection(DriverManager.java:681)
   at java.sql.DriverManager.getConnection(DriverManager.java:252)
   at xyz.behrang.fs.commands.Init.run(Init.java:35)
   at xyz.behrang.fs.Main.main(Main.java:28)
   at com.oracle.svm.core.JavaMainWrapper.runCore(JavaMainWrapper.java:147)
   at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:183)

        at com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:133)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.createTypeFlow(MethodTypeFlow.java:311)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureTypeFlowCreated(MethodTypeFlow.java:282)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:103)
        at com.oracle.graal.pointsto.flow.StaticInvokeTypeFlow.update(InvokeTypeFlow.java:420)
        at com.oracle.graal.pointsto.PointsToAnalysis$2.run(PointsToAnalysis.java:595)
        at com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:188)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:172)
        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: com.oracle.graal.pointsto.util.AnalysisError: parsing had failed in another thread
        at com.oracle.graal.pointsto.util.AnalysisError.shouldNotReachHere(AnalysisError.java:153)
        at com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsed(AnalysisMethod.java:656)
        at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.lookupEncodedGraph(InlineBeforeAnalysis.java:182)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.doInline(PEGraphDecoder.java:1120)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.tryInline(PEGraphDecoder.java:1103)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.trySimplifyInvoke(PEGraphDecoder.java:961)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.handleInvoke(PEGraphDecoder.java:915)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:791)
        at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:242)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:532)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:787)
        at com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:99)
        at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:171)
        at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:321)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.createTypeFlow(MethodTypeFlow.java:293)
        ... 12 more
Caused by: org.graalvm.compiler.java.BytecodeParser$BytecodeParserError: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: org.locationtech.jts.geom.Geometry. To diagnose the issue you can use the --allow-incomplete-classpath option. The missing type is then reported at run time when it is accessed the first time.
        at parsing org.h2.value.ValueGeometry.getGeometry(ValueGeometry.java:163)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.throwParserError(BytecodeParser.java:2624)
        at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.throwParserError(SharedGraphBuilderPhase.java:107)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3485)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.handleBytecodeBlock(BytecodeParser.java:3437)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBlock(BytecodeParser.java:3282)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:1145)
        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:84)
        at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase.run(SharedGraphBuilderPhase.java:81)
        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:212)
        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 com.oracle.graal.pointsto.flow.AnalysisParsedGraph.parseBytecode(AnalysisParsedGraph.java:132)
        at com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsed(AnalysisMethod.java:621)
        ... 25 more
Caused by: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: org.locationtech.jts.geom.Geometry. To diagnose the issue you can use the --allow-incomplete-classpath option. The missing type is then reported at run time when it is accessed the first time.
        at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.reportUnresolvedElement(SharedGraphBuilderPhase.java:307)
        at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedType(SharedGraphBuilderPhase.java:263)
        at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedCheckCast(SharedGraphBuilderPhase.java:227)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genCheckCast(BytecodeParser.java:4458)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genCheckCast(BytecodeParser.java:4451)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5427)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3477)
        ... 37 more
[findex:56102]      [total]:   5,964.61 ms,  2.31 GB
# Printing build artifacts to: /home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/findex.build_artifacts.txt
Error: Image build request failed with exit status 1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.370 s
[INFO] Finished at: 2022-01-05T22:48:48+11:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.9:build (build-native) on project xyz-fs: Execution of /home/behrangsa/.sdkman/candidates/java/current/bin/native-image -cp /home/behrangsa/.m2/repository/com/h2database/h2/2.0.204/h2-2.0.204.jar:/home/behrangsa/.m2/repository/commons-codec/commons-codec/1.15/commons-codec-1.15.jar:/home/behrangsa/.m2/repository/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar:/home/behrangsa/Documents/Projects/github.com/behrangsa/xyz-fs/target/xyz-fs-1.0-SNAPSHOT.jar -H:Class=xyz.behrang.fs.Main -H:Name=findex returned non-zero result -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Noel Grandin

unread,
Jan 5, 2022, 7:02:30 AM1/5/22
to H2 Database
You're missing the the JTS geometry classes

Behrang

unread,
Jan 7, 2022, 5:43:59 AM1/7/22
to H2 Database
Hi Noel,

Adding that dependency solved that problem, but the program still breaks at runtime, this time with another error.

I have uploaded some sample code here: https://github.com/behrangsa/xyz-fs/tree/feature/graal

When I run the program with plain old Java, it runs fine and creates an empty database at ~/Crash.

When I run it through native-image, the executable crashes with:

org.h2.jdbc.JdbcSQLNonTransientException: (Message HY000 not found) [50000-204]
        at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:340)

        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:117)
        at org.h2.Driver.connect(Driver.java:59)
        at java.sql.DriverManager.getConnection(DriverManager.java:681)
        at java.sql.DriverManager.getConnection(DriverManager.java:252)
        at xyz.behrang.fs.Main.main(Main.java:10)
Caused by: java.lang.NullPointerException
        at org.h2.store.fs.FilePath.get(FilePath.java:87)
        at org.h2.store.fs.FileUtils.isAbsolute(FileUtils.java:139)
        at org.h2.engine.ConnectionInfo.getName(ConnectionInfo.java:457)
        at org.h2.engine.Engine.openSession(Engine.java:49)
        at org.h2.engine.Engine.openSession(Engine.java:222)

        at org.h2.engine.Engine.createSession(Engine.java:201)
        at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)

I run this program under Linux. Under another OS it may work. But looks like native image doesn't like something about the way FilePath class is written.

Evgenij Ryazanov

unread,
Jan 10, 2022, 5:52:20 AM1/10/22
to H2 Database
Hello!

I think you need to force inclusion of org.h2.store.fs.disk.* classes into compiled program somehow, H2 loads them dynamically through reflection and NPE here mean they weren't found.
Reply all
Reply to author
Forward
0 new messages