-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
AWT extension fails native build because "Classes that should be initialized at run time got initialized during image building" #30908
Comments
@geoand This isn't a critical issue for my demo at LJC Live next week. As it turns out, AWT doesn't work right now on macOS (it may have never). It's on the GraalVM roadmap. |
Good to know, thanks for the update. |
I switched my demo app from creating thumbnails for pictures to converting pictures to PDF. That ain't using AWT. 😉 |
💪🏼 |
I changed my app now so the error won't show anymore. I'll provide new recreation steps tomorrow morning. |
@geoand @Karm I finally created a repo that demonstrates this bug. I updated the description accordingly. The application works from the IDE and when running as an uber JAR but fails the native build. The error doesn't show with light use of the AWT extension - say, instantiating an |
@ksilz thanks for the reproducer. I will take a look presently. (using my CentOS 8 Stream deck) |
Hello @ksilz, I had taken a look at the reproducer and I opened a PR fixing the project, see: ksilz/bug-quarkus-awt-extension#1 See the successful log on my machine (CentOS 8 Stream, amd64): This is not a bug, I would say. It's rather a fact of interacting with JDK's graphics libraries and native compilation. JDK's graphics libraries hold state after init, they are interwoven with JNI code that holds its own state too and we cannot have any of that at build time. We need to defer many related JDK classes to runtime init rather than build time init, we also need to allow for refclection at runtime and we need to set JNI access at runtime (e.g. a code in C decides to call some Java code via JNI). AWT extension does that heavy lifting for you in Quarkus, see mostly this code: https://github.com/quarkusio/quarkus/blob/main/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java It allows you create thumbnails or watermark images without any additional hassle, see e.g. this QuickStart: When you let net.coobird.thumbnailator in as a dependency, you opened the door for Thumbnailator trying to init some of those classes at build time, we definitely need to be deferred to runtime. What I did for you in the aforementioned PR is that I told the native-image compiler via the Quarkus option to defer those classes' init to runtime too. It will work just fine until something in Thumbnailator changes that could affect this area again. I will close this issue as it is not a Quarkus AWT extension bug. Feel free to reach out on Zulip or here again to discuss more though. |
...if you need that in many Quarkus apps and maintaining that list of classes becomes tedious, a tiny Thumbnailator Quarkus Extension might be in order. You can then use it as a dependency in your projects. |
@Karm Thank you for your feedback! Some questions.
|
Correct.
I wouldn't say it's an issue. It's a feature : ) The decision to go build-time-init first makes things more convoluted for Quarkus and Quarkus Extensions developers, yet it yields improved memory footprint, startup times and overall image size to users who code their apps using Quarkus. Ad GraalVM Reachability metadata: Quarkus doesn't use it. The additional metadata I provided in ksilz/bug-quarkus-awt-extension#1 form just a tiny tip of what would be needed, because Quarkus AWT extension does a lot on its own. You can take a look at this small demo I prepared: https://github.com/Karm/dev-null/blob/main/thumbsup/src/main/java/thumbsup/Main.java#L31
Correct. One would make a Quarkus Extension.
One can package JSON config and properties file META-INF/native-image/ as demonstrated in the example, i.e. if Thumbnailnator already had those files you as a user wouldn't have to fiddle with the agent. Such metadata cannot be specific to Quarkus though. Hope this helps. |
@Karm Thank you! You answered all my questions. |
@Karm sorry, two follow-ups to your answer on Quarkus defaulting to "build-time first initialization of classes".
|
Yes, GraalVM might choose to initialize a class at build time if it considers it safe. I'm not aware of a detailed explanation of this but you can see examples of when it initializes class at build time vs runtime in this test class. No, Quarkus does not do any checks to see if classes at safe to be build-time init. Having said all of this, a new class initialization strategy is currently being worked on GraalVM. A short description of this new strategy is that re-initialize at runtime would be the default. The aim is to get rid of most build time vs run time initialization errors. |
Details on the new class initialization strategy can be found here. |
@galderz Thank you! |
Describe the bug
I wrote a program that creates Thumbnails for images. It uses the Thumbnailator library. For native execution, Quarkus needs the AWT extension - it through a
Add AWT Quarkus extension to enable Java2D/ImageIO
without it. But building a native image with the AWT extension fails.Expected behavior
./mvnw clean install -Dnative
in my project completes.Actual behavior
./mvnw clean install -Dnative
in my project completes fails:How to Reproduce?
./mvnw clean install -Dnative
.Output of
uname -a
orver
Darwin m1x-773.local 22.3.0 Darwin Kernel Version 22.3.0: Thu Jan 5 20:48:54 PST 2023; root:xnu-8792.81.2~2/RELEASE_ARM64_T6000 arm64
Output of
java -version
openjdk version "17.0.5" 2022-10-18 OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08) OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.16.2.Final
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63) Maven home: /Users/karsten/.m2/wrapper/dists/apache-maven-3.8.6-bin/67568434/apache-maven-3.8.6 Java version: 17.0.5, vendor: GraalVM Community, runtime: /Users/karsten/.sdkman/candidates/java/22.3.r17-grl Default locale: en_US, platform encoding: UTF-8 OS name: "mac os x", version: "13.2", arch: "aarch64", family: "mac"
Additional information
No response
The text was updated successfully, but these errors were encountered: