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
[GR-39408] Native-image fails to compile application due to unresolved reference although the said reference is unreachable #4652
Comments
This new combination is tricky. It imposes to have brotli4j available in the classpath as, because of the new HTTP compression feature from vert.x, it does now have a hard dependency on brotli4j. While in JVM mode, everything is fine, native compilation fails if not there. We have tried a few things to avoid the dependency, but we are hitting oracle/graal#4652.
This new combination is tricky. It imposes to have brotli4j available in the classpath as, because of the new HTTP compression feature from vert.x, it does now have a hard dependency on brotli4j. While in JVM mode, everything is fine, native compilation fails if not there. We have tried a few things to avoid the dependency, but we are hitting oracle/graal#4652.
This new combination is tricky. It imposes to have brotli4j available in the classpath as, because of the new HTTP compression feature from vert.x, it does now have a hard dependency on brotli4j. While in JVM mode, everything is fine, native compilation fails if not there. We have tried a few things to avoid the dependency, but we are hitting oracle/graal#4652.
ping @olpaw |
This is not a bug.
|
To further clarify, to allow |
Thanks for the comments @olpaw. The thing is that the error message references the access happening in Main.java:26 which is dead code, it doesn't complain for Main.java:14 where the class loading is attempted at build time.
This doesn't seem to trigger an error if I just remove line 26 in the same example. To try and rephrase my concern/expectation. If a library reflectively checks if classes |
Well, If I library does that, then, generally, you cannot reliably use
How about moving the setting of |
But to determine that
If the body of the if-then statement is empty and if the |
Sure, for things we control that would be fine. I am thinking about 3rd party libraries though, where it's much harder to convince maintainers to include GraalVM dependent code in contrast to asking for some refactoring, like a static initializer and some if-else guards.
FWIW replacing the if body with a print still doesn't reproduce the issue and the resulting binary behaves as expected. if (unreachableIsReachable()) {
// Unreachable.reached();
System.out.println("Unreachable.reached()");
} |
I assume this is because But none of that invalidates what I said about the semantics of |
OK, thanks for the clarifications @olpaw. If more such cases start appearing in the future we will consider creating a feature request for a less strict |
Note: The static initializer is actually in |
First, I want to start with my usual disclaimer that Why is this relevant? Even if we would simulate the class initializer successfully, the simulation results are not yet available during bytecode parsing, but only for the "inlining before analysis". But now to the actual issue, what is going on in the example: The What we could do is move the In summary, the current behavior is just what we organically grew into when we switched from "always throw all linkage errors at build time" to "allow the user to configure when linkage errors are thrown". It can be changed if there are enough good reasons for it. Which is my final question: are there example where this behavior is a problem in real-world code? |
Paul is incorrect on that. Neither with nor without class intialization at build time, the class initializer would be flagged by |
Ah, right. |
Hi @christianwimmer thanks for the detailed answer.
Without getting in an argument, the Quarkus team finds the benefits of using BTI globally to outweigh the drawbacks and there are currently no plans to move away from build-time-initializing anything that can be initialized at build time.
I intuitively believe that native-image should only report linking errors at image build time if they are still present after the static analysis (or even at a later stage if there is any chance of dropping the code generating the
That's a good point. Indeed, users will probably get confused if their code fails to build when they throw a
We originally hit this issue in a version bump of Vert.x and Netty in Quarkus. Netty uses pretty much the same technique as the reproducer used in this issue to figure out if Brotli4J is available at run time. More specifically, in the following code snippet:
A similar pattern/issue that we are aware of has been observed in Apache HttpComponents Client, see https://github.com/apache/httpcomponents-client/blob/5f6ad302ba94e039bb2084ac27fbac42044ef211/httpclient5/src/main/java/org/apache/hc/client5/http/entity/BrotliDecompressingEntity.java#L48-L55 and https://github.com/apache/httpcomponents-client/blob/5f6ad302ba94e039bb2084ac27fbac42044ef211/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ContentCompressionExec.java#L91-L110 |
Describe the issue
Despite the fact that the static analysis is able to figure out that a code path and thus a class is unreachable
native-image
will still complain for that class if it is unresolved at build time when using--link-at-build-time
.Steps to reproduce the issue
The last command will fail with:
Current work-around: Removing
--link-at-build-time
allows the build to succeed, but the build should not fail in the first place.UnresolvedElementException
should only be thrown when reachable, according to the static analysis, classes cannot be resolved.Describe GraalVM and your environment:
More details
Inspecting the compiler IR we see that for the given example:
Graal is able to figure out that
unreachableIsReachable()
is always false:Which means that there is no real need for Unreachable to be resolved at build time since it's not going to be added to the native image anyway.
PS: I am willing to implement a fix for this and would appreciate some guidance on how to approach it.
The text was updated successfully, but these errors were encountered: