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

Draft support for AWT image resizing #20148

Closed
wants to merge 3 commits into from

Conversation

galderz
Copy link
Member

@galderz galderz commented Sep 14, 2021

Draft PR to fix #19789.

To enable AWT image resizing, it does a couple of things:

  1. It instructs AWT and graphics related java, javax, and sun packages to be runtime initialized. The rest of the code is build time initialized as usual.
  2. It registers the necessary reflection and JNI items for things to work. These are derived from running the Java version of this Quarkus AWT image resize example with -agentlib:native-image-agent=config-output-dir=META-INF/native-image. I wonder if, rather than having Java2DProcessor in core/deployment, it would make more sense to have this as an extension? E.g. an extension/awt where we can put all this things and people optionally depend on it.

@galderz galderz requested review from Sanne and geoand September 14, 2021 15:39
@galderz
Copy link
Member Author

galderz commented Sep 14, 2021

The configuration files generated by native-image-agent can be found here for comparison.

@quarkus-bot
Copy link

quarkus-bot bot commented Sep 14, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building b937102

Status Name Step Failures Logs Raw logs
Initial JDK 11 Build Build Failures Logs Raw logs

Failures

⚙️ Initial JDK 11 Build #

- Failing: core/deployment 
! Skipped: core/test-extension/deployment core/test-extension/runtime devtools/bom-descriptor-json and 605 more

📦 core/deployment

Failed to execute goal net.revelc.code.formatter:formatter-maven-plugin:2.16.0:validate (default) on project quarkus-core-deployment: File '/home/runner/work/quarkus/quarkus/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java' has not been previously formatted. Please format file and commit before running validation!

@gastaldi
Copy link
Contributor

gastaldi commented Sep 14, 2021

+1, I think it makes total sense to introduce a AWT extension instead

@quarkus-bot
Copy link

quarkus-bot bot commented Sep 14, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building 1aad280

Status Name Step Failures Logs Raw logs
Native Tests - Main Build Failures Logs Raw logs
Native Tests - Misc2 Build Failures Logs Raw logs
Native Tests - Security3 Build Failures Logs Raw logs
Native Tests - Windows - hibernate-validator Build Failures Logs Raw logs

Full information is available in the Build summary check run.

Failures

⚙️ Native Tests - Main #

- Failing: integration-tests/main 

📦 integration-tests/main

io.quarkus.it.main.ImageIOITCase.testImageRead - More details - Source on GitHub

java.lang.AssertionError: 
1 expectation failed.
Response body doesn't match expectation.

⚙️ Native Tests - Misc2 #

- Failing: integration-tests/tika 

📦 integration-tests/tika

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-tika: Failed to build quarkus application


⚙️ Native Tests - Security3 #

- Failing: integration-tests/vault-agroal 

📦 integration-tests/vault-agroal

io.quarkus.vault.AgroalVaultITCase. - More details - Source on GitHub

java.lang.RuntimeException: Error waiting for test resource future to finish.
	at io.quarkus.test.common.TestResourceManager.waitForAllFutures(TestResourceManager.java:151)
	at io.quarkus.test.common.TestResourceManager.start(TestResourceManager.java:136)

io.quarkus.vault.AgroalVaultKv1ITCase. - More details - Source on GitHub

java.lang.RuntimeException: Error waiting for test resource future to finish.
	at io.quarkus.test.common.TestResourceManager.waitForAllFutures(TestResourceManager.java:151)
	at io.quarkus.test.common.TestResourceManager.start(TestResourceManager.java:136)

io.quarkus.vault.VaultKv1ITCase. - More details - Source on GitHub

java.lang.RuntimeException: Error waiting for test resource future to finish.
	at io.quarkus.test.common.TestResourceManager.waitForAllFutures(TestResourceManager.java:151)
	at io.quarkus.test.common.TestResourceManager.start(TestResourceManager.java:136)

⚙️ Native Tests - Windows - hibernate-validator #

- Failing: integration-tests/hibernate-validator 

📦 integration-tests/hibernate-validator

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-hibernate-validator: Failed to build quarkus application

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

I'm looking at the test failures.

@quarkus-bot
Copy link

quarkus-bot bot commented Sep 15, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building 1aad280

Status Name Step Failures Logs Raw logs
Native Tests - Main Build Failures Logs Raw logs
Native Tests - Misc2 Build Failures Logs Raw logs
Native Tests - Misc4 Build Failures Logs Raw logs
Native Tests - Windows - hibernate-validator Build Failures Logs Raw logs

Full information is available in the Build summary check run.

Failures

⚙️ Native Tests - Main #

- Failing: integration-tests/main 

📦 integration-tests/main

io.quarkus.it.main.ImageIOITCase.testImageRead - More details - Source on GitHub

java.lang.AssertionError: 
1 expectation failed.
Response body doesn't match expectation.

⚙️ Native Tests - Misc2 #

- Failing: integration-tests/tika 

📦 integration-tests/tika

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-tika: Failed to build quarkus application


⚙️ Native Tests - Misc4 #

- Failing: integration-tests/gradle 

📦 integration-tests/gradle

io.quarkus.gradle.nativeimage.BasicJavaNativeBuildIT.shouldBuildNativeImage line 27 - More details - Source on GitHub

java.lang.AssertionError: 
native-image build log is missing certain expected log messages:

⚙️ Native Tests - Windows - hibernate-validator #

- Failing: integration-tests/hibernate-validator 

📦 integration-tests/hibernate-validator

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-hibernate-validator: Failed to build quarkus application

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

Any ideas on how to deal with situations like this going forward?

sun.awt.image.ByteBandedRaster the class was requested to be initialized at run time (from the command line with 'sun.awt'). org.apache.pdfbox.pdmodel.PDDocument caused initialization of this class with the following trace:
	at sun.awt.image.ByteBandedRaster.<clinit>(ByteBandedRaster.java)
	at java.awt.image.Raster.createBandedRaster(Raster.java:730)
	at java.awt.image.Raster.createBandedRaster(Raster.java:417)
	at java.awt.image.Raster.createBandedRaster(Raster.java:324)
	at org.apache.pdfbox.pdmodel.PDDocument.<clinit>(PDDocument.java:107)

The issue is that if we push java.awt and related to be runtime init, any static initializers that use those need to be as well. So, seems to me there has to be some kind of way for extensions to say: please add this package(s) to be runtime initialized. How would that be achieved? @Sanne @geoand? For this experiment, I'm hacking NativeImageBuildStep to add a runtime init for org.apache.pdfbox.pdmodel package and see how far I get...

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

Any ideas on how to deal with situations like this going forward?

sun.awt.image.ByteBandedRaster the class was requested to be initialized at run time (from the command line with 'sun.awt'). org.apache.pdfbox.pdmodel.PDDocument caused initialization of this class with the following trace:
	at sun.awt.image.ByteBandedRaster.<clinit>(ByteBandedRaster.java)
	at java.awt.image.Raster.createBandedRaster(Raster.java:730)
	at java.awt.image.Raster.createBandedRaster(Raster.java:417)
	at java.awt.image.Raster.createBandedRaster(Raster.java:324)
	at org.apache.pdfbox.pdmodel.PDDocument.<clinit>(PDDocument.java:107)

The issue is that if we push java.awt and related to be runtime init, any static initializers that use those need to be as well. So, seems to me there has to be some kind of way for extensions to say: please add this package(s) to be runtime initialized. How would that be achieved? @Sanne @geoand? For this experiment, I'm hacking NativeImageBuildStep to add a runtime init for org.apache.pdfbox.pdmodel package and see how far I get...

It could be that, rather than using the ----initialize-at-run-time param, maybe it's easier for extensions to extend this if done via the programmatic API, akin to what @geoand did in a85c687#diff-bbea232d6b9141ad313658b2587f9ec7e23d90c93cd79994dd14086a769d52d0?

@Sanne
Copy link
Member

Sanne commented Sep 15, 2021

hi @galderz ! That would be RuntimeInitializedClassBuildItem

e.g. see

@BuildStep
void runtimeInitializeDriver(BuildProducer<RuntimeInitializedClassBuildItem> runtimeInitialized) {
//These re-implement all the "--initialize-at-build-time" arguments found in the native-image.properties :
runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.OracleDriver"));
runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.driver.OracleDriver"));

@geoand
Copy link
Contributor

geoand commented Sep 15, 2021

Unfortunately emitting RuntimeInitializedClassBuildItem won't work properly for packages. If we really do want to add that kind of support for packages, we'll need a new build item.

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

@geoand Could you work on that bit in parallel? I've just verified that with this, the Tika tests pass:

nativeImageArgs
    .add("--initialize-at-run-time=java.awt,javax.imageio,sun.awt,sun.java2d,sun.font,com.sun.imageio,org.apache.pdfbox,org.apache.poi.hssf.util,org.apache.poi.ss.format");

I just added org.apache.pdfbox,org.apache.poi.hssf.util,org.apache.poi.ss.format to the Java AWT/Graphics runtime init packages. As mentioned above, the extensions/awt would take care of using this new construct too. I'll take care of extensions/awt when CI is happy and the runtime init package item is available :)

@Sanne
Copy link
Member

Sanne commented Sep 15, 2021

I don't like the idea of offering an approach based on packages.

Couldn't we list the individual classes?

  1. for AWT this ismost likely a too wide net, I hope you can identify which ones really need it.
  2. we should encourage other extension writers to also be very selective about this

@geoand
Copy link
Contributor

geoand commented Sep 15, 2021

@geoand Could you work on that bit in parallel? I've just verified that with this, the Tika tests pass:

The current build item for classes results in org.graalvm.nativeimage.hosted.RuntimeClassInitialization#initializeAtRunTime being called, with the argument being classes.
The new build item would call the method that expects strings with the expectation that those strings are valid packages.

@Sanne
Copy link
Member

Sanne commented Sep 15, 2021

BTW @galderz : when it's a static well known list such as in this case, rather than relying on the build items which will dynamically generate an AutomaticFeature during the Quarkus build, you might as well just create an AutomaticFeature ... KISS and it would allow you to use packages - if you really must :)

@geoand
Copy link
Contributor

geoand commented Sep 15, 2021

I don't like the idea of offering an approach based on packages.

Couldn't we list the individual classes?

I completely agree - we should avoid doing the packages thing if possible.

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

I'm not going to track individual classes. My experiment will focus on packages. Feel free to further tune it for packages classes.

@galderz
Copy link
Member Author

galderz commented Sep 15, 2021

I've pushed a couple of commits to fix the main and tika tests.

Are the gradle native tests flaky? It seems to complain that [total] was not printed in the output... No idea, but I was unable to replicate locally. Gradle IT dependencies look outdated.

The native failures for hibernate validator on Windows don't know either. Let's see if they're still present after the update.

@geoand
Copy link
Contributor

geoand commented Sep 15, 2021

Some of the tests are flaky indeed :(

@maxandersen
Copy link
Member

this should be in a .awt/.java2d extension rather than in quarkus core should it not? then we can also mark it experimental :)

@quarkus-bot
Copy link

quarkus-bot bot commented Sep 15, 2021

Failing Jobs - Building 9d5d2ab

Status Name Step Failures Logs Raw logs
JVM Tests - JDK 11 Build ⚠️ Check → Logs Raw logs
JVM Tests - JDK 11 Windows Build Failures Logs Raw logs
JVM Tests - JDK 16 Build Failures Logs Raw logs
Native Tests - Windows - hibernate-validator Build Failures Logs Raw logs

Full information is available in the Build summary check run.

Failures

⚙️ JVM Tests - JDK 11 Windows #

- Failing: extensions/amazon-lambda/deployment 
! Skipped: docs extensions/amazon-lambda-http/deployment extensions/amazon-lambda-rest/deployment and 6 more

📦 extensions/amazon-lambda/deployment

io.quarkus.amazon.lambda.deployment.testing.LambdaDevServicesContinuousTestingTestCase.testLambda line 41 - More details - Source on GitHub

org.opentest4j.AssertionFailedError: expected: <0> but was: <1>
	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
	at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)

⚙️ JVM Tests - JDK 16 #

📦 extensions/amazon-lambda/deployment

io.quarkus.amazon.lambda.deployment.testing.LambdaDevServicesContinuousTestingTestCase.testLambda line 41 - More details - Source on GitHub

org.opentest4j.AssertionFailedError: expected: <0> but was: <1>
	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
	at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)

⚙️ Native Tests - Windows - hibernate-validator #

- Failing: integration-tests/hibernate-validator 

📦 integration-tests/hibernate-validator

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-hibernate-validator: Failed to build quarkus application

@gastaldi
Copy link
Contributor

Superseded by #20239

@gastaldi gastaldi closed this Sep 17, 2021
@quarkus-bot quarkus-bot bot added the triage/invalid This doesn't seem right label Sep 17, 2021
@galderz galderz deleted the t_awt_image_resize branch October 1, 2021 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core triage/invalid This doesn't seem right
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AWT Graphics does not seem to work in native image
5 participants