RFR: 8336382: Fixes error reporting in loading AWT and fonts [v10]

Alexey Ivanov aivanov at openjdk.org
Mon Jan 20 21:26:42 UTC 2025


On Tue, 26 Nov 2024 15:11:58 GMT, Karm Michal Babacek <duke at openjdk.org> wrote:

>> If there is a problem with finding and calling e.g. `java/awt/GraphicsEnvironment` in `AWTIsHeadless`, the env' Exception remains set and it is not cleared. Later, that manifests as:
>> 
>>     Fatal error reported via JNI: Could not allocate library name
>> 
>> Which is misleading. The code path is perhaps rare in a normal JDK usage, but it has been complicating our users' bug reports in the GraalVM/native-image ecosystem for quite some time.
>> 
>> Instead of failing later indicating that the user has incorrectly configured JNI, it bails out very soon with a message that seems as if a jstring could not have been allocated. It sends users on wild goose chases where it appears `JNU_NewStringPlatform` calls failed,  e.g.
>> 
>> * https://github.com/oracle/graal/issues/9138
>> * https://github.com/oracle/graal/issues/8475
>> * https://github.com/oracle/graal/issues/9300
>> * https://github.com/quarkusio/quarkus/issues/31596
>> * https://github.com/graalvm/mandrel/issues/292
>> * https://github.com/Karm/mandrel-integration-tests/issues/262
>> 
>> This commit fixes the error reporting in the AWTIsHeadless.
>> 
>> Furthermore, when AOT compiled, there is little sense for having a JAVA_HOME, yet some parts of AWT code look for it to search fonts. In such case, an empty directory structure is enough to accommodate it, e.g.
>> 
>> /tmp/JAVA_HOME/
>> /tmp/JAVA_HOME/conf
>> /tmp/JAVA_HOME/conf/fonts
>> /tmp/JAVA_HOME/lib
>> 
>> The exception is somewhat cryptic for users again, merely stating:
>> 
>>     Exception in thread "main" java.io.IOException: Problem reading font data.
>>         at java.desktop at 22.0.1/java.awt.Font.createFont0(Font.java:1205)
>>         at java.desktop at 22.0.1/java.awt.Font.createFont(Font.java:1076)
>>         at imageio.Main.loadFonts(Main.java:139
>> 
>> Adding the cause there makes it clearer, i.e. that JAVA_HOME might be missing:
>> 
>>     Exception in thread "main" java.io.IOException: Problem reading font data.
>>         at java.desktop at 23-internal/java.awt.Font.createFont0(Font.java:1206)
>>         at java.desktop at 23-internal/java.awt.Font.createFont(Font.java:1076)
>>         at imageio.Main.loadFonts(Main.java:139)
>>         at imageio.Main.paintRectangles(Main.java:97)
>>         at imageio.Main.main(Main.java:195)
>>         at java.base at 23-internal/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
>>     Caused by: java.lang.Error: java.home property not set
>>         at java.desktop at 23-internal/sun.awt.FontConfiguration.findFontConfigF...
>
> Karm Michal Babacek has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Amended error message, doesn't clear exception

src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c line 70:

> 68:         graphicsEnvClass = (*env)->FindClass(env,
> 69:                                              "java/awt/GraphicsEnvironment");
> 70:         CHECK_EXCEPTION_FATAL(env, "FindClass java/awt/GraphicsEnvironment failed");

If `FindClass` fails to find the class, a `NoClassDefFoundError` should be raised. This function returns immediately (a value of `true`). The caller of this function should check if there's a pending exception and perform an appropriate action.

In this case, the function is called from

https://github.com/openjdk/jdk/blob/955bf185c38ec0fcedb0a549461fc85367b37fbb/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c#L130-L132

If there's a pending exception, it should bail out and let the exception be thrown on the Java side.

If it doesn't, the pending exception makes `JNU_NewStringPlatform` fail at

https://github.com/openjdk/jdk/blob/955bf185c38ec0fcedb0a549461fc85367b37fbb/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c#L149-L150

---

Ah! There's no Java code to catch the exception… `AWT_OnLoad` is essentially `JNI_OnLoad`. In this case, `CHECK_EXCEPTION_FATAL` seems right.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20169#discussion_r1922849674


More information about the client-libs-dev mailing list