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

Karm Michal Babacek duke at openjdk.org
Wed Jul 24 12:48:34 UTC 2024


On Mon, 15 Jul 2024 19:11:38 GMT, Phil Race <prr at openjdk.org> wrote:

>> Karm Michal Babacek has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Treats missing class as a fatal error
>
> There is nothing in this PR that I would accept. It should be withdrawn.

Hello @prrace 

TBH, I got somewhat bewildered by your comments on how this PR makes no sense. Then I realized I might have been erroneously treating the `AWTIsHeadless` function's contents as correct, merely building on the previous error.

If you take a look at the flow of `awt_LoadLibrary.c`, my problem with it is that errors originating in `AWTIsHeadless` are reported way later in `AWT_OnLoad` and that is wrong.  

`awt_LoadLibrary.c`:
![JDK-pr-20169-drawing](https://github.com/user-attachments/assets/d0024ecc-ba12-4f53-b616-d370196d6cc9)

# Previous fix

So I made this PR, thinking that for some headless JDK distributions it is O.K. to be entirely missing `java/awt/GraphicsEnvironment` class or `isHeadless` method.


@@ -62,15 +62,24 @@ JNIEXPORT jboolean JNICALL AWTIsHeadless() {
         graphicsEnvClass = (*env)->FindClass(env,
                                              "java/awt/GraphicsEnvironment");
         if (graphicsEnvClass == NULL) {
+            // Not finding the class is not necessarily an error.
+            if ((*env)->ExceptionCheck(env)) {
+                (*env)->ExceptionClear(env);
+            }
             return JNI_TRUE;
         }
         headlessFn = (*env)->GetStaticMethodID(env,
                                                graphicsEnvClass, "isHeadless", "()Z");
         if (headlessFn == NULL) {
+            // If we can't find the method, we assume headless mode.
+            if ((*env)->ExceptionCheck(env)) {
+                (*env)->ExceptionClear(env);
+            }
             return JNI_TRUE;
         }
         isHeadless = (*env)->CallStaticBooleanMethod(env, graphicsEnvClass,
                                                      headlessFn);
+        // If an exception occurred, we assume headless mode.
         if ((*env)->ExceptionCheck(env)) {
             (*env)->ExceptionClear(env);
             return JNI_TRUE;


# New fix

The new fix I propose treats the missing class or missing method as fatal errors. The crash makes sense, the error message is correct:


$ ./target/imageio   -Djava.awt.headless=true
Fatal error reported via JNI: java/awt/GraphicsEnvironment class not found

Printing instructions (ip=0x000000000048f8d9):
...


It's a little more invasive though:


diff --git a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
index 0fc44bfca71..7ef6dab8682 100644
--- a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
+++ b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
@@ -43,6 +43,12 @@
 #define VERBOSE_AWT_DEBUG
 #endif
 
+#define CHECK_EXCEPTION_FATAL(env, message) \
+    if ((*env)->ExceptionCheck(env)) { \
+        (*env)->ExceptionClear(env); \
+        (*env)->FatalError(env, message); \
+    }
+
 static void *awtHandle = NULL;
 
 typedef jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved);
@@ -61,25 +67,13 @@ JNIEXPORT jboolean JNICALL AWTIsHeadless() {
         env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
         graphicsEnvClass = (*env)->FindClass(env,
                                              "java/awt/GraphicsEnvironment");
-        if (graphicsEnvClass == NULL) {
-            // Not finding the class is not necessarily an error.
-            if ((*env)->ExceptionCheck(env)) {
-                (*env)->ExceptionClear(env);
-            }
-            return JNI_TRUE;
-        }
+        CHECK_EXCEPTION_FATAL(env, "java/awt/GraphicsEnvironment class not found");
         headlessFn = (*env)->GetStaticMethodID(env,
                                                graphicsEnvClass, "isHeadless", "()Z");
-        if (headlessFn == NULL) {
-            // If we can't find the method, we assume headless mode.
-            if ((*env)->ExceptionCheck(env)) {
-                (*env)->ExceptionClear(env);
-            }
-            return JNI_TRUE;
-        }
+        CHECK_EXCEPTION_FATAL(env, "isHeadless method not found");
         isHeadless = (*env)->CallStaticBooleanMethod(env, graphicsEnvClass,
                                                      headlessFn);
-        // If an exception occurred, we assume headless mode.
+        // If an exception occurred, we assume headless mode and carry on.
         if ((*env)->ExceptionCheck(env)) {
             (*env)->ExceptionClear(env);
             return JNI_TRUE;
@@ -88,12 +82,6 @@ JNIEXPORT jboolean JNICALL AWTIsHeadless() {
     return isHeadless;
 }
 
-#define CHECK_EXCEPTION_FATAL(env, message) \
-    if ((*env)->ExceptionCheck(env)) { \
-        (*env)->ExceptionClear(env); \
-        (*env)->FatalError(env, message); \
-    }
-
 /*
  * Pathnames to the various awt toolkits
  */


Thanks for your time. I hope the PR makes more sense now or at least that I managed to get my point across.

If you think there is a better way to handle it, tell me and I'll do it. I don't dwell on a particular implementation, I merely want the misleading error gone.

Thx
K.

> src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c line 65:
> 
>> 63:                                              "java/awt/GraphicsEnvironment");
>> 64:         if (graphicsEnvClass == NULL) {
>> 65:             // Not finding the class is not necessarily an error.
> 
> I can't see how that comment can possibly be true. This change makes no sense.

See [comment](https://github.com/openjdk/jdk/pull/20169#issuecomment-2247823182), please.

> src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c line 83:
> 
>> 81:                                                      headlessFn);
>> 82:         // If an exception occurred, we assume headless mode.
>> 83:         if ((*env)->ExceptionCheck(env)) {
> 
> I don't like this at all.

See [comment](https://github.com/openjdk/jdk/pull/20169#issuecomment-2247823182), please.

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

PR Comment: https://git.openjdk.org/jdk/pull/20169#issuecomment-2247823182
PR Review Comment: https://git.openjdk.org/jdk/pull/20169#discussion_r1689731774
PR Review Comment: https://git.openjdk.org/jdk/pull/20169#discussion_r1689731419


More information about the client-libs-dev mailing list