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

Native Compilation and --link-at-build-time #30528

Closed
hernael opened this issue Jan 23, 2023 · 31 comments
Closed

Native Compilation and --link-at-build-time #30528

hernael opened this issue Jan 23, 2023 · 31 comments
Assignees
Labels
area/mandrel kind/bug Something isn't working triage/needs-reproducer We are waiting for a reproducer.

Comments

@hernael
Copy link

hernael commented Jan 23, 2023

Describe the bug

In native build process, quarkus add --link-at-build-time argument.
But in my case that argument throws:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing com.squareup.wire.schema.RootKt.<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.UnresolvedElementException: Discovered unresolved field during parsing: okio.Options.Companion. This error is reported at image build time because class com.squareup.wire.schema.RootKt is registered for linking at image build time by command line
        at parsing com.squareup.wire.schema.RootKt.<clinit>(Root.kt:192)
        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.UnresolvedElementException: Discovered unresolved field during parsing: okio.Options.Companion. This error is reported at image build time because class com.squareup.wire.schema.RootKt 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.handleUnresolvedField(SharedGraphBuilderPhase.java:305)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.handleUnresolvedLoadField(SharedGraphBuilderPhase.java:274)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.resolveStaticFieldAccess(BytecodeParser.java:4850)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genGetStatic(BytecodeParser.java:4776)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.genGetStatic(BytecodeParser.java:4772)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5282)
        at jdk.internal.vm.compiler/org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3385)
        ... 28 more

error even stays if i add the property:

quarkus.native.additional-build-args=--initialize-at-run-time=com.squareup.wire.schema.RootKt,--allow-incomplete-classpath

the way I got it NOT to be added --link-at-build-time argument to native build phase was to add a dependency:

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-reactive-oracle-client</artifactId>
        </dependency>

There must be a solution other than adding a dependency so that the --link-at-build-time argument is removed in native build.

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

openjdk version "17.0.5"

GraalVM version (if different from Java)

mandrel-java17-22.3.0.1-Final

Quarkus version or git rev

2.16.0.CR1

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.6

Additional information

No response

@hernael hernael added the kind/bug Something isn't working label Jan 23, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Jan 23, 2023

/cc @Karm (mandrel), @galderz (mandrel), @zakkak (mandrel)

@geoand
Copy link
Contributor

geoand commented Jan 23, 2023

What is the exact error is you use quarkus.native.additional-build-args=--initialize-at-run-time=com.squareup.wire.schema.RootKt,--allow-incomplete-classpath?

And what is the native-image command that has been executed (it's printed in the console)?

@zakkak
Copy link
Contributor

zakkak commented Jan 23, 2023

Related to #25526

@geoand
Copy link
Contributor

geoand commented Jan 23, 2023

@zakkak should we close this as a duplicate?

@zakkak
Copy link
Contributor

zakkak commented Jan 23, 2023

Yes and no :)

Yes: This is not actually a Quarkus issue. We need to write a guide about how to approach this kind of issues and point people to it.

No: #25526 is a feature request for allowing users to bypass such issues, which is something we would like them to do only as a last resort. So in that sense this issue is not a duplicate per se.

In the lack of a proper guide on how to approach this I suggest we keep this open and help @hernael find a fix.
Unfortunately I won't be able to help with any of these in the next couple of days, but feel free to assign this to me.

@hernael
Copy link
Author

hernael commented Jan 23, 2023

Hi @geoand @zakkak

The error mentioned in first comment is error exact that is thrown with those arguments: quarkus.native.additional-build-args=--initialize-at-run-time=com.squareup.wire.schema.RootKt,--allow-incomplete-classpath

The native command is:

/opt/mandrel/bin/native-image -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dlogging.initial-configurator.min-level=500 -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Davro.disable.unsafe=true -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=es -J-Duser.country=VE -J-Dfile.encoding=UTF-8 --features=io.quarkus.caffeine.runtime.graal.CacheConstructorsFeature,io.quarkus.runner.Feature,io.quarkus.runtime.graal.ResourcesFeature,io.quarkus.runtime.graal.DisableLoggingFeature -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -J--add-opens=java.base/java.io=ALL-UNNAMED -J--add-opens=java.base/java.lang.invoke=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -H:+CollectImageBuildStatistics -H:ImageBuildStatisticsFile=process-transaction-application-2.1-SNAPSHOT-runner-timing-stats.json -H:BuildOutputJSONFile=process-transaction-application-2.1-SNAPSHOT-runner-build-output-stats.json -H:ReflectionConfigurationFiles=reflection-kafka-proto-config.json --initialize-at-run-time=com.squareup.wire.schema.RootKt --allow-incomplete-classpath -H:+AllowFoldMethods -J-Djava.awt.headless=true --no-fallback --link-at-build-time -H:+ReportExceptionStackTraces -H:-AddAllCharsets --enable-url-protocols=http,https -H:NativeLinkerOption=-no-pie -H:-UseServiceLoaderFeature -H:+StackTrace -H:AdditionalSecurityProviders=com.sun.security.sasl.Provider,org.apache.kafka.common.security.oauthbearer.internals.OAuthBearerSaslClientProvider,org.apache.kafka.common.security.scram.internals.ScramSaslClientProvider -J--add-exports=org.graalvm.sdk/org.graalvm.nativeimage.impl=ALL-UNNAMED -J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk=ALL-UNNAMED --exclude-config io\.netty\.netty-codec /META-INF/native-image/io\.netty/netty-codec/generated/handlers/reflect-config\.json --exclude-config io\.netty\.netty-handler /META-INF/native-image/io\.netty/netty-handler/generated/handlers/reflect-config\.json process-transaction-application-2.1-SNAPSHOT-runner -jar process-transaction-application-2.1-SNAPSHOT-runner.jar

Important note, before updating there were no errors! and I used:

quarkus.platform.version: 2.13.2.Final
graal.version: mandrel-java17-21.3.1.1-Final

I just made a change of quarkus and native compiler. Maybe the problem is mandrel

@galderz
Copy link
Member

galderz commented Jan 25, 2023

I don't know how 21.3 would work, but if I were you, I would look to your application, its dependencies and see why the jar containing okio.Options.Companion might not be included in the list of jars that native image takes as input. I'm neither a Kotlin or Gradle expert.

No idea where you got the clue to add the quarkus-reactive-oracle-client dependency but if that works, that's likely due to extension behind it, or the oracle client jar itself, which under the covers sets the allow incomplete classpath underneath. In any case, going down this path is not recommended.

A preferred approach might be to pass in --initialize-at-run-time=com.squareup or a problematic package that is underneath that within the additional build arguments.

@hernael
Copy link
Author

hernael commented Jan 26, 2023

@galderz for some unknown reason, when i add the oracle dependency (quarkus-reactive-oracle-client), quarkus doesn't add --link-at-build-time argument in native-image command. With that argument Mandrel ignores --initialize-at-run-time=com.squareup.wire.schema.RootKt and throws exception, but if --link-at-build-time argument is removed everything compiles fine.

It's like --link-at-build-time has higher priority than --initialize-at-run-time=com.squareup.wire.schema.RootKt in Mandrel

Change --initialize-at-run-time=com.squareup.wire.schema.RootKt for --initialize-at-run-time=com.squareup makes no difference, error still occurs.

@zakkak
Copy link
Contributor

zakkak commented Jan 30, 2023

@hernael can you please have a look at #30716 and see if the information there are enough for you to overcome the issue? If not please provide feedback on how to improve it.

@turing85
Copy link
Contributor

turing85 commented Feb 1, 2023

@zakkak I have a very similar issue (details are in zulip). In my case, a constructor is not found. I have verified that the class is on the classpath (mvn dependency:tree shows the dependency that contains the class, is present). And I am also quite sure that there are no optional dependencies involved. Any hints on how to tackle this situation?

@galderz
Copy link
Member

galderz commented Feb 6, 2023

@turing85 Native reports.

@zakkak
Copy link
Contributor

zakkak commented Feb 6, 2023

@turing85 you might be hitting the issue I describe in oracle/graal#4661, i.e., the error you are seeing might be missleading and the actual issue is different.

@jerboaa
Copy link
Contributor

jerboaa commented Feb 8, 2023

quarkus.platform.version: 2.13.2.Final
graal.version: mandrel-java17-21.3.1.1-Final

Hmm, so you are using Quarkus 2.13.x with 21.3 Mandrel? For 2.13 Quarkus it's recommended to use 22.3 mandrel. Have you tried that?

Edit: The original report mentions 22.3 GraalVM/Mandrel. It would be good to know which it is :)

@zakkak
Copy link
Contributor

zakkak commented Feb 8, 2023

Hmm, so you are using Quarkus 2.13.x with 21.3 Mandrel? For 2.13 Quarkus it's recommended to use 22.3 mandrel.

Just a clarification for the record.

For Quarkus 2.13.0 -- 2.13.3 it's actually recommended to use GraalVM/Mandrel 21.3 or 22.2. For 2.13.4 onwards, it's recommended to use 22.3. See https://github.com/graalvm/mandrel/wiki.

That being said, it's always recommended to use the latest release. Both 2.13.2 and 21.3 are outdated at this point, so please consider updating to Quarkus 2.13.7 or later and GraalVM/Mandrle 22.3 regardless of this issue.

@zakkak
Copy link
Contributor

zakkak commented Mar 6, 2023

@hernael is this still an issue for you?

@luis-rabock
Copy link

I have the same issue:

com.pengrad.telegrambot.impl.TelegramBotClient is registered for linking at image build time by command line

Running:
mvn package -Dquarkus.package.type=native -Dquarkus.native.additional-build-args="--initialize-at-run-time=com.pengrad.telegrambot.impl.TelegramBotClient, --allow-incomplete-classpath"

GraalVm: 22.3.r19-grl
quarkus: 3.0.0.Alpha4

@hernael
Copy link
Author

hernael commented Mar 7, 2023

Hi @zakkak
yes, if there is already a quarkus property so that --link-at-build-time argument is not added in native compile
no, if there is no way to remove that option

@zakkak
Copy link
Contributor

zakkak commented Mar 13, 2023

@hernael and @luis-rabock did you try following the short guide in https://quarkus.io/version/main/guides/native-reference#i-get-a-analysiserrorparsingerror-when-building-a-native-executable-due-to-an-unresolvedelementexception-what-can-i-do ?

If not, please do.
If yes, please let me know what you tried and why it doesn't work so that we can improve that guide.

Thanks

@galderz
Copy link
Member

galderz commented Mar 14, 2023

@luis-rabock Please open a different issue to avoid creating confusion.

@hernael Please follow @zakkak's advice. Also, you still didn't provide the error(s) you get when you pass in --initialize-at-run-time=com.squareup.wire.schema.RootKt or --initialize-at-run-time=com.squareup. Sure, adding those flags might still cause errors but they should be slightly different and this is important for us to be able to help further. Or provide a reproducer for us to run.

@hernael
Copy link
Author

hernael commented Mar 15, 2023

@zakkak and @galderz adding --initialize-at-run-time=com.squareup.wire.schema.RootKt argument is required, otherwise my application fails to compile natively indicating that it must be added. The problem is that when --link-at-build-time argument is added then native compiler ignores the other argument and fails with same error as if the first argument had not been passed.

My application only works if --initialize-at-run-time=com.squareup.wire.schema.RootKt argument is added and --link-at-build-time is not added.

The problem is that currently quarkus almost always adds --link-at-build-time argument, and the only way I found to stop it from adding it is to add the dependency on: quarkus-reactive-oracle-client

@zakkak zakkak added the triage/needs-reproducer We are waiting for a reproducer. label Mar 16, 2023
@zakkak
Copy link
Contributor

zakkak commented Mar 16, 2023

@hernael Can you please let us know if you tried following the guide I mention in #30528 (comment) and #30528 (comment)?

For further help (if the guide doesn't help you resolve the issue) we will also need a reproducer (i.e. a maven/gradle project reproducing the error).

@galderz
Copy link
Member

galderz commented Mar 17, 2023

@zakkak and @galderz adding --initialize-at-run-time=com.squareup.wire.schema.RootKt argument is required, otherwise my application fails to compile natively indicating that it must be added. The problem is that when --link-at-build-time argument is added then native compiler ignores the other argument and fails with same error as if the first argument had not been passed.

My application only works if --initialize-at-run-time=com.squareup.wire.schema.RootKt argument is added and --link-at-build-time is not added.

^ That sounds odd. By default GraalVM initializes classes at runtime unless you specify which classes to initialize at build time. What --link-at-build-time does is change the default so that all classes are initialized at build time and only those specified otherwise are initialized at runtime. Hence, if --link-at-build-time is not added, there would be no need to add any --initialize-at-run-time for that class, unless there's some other thing at play here.

The problem is that currently quarkus almost always adds --link-at-build-time argument, and the only way I found to stop it from adding it is to add the dependency on: quarkus-reactive-oracle-client

That is not a "problem". It's designed that way. So far all the issues we are aware about build time initialized classes can be solved by marking the necessary classes to be initialized at runtime. To reiterate @zakkak said, we can't help further without a reproducer or some more tangible information from you (see previous comments).

@galderz
Copy link
Member

galderz commented Mar 17, 2023

One more thing you can try if you're feeling adventurous: download a GraalVM 23.0 snapshot and run with -H:+UseNewExperimentalClassInitialization and see if your odd case is solved that way alternatively (see details).

@zakkak
Copy link
Contributor

zakkak commented Mar 17, 2023

^ That sounds odd. By default GraalVM initializes classes at runtime unless you specify which classes to initialize at build time. What --link-at-build-time does is change the default so that all classes are initialized at build time and only those specified otherwise are initialized at runtime. Hence, if --link-at-build-time is not added, there would be no need to add any --initialize-at-run-time for that class, unless there's some other thing at play here.

@galderz that's not true.

The build time initialization is done in

overallCatch.invokeStaticMethod(BUILD_TIME_INITIALIZATION,
overallCatch.marshalAsArray(String.class, overallCatch.load(""))); // empty string means initialize everything

--link-at-build-time is not related to build-time initialization. --link-at-build-time essentially instructs GraalVM/Mandrel to fail if a reachable (according to the static analysis) class is not available on the classpath at build time (regardless if the said class is run-time or build-time initialized).

To my understanding this issue is not a run-time vs build-time initialization issue, but an incomplete classpath initialization issue. https://quarkus.io/version/main/guides/native-reference#i-get-a-analysiserrorparsingerror-when-building-a-native-executable-due-to-an-unresolvedelementexception-what-can-i-do is meant to help developers address such issues.

@galderz
Copy link
Member

galderz commented Mar 20, 2023

Ah yes, thx for correcting me @zakkak :)

@galderz
Copy link
Member

galderz commented Mar 31, 2023

@hernael Have you checked where the jar that contains okio.Options.Companion is and what kind of dependency com.squareup.wire.schema.RootKt has on it? Even if the class is not really used by your application, adding the jar that contains the okio.Options.Companion version that com.squareup.wire.schema.RootKt expects to the classpath should work.

@geoand
Copy link
Contributor

geoand commented May 12, 2023

Closing for lack of feedback

@geoand geoand closed this as completed May 12, 2023
@floka94
Copy link

floka94 commented Jul 13, 2023

@galderz @geoand Still have the same error when using:

        <dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>6.7.0</version>
        </dependency>

Error:

Caused by: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: javax.ws.rs.core.Context. This error is reported at image build time 
because class org.glassfish.jersey.inject.hk2.ContextInjectionResolverImpl is registered for linking at image build time by command line

I tried to set --initialize-at-run-time in application.properties but no success.

quarkus.native.additional-build-args=--initialize-at-run-time=org.glassfish.jersey.inject.hk2.ContextInjectionResolverImpl

@galderz
Copy link
Member

galderz commented Jul 18, 2023

One more thing you can try if you're feeling adventurous: download a GraalVM 23.0 snapshot and run with -H:+UseNewExperimentalClassInitialization and see if your odd case is solved that way alternatively (see details).

@floka94 ^

@galderz
Copy link
Member

galderz commented Jul 18, 2023

Actually, the new class initialization method is on by default on master graal master since today. You can wait a few days, download a nightly build from here and you don't have to pass any new parameters to try the new class initialization mechanism.

@floka94
Copy link

floka94 commented Jul 18, 2023

Thx, i will try!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/mandrel kind/bug Something isn't working triage/needs-reproducer We are waiting for a reproducer.
Projects
None yet
Development

No branches or pull requests

8 participants