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

Missing native-image hints for PWA icon #19123

Closed
javier-godoy opened this issue Apr 5, 2024 · 16 comments
Closed

Missing native-image hints for PWA icon #19123

javier-godoy opened this issue Apr 5, 2024 · 16 comments
Labels
investigation native-image Issues related to native image compilation, GraalVM

Comments

@javier-godoy
Copy link
Contributor

Description of the bug

Running a Vaadin 24.3.7 application with @PWA and a custom icon (located at src/main/resources/META-INF/resources/icons/icon.png), compiled into a native image using GraalVM 21 results in the following errors. Interestingly, the Tracing Agent did not provide the anticipated hints during initial testing.

java.lang.NoClassDefFoundError: Could not initialize class java.awt.GraphicsEnvironment$LocalGE
        at [email protected]/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:106) ~[addons-demos-24-native.exe:na]
        at [email protected]/java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1182) ~[addons-demos-24-native.exe:na]
        at com.vaadin.flow.server.PwaIcon.drawIconImage(PwaIcon.java:268) ~[na:na]
java.lang.NoSuchMethodError: sun.awt.windows.WToolkit.windowsSettingChange()V
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1341) ~[na:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1326) ~[na:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions.GetMethodID(JNIFunctions.java:431) ~[na:na]
        at [email protected]/sun.awt.windows.WToolkit.initIDs(Native Method) ~[na:na]
        at [email protected]/sun.awt.windows.WToolkit.<clinit>(WToolkit.java:190) ~[na:na]
        at [email protected]/sun.awt.Win32GraphicsEnvironment.<clinit>(Win32GraphicsEnvironment.java:60) ~[na:na]
        at [email protected]/sun.awt.PlatformGraphicsInfo.createGE(PlatformGraphicsInfo.java:34) ~[na:na]
        at [email protected]/java.awt.GraphicsEnvironment$LocalGE.createGE(GraphicsEnvironment.java:93) ~[na:na]
        at [email protected]/java.awt.GraphicsEnvironment$LocalGE.<clinit>(GraphicsEnvironment.java:84) ~[na:na]
        at [email protected]/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:106) ~[addons-demos-24-native.exe:na]
        at [email protected]/java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1182) ~[addons-demos-24-native.exe:na]
        at com.vaadin.flow.server.PwaIcon.drawIconImage(PwaIcon.java:268) ~[na:na]

#16307 also mentions the following hint, which in my case was produced by the Tracing Agent:

{
  "name":"sun.java2d.Disposer",
  "methods":[{"name":"addRecord","parameterTypes":["java.lang.Object","long","long"] }]
}

Expected behavior

In 2022 @mstahv said that "Vaadin don’t yet come with these hints", but now there is VaadinHintsRegistrar and the documentation does not mention a word about hints, so I'm inclined to think that I could expect it to work.

Icon generation in native apps seems to be a known issue, though #16307 (comment).

Minimal reproducible example

A Vaadin 24.3.7 application with @PWA and a custom icon.

Versions

  • Vaadin / Flow version: 24.3.7
  • Java version: GraalVM version 21.0.2+13.1
  • OS version: Windows 10.0.19045.4170
@mcollovati
Copy link
Collaborator

Looking at Quarkus AwtProcessor it seems that there have been some changes in GraalVM 23 related to AWT.
For example this block of code https://github.com/quarkusio/quarkus/blob/4b8a27a5d591841d579a1b8ea1041b5fa481e8cf/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java#L276-L287

that points to oracle/graal#4921.

Link to the Quarkus commit quarkusio/quarkus@a354621

@javier-godoy
Copy link
Contributor Author

In my case it was a Spring Boot application. I'm fine with maintaining the hints locally, but maybe they should be added to the framework.

@mcollovati
Copy link
Collaborator

mcollovati commented Apr 5, 2024

I mentioned the Quarkus class only because the hints in Flow were updated based on it

@javier-godoy
Copy link
Contributor Author

I was able to reproduce NoSuchMethodError: sun.awt.windows.WToolkit.windowsSettingChange()V by playing a sound in the browser:

//https://gist.github.com/literallylara/7ece1983fab47365108c47119afb51c7
//(C) Lara Sophie Schütt 2016, CC0 
for(var i=44100*0.1,d="";i--;)d+=String.fromCharCode(~~((Math.sin(i/44100*2*Math.PI*800)+1)*128)); 
bellSound = "data:Audio/WAV;base64,"+btoa("RIFFdataWAVEfmt "+atob("EAAAAAEAAQBErAAARKwAAAEACABkYXRh/////w==")+d);
new Audio(bellSound).play();

Collect Metadata with the Tracing Agent

  1. Start the application with Tracing Agent, open application in browser, terminate.
    jni-config before playing sound

  2. Start the application with Tracing Agent, open application in browser, open developer tools, execute script above, terminate.
    jni-config after playing sound

(Browser requests icons/icon-180x180.png when playing a sound)

Required hints

The required hints (in jni-config-after, but neither in jni-config-before, nor provided by VaadinBeanFactoryInitializationAotProcessor) are:

[
{
  "name":"java.awt.Component"
},
{
  "name":"java.awt.Font",
  "fields":[{"name":"name"}, {"name":"pData"}, {"name":"size"}, {"name":"style"}],
  "methods":[{"name":"getFont","parameterTypes":["java.lang.String"] }, {"name":"getFontPeer","parameterTypes":[] }]
},
{
  "name":"java.awt.desktop.UserSessionEvent$Reason",
  "fields":[{"name":"CONSOLE"}, {"name":"LOCK"}, {"name":"REMOTE"}, {"name":"UNSPECIFIED"}]
},
{
  "name":"sun.awt.AWTAutoShutdown",
  "methods":[{"name":"notifyToolkitThreadBusy","parameterTypes":[] }, {"name":"notifyToolkitThreadFree","parameterTypes":[] }]
},
{
  "name":"sun.awt.SunToolkit",
  "methods":[{"name":"isTouchKeyboardAutoShowEnabled","parameterTypes":[] }]
},
{
  "name":"sun.awt.Win32GraphicsEnvironment",
  "methods":[{"name":"dwmCompositionChanged","parameterTypes":["boolean"] }]
},
{
  "name":"sun.awt.image.SunVolatileImage",
  "fields":[{"name":"volSurfaceManager"}]
},
{
  "name":"sun.awt.image.VolatileSurfaceManager",
  "fields":[{"name":"sdCurrent"}]
},
{
  "name":"sun.awt.windows.WDesktopPeer",
  "methods":[{"name":"systemSleepCallback","parameterTypes":["boolean"] }, {"name":"userSessionCallback","parameterTypes":["boolean","java.awt.desktop.UserSessionEvent$Reason"] }]
},
{
  "name":"sun.awt.windows.WToolkit",
  "methods":[{"name":"displayChanged","parameterTypes":[] }, {"name":"windowsSettingChange","parameterTypes":[] }]
},
{
  "name":"sun.java2d.windows.WindowsFlags",
  "fields":[{"name":"d3dEnabled"}, {"name":"d3dSet"}, {"name":"offscreenSharingEnabled"}, {"name":"setHighDPIAware"}]
}
]

After adding these hints, I was able to play the sound in the native image, with no exceptions being logged when the icon is requested. Note that one of the hints is about sun.awt.Win32GraphicsEnvironment, so it's platform-specific.

So far, I've not been able to reproduce NoClassDefFoundError for java.awt.GraphicsEnvironment$LocalGE

Versions

Vaadin / Flow version: 24.3.7
Java version: GraalVM 22+36.1
OS version: Windows 10.0.19045.4170
Browser: Chrome 123.0.6312.88

@mshabarov mshabarov moved this from 🆕 Needs triage to 🔎 Investigation in Vaadin Flow bugs & maintenance (Vaadin 10+) Apr 9, 2024
@mshabarov mshabarov added the native-image Issues related to native image compilation, GraalVM label Oct 29, 2024
@mshabarov mshabarov moved this from 🟢Ready to Go to 🪵Product backlog in Vaadin Flow ongoing work (Vaadin 10+) Nov 11, 2024
@mcollovati
Copy link
Collaborator

This should have been fixed in recent Vaadin version.

@mcollovati
Copy link
Collaborator

Can't reproduce with 24.5

@mshabarov mshabarov self-assigned this Nov 25, 2024
@mshabarov
Copy link
Contributor

mshabarov commented Nov 26, 2024

I can't provide a complete proof that it has been tested due to encountering this issue: oracle/graal#4124, I have similar exceptions and I'm using macOS:

java.lang.UnsatisfiedLinkError: Can't load library: awt | java.library.path = [.]

also:

java.lang.NoClassDefFoundError: Could not initialize class javax.imageio.ImageIO

Tested with GraalVM 23.0.1, Vaadin 24.6.0.beta1 and Vaadin Spring Boot skeleton starter.
The original exceptions in the description seem to be related to awt as well.

I'd propose to close this ticket, likely it's a GraalVM issue that prevents to use PWA in Vaadin with native-image.

@github-project-automation github-project-automation bot moved this from 🔎 Investigation to ✅ Closed in Vaadin Flow bugs & maintenance (Vaadin 10+) Nov 26, 2024
@github-project-automation github-project-automation bot moved this from ⚒️ In progress to Done in Vaadin Flow ongoing work (Vaadin 10+) Nov 26, 2024
@caalador
Copy link
Contributor

caalador commented Nov 27, 2024

I'm getting the couldn't initialize class on Windows 11 also with GraalVM 23.0.1+11.1, Vaadin 24.5.5 (also 24.5-SNAPSHOT)

java.lang.NoClassDefFoundError: Could not initialize class java.awt.GraphicsEnvironment$LocalGE
        at [email protected]/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:104) ~[my-app.exe:na]
        at [email protected]/java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1182) ~[my-app.exe:na]
        at com.vaadin.flow.server.PwaIcon.drawIconImage(PwaIcon.java:268) ~[na:na]
        at com.vaadin.flow.server.PwaIcon.write(PwaIcon.java:249) ~[na:na]

This comes when the app is running and service worker requests icons/icon-144x144.png leading to console exception Error while trying to use the following icon from the Manifest: http://localhost:8080/icons/icon-144x144.png (Download error or resource isn't a valid image) can also be triggered with just requesting the icon from the browser for that url.

@mshabarov mshabarov reopened this Nov 27, 2024
@mshabarov mshabarov moved this from ✅ Closed to 🔖 Normal Priority (P2) in Vaadin Flow bugs & maintenance (Vaadin 10+) Nov 27, 2024
@mshabarov mshabarov moved this from Done to 🪵Product backlog in Vaadin Flow ongoing work (Vaadin 10+) Nov 27, 2024
@mshabarov mshabarov removed their assignment Nov 27, 2024
@mshabarov
Copy link
Contributor

#20516 to be tested if it helps to fix this issue with PWA icon.

@mshabarov mshabarov moved this from 🪵Product backlog to 🟢Ready to Go in Vaadin Flow ongoing work (Vaadin 10+) Nov 27, 2024
@caalador
Copy link
Contributor

Tested against 24.6-SNAPSHOT and there the exception is not thrown anymore when the images are pregenerated.

@mcollovati
Copy link
Collaborator

According to Quarkus code, it seems AWT integration is not yet working in native-image for Windows

https://github.com/quarkusio/quarkus/blob/4864b938f595154ff8c32b0a155d211274e75753/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java#L46C1-L52C1

    @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
    UnsupportedOSBuildItem osSupportCheck() {
        return new UnsupportedOSBuildItem(WINDOWS,
                "Windows AWT integration is not ready in native-image and would result in " +
                        "java.lang.UnsatisfiedLinkError: no awt in java.library.path.");
    }

@mstahv
Copy link
Member

mstahv commented Nov 27, 2024

Could we just try to fix this "properly"? To me the AWT usage at runtime sounds like a design bug we should fix. It makes some raster images scaling? Shouldn't that be done when doing a production build of the client bundle?

@mcollovati
Copy link
Collaborator

Could we just try to fix this "properly"? To me the AWT usage at runtime sounds like a design bug we should fix. It makes some raster images scaling? Shouldn't that be done when doing a production build of the client bundle?

#20516 generates PWA icons at build time

@mstahv
Copy link
Member

mstahv commented Nov 27, 2024

Ah, excellent, so only trying to get it work in older branches?

@mshabarov
Copy link
Contributor

#20516 is not binary compatible, thus I'd not doing backport in a patch release, but rather in the future minor releases of V14 and V23.

@mshabarov
Copy link
Contributor

Closed based on #19123 (comment) testing.

@github-project-automation github-project-automation bot moved this from 🔖 Normal Priority (P2) to ✅ Closed in Vaadin Flow bugs & maintenance (Vaadin 10+) Nov 27, 2024
@github-project-automation github-project-automation bot moved this from 🟢Ready to Go to Done in Vaadin Flow ongoing work (Vaadin 10+) Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigation native-image Issues related to native image compilation, GraalVM
Development

No branches or pull requests

5 participants