Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jine 3.22.0 - unable to build native image with GraalVM + Quarkus #818

Closed
vaclavsvejcar opened this issue Jan 23, 2023 · 9 comments
Closed
Milestone

Comments

@vaclavsvejcar
Copy link

Hello,

I was using jline 3.21.0 with Quarkus 2.15.3.Final and GraalVM 22.3.0 without any isues during building and running the native image, but after upgrading to jline 3.22.0 I'm getting following error during native image build:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing org.jline.terminal.impl.jna.JnaTerminalProvider.open(org.jline.terminal.Attributes, org.jline.terminal.Size) 
Parsing context:
   at org.jline.terminal.impl.jna.JnaTerminalProvider.open(JnaTerminalProvider.java:38)
   at org.jline.terminal.impl.jna.JnaTerminalProvider.newTerminal(JnaTerminalProvider.java:70)
   at org.jline.terminal.TerminalBuilder.doBuild(TerminalBuilder.java:509)
   at org.jline.terminal.TerminalBuilder.build(TerminalBuilder.java:303)
   at org.jline.terminal.TerminalBuilder.terminal(TerminalBuilder.java:94)
   at com.norcane.zen.ui.console.JLineConsole.postConstruct(JLineConsole.java:58)
   at com.norcane.zen.ui.console.JLineConsole_Bean.create(Unknown Source)
   at com.norcane.zen.ui.console.JLineConsole_Bean.create(Unknown Source)
   at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:74)
   at io.quarkus.arc.impl.RequestContext.get(RequestContext.java:82)
   at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:21)
   at com.norcane.zen.template.TemplateManager_ClientProxy.arc$delegate(Unknown Source)
   at com.norcane.zen.template.TemplateManager_ClientProxy.toString(Unknown Source)
   at java.lang.String.valueOf(String.java:4225)
   at java.lang.AssertionError.<init>(AssertionError.java:75)
   at com.oracle.svm.core.snippets.ImplicitExceptions.createAssertionErrorObject(ImplicitExceptions.java:222)

	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.DefaultVirtualInvokeTypeFlow.onObservedUpdate(DefaultVirtualInvokeTypeFlow.java:109)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:562)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:488)
	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:1423)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1840)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Caused by: org.graalvm.compiler.java.BytecodeParser$BytecodeParserError: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: com.sun.jna.Platform. This error is reported at image build time because class org.jline.terminal.impl.jna.JnaNativePty is registered for linking at image build time by command line
	at parsing org.jline.terminal.impl.jna.JnaNativePty.open(JnaNativePty.java:58)
	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.phases.InlineBeforeAnalysisGraphDecoder.lookupEncodedGraph(InlineBeforeAnalysis.java:180)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.doInline(PEGraphDecoder.java:1162)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.tryInline(PEGraphDecoder.java:1145)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.trySimplifyInvoke(PEGraphDecoder.java:1003)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.handleInvoke(PEGraphDecoder.java:957)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:817)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:179)
	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.UnresolvedElementException: Discovered unresolved type during parsing: com.sun.jna.Platform. This error is reported at image build time because class org.jline.terminal.impl.jna.JnaNativePty is registered for linking at image build time by command line
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.reportUnresolvedElement(SharedGraphBuilderPhase.java:333)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedType(SharedGraphBuilderPhase.java:288)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedMethod(SharedGraphBuilderPhase.java:316)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedInvoke(SharedGraphBuilderPhase.java:279)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeStatic(BytecodeParser.java:1676)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeStatic(BytecodeParser.java:1651)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5288)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3385)
	... 38 more

Do you have any idea what could be the cause and what could have changed between those two jline versions? Also let me know if you need any more info.
Thanks a lot!

@mattirn
Copy link
Collaborator

mattirn commented Jan 23, 2023

I think you should add --allow-incomplete-classpath build argument to avoid error com.oracle.graal.pointsto.constraints.UnresolvedElementException in your GraalVM compilation.

Build option --allow-incomplete-classpath should be default in GraalVM version 22.3.0????

@gnodet
Copy link
Member

gnodet commented Jan 24, 2023

There's one change between JLine 3.21 and 3.22 that could be related. It's the fact that an indirection has been added and a TerminalProvider service has been introduced, using the traditional META-INF/services discovery mechanism.
I've added the graalvm resources required to have those classes available for dynamic loading using https://github.com/jline/jline3/tree/master/terminal-jna/src/main/resources/META-INF/native-image/org.jline/jline-terminal-jansi, but it may not be sufficient to force graalvm to add the needed JNA classes. Maybe somehow forcing the inclusion of the JnaTerminalProvider will do the trick ?

@vaclavsvejcar
Copy link
Author

https://github.com/jline/jline3/tree/master/terminal-jna/src/main/resources/META-INF/native-image/org.jline/jline-terminal-jansi

@gnodet Thanks for the answer, do you know if those graalvm resources you mentioned should be automatically discovered and used by GraalVM during native image build, or do I need to somehow include it in my build configuration?

@gnodet
Copy link
Member

gnodet commented Jan 24, 2023

https://github.com/jline/jline3/tree/master/terminal-jna/src/main/resources/META-INF/native-image/org.jline/jline-terminal-jansi

@gnodet Thanks for the answer, do you know if those graalvm resources you mentioned should be automatically discovered and used by GraalVM during native image build, or do I need to somehow include it in my build configuration?

Those resources should be automatically discovered.

@gnodet
Copy link
Member

gnodet commented Jan 25, 2023

@vaclavsvejcar Do you have a simple reproducer for the problem ?

@vaclavsvejcar
Copy link
Author

vaclavsvejcar commented Jan 25, 2023

@gnodet Yes, I created simple demo project where the issue can be reproduced: https://github.com/vaclavsvejcar/jline-graalvm-issue-demo

It's basically a simple hello world Quarkus app as described on Get Started page, generated using following command:

quarkus create && cd code-with-quarkus

Then I only added single class ConsoleUtils that only retrieves Terminal instance from jLine and tries to call following:

terminal.getStringCapability(InfoCmp.Capability.cursor_up) != null;

When you try to build native image using

quarkus build --native

It will fail with the same error:

Caused by: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: com.sun.jna.Platform. This error is reported at image build time because class org.jline.terminal.impl.jna.JnaNativePty is registered for linking at image build time by command line
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.reportUnresolvedElement(SharedGraphBuilderPhase.java:333)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedType(SharedGraphBuilderPhase.java:288)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedMethod(SharedGraphBuilderPhase.java:316)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedInvoke(SharedGraphBuilderPhase.java:279)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeStatic(BytecodeParser.java:1676)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genInvokeStatic(BytecodeParser.java:1651)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5288)
	at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3385)
	... 37 more

Hope this will help, let me know if you need some more info.

@gnodet
Copy link
Member

gnodet commented Jan 25, 2023

Simply add the following dependency to you project:

    <dependency>
      <groupId>net.java.dev.jna</groupId>
      <artifactId>jna</artifactId>
    </dependency>

The jline artifact includes the code for terminal providers (exec, jansi and jna), but the jansi and jna providers require the dependencies. You can also use the smaller jline artifacts if you prefer, as those have the required dependencies.

@vaclavsvejcar
Copy link
Author

vaclavsvejcar commented Jan 28, 2023

@gnodet This seems to fix the native image build itself, but now it seems that the native image uses dumb terminal instead, with this warning in logs:

2023-01-28 19:30:32,184 WARNING [org.jline] (main) Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)

Is there still something that might have changed in 3.22.0 resulting in this problem? Still don't understand why it works with JVM and not with native image, and what exactly changed between the two versions, because 3.21.0 worked without any issues with native image.

EDIT: debug log below

2023-01-28 21:40:21,609 WARNING [org.jline] (main) Creating a dumb terminal: java.lang.IllegalStateException: Unable to create a terminal
	at org.jline.terminal.TerminalBuilder.doBuild(TerminalBuilder.java:363)
	at org.jline.terminal.TerminalBuilder.build(TerminalBuilder.java:303)
	at org.jline.terminal.TerminalBuilder.terminal(TerminalBuilder.java:94)
	at com.norcane.zen.ui.console.JLineConsole.postConstruct(JLineConsole.java:58)
	at com.norcane.zen.ui.console.JLineConsole_Bean.create(Unknown Source)
	at com.norcane.zen.ui.console.JLineConsole_Bean.create(Unknown Source)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:113)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:37)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:34)
	at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
	at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:34)
	at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:21)
	at com.norcane.zen.ui.console.JLineConsole_ClientProxy.arc$delegate(Unknown Source)
	at com.norcane.zen.ui.console.JLineConsole_ClientProxy.printLn(Unknown Source)
	at com.norcane.zen.cli.command.AbstractCommand.printProductHeader(AbstractCommand.java:77)
	at com.norcane.zen.cli.command.AbstractCommand.call(AbstractCommand.java:63)
	at com.norcane.zen.cli.command.AbstractCommand.call(AbstractCommand.java:46)
	at picocli.CommandLine.executeUserObject(CommandLine.java:2041)
	at picocli.CommandLine.access$1500(CommandLine.java:148)
	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2453)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2415)
	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
	at picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
	at io.quarkus.picocli.runtime.PicocliRunner$EventExecutionStrategy.execute(PicocliRunner.java:26)
	at picocli.CommandLine.execute(CommandLine.java:2170)
	at io.quarkus.picocli.runtime.PicocliRunner.run(PicocliRunner.java:40)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:129)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
	Suppressed: java.io.IOException: Unable to load terminal provider jansi
		at org.jline.terminal.spi.TerminalProvider.load(TerminalProvider.java:65)
		at org.jline.terminal.TerminalBuilder.doBuild(TerminalBuilder.java:376)
		... 31 more
	Caused by: java.lang.ClassNotFoundException: org.jline.terminal.impl.jansi.JansiTerminalProvider
		at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
		at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
		at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:132)
		at org.jline.terminal.spi.TerminalProvider.load(TerminalProvider.java:62)
		... 32 more
	Suppressed: java.io.IOException: Unable to load terminal provider exec
		at org.jline.terminal.spi.TerminalProvider.load(TerminalProvider.java:65)
		at org.jline.terminal.TerminalBuilder.doBuild(TerminalBuilder.java:386)
		... 31 more
	Caused by: java.lang.ClassNotFoundException: org.jline.terminal.impl.exec.ExecTerminalProvider
		at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
		at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
		at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:132)
		at org.jline.terminal.spi.TerminalProvider.load(TerminalProvider.java:62)
		... 32 more

@mattirn
Copy link
Collaborator

mattirn commented Feb 20, 2023

@vaclavsvejcar this has been fixed in JLine3.22.1-SNAPSHOT, see commit 8cb3793

@gnodet gnodet added this to the 3.23.0 milestone Mar 2, 2023
@gnodet gnodet closed this as completed Mar 2, 2023
sophokles73 added a commit to eclipse-hono/hono that referenced this issue Oct 11, 2023
Added missing JNA library required for determining terminal type during
runtime.

See jline/jline3#818
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants