8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class
authorprr
Mon, 29 Apr 2019 10:16:58 -0700
changeset 54865 99337f94b04d
parent 54864 6b1bac001aaf
child 54866 a7a436e080c1
8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class Reviewed-by: serb, bchristi
src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java
src/java.base/share/classes/jdk/internal/util/SystemProps.java
src/java.base/share/native/libjava/System.c
src/java.base/share/native/libjava/java_props.h
src/java.base/unix/native/libjava/java_props_md.c
src/java.base/windows/native/libjava/java_props_md.c
src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java
src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m
src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java
src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
test/jdk/java/awt/GraphicsEnvironment/CheckGraphicsEnvSystemProperty.java
--- a/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java	Mon Apr 29 10:16:58 2019 -0700
@@ -81,7 +81,6 @@
         "java.library.path",
         "java.io.tmpdir",
         "java.util.prefs.PreferencesFactory",
-        "sun.java2d.fontpath",
         "sun.boot.library.path",
     };
 
@@ -100,8 +99,6 @@
      * java.vm.specification.vendor
      * java.vm.specification.version
      * java.vm.vendor
-     * java.awt.graphicsenv
-     * java.awt.printerjob
      * user.language
      * sun.os.patch.level
      * sun.arch.data.model
--- a/src/java.base/share/classes/jdk/internal/util/SystemProps.java	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.base/share/classes/jdk/internal/util/SystemProps.java	Mon Apr 29 10:16:58 2019 -0700
@@ -92,7 +92,6 @@
         putIfAbsent(props, "socksNonProxyHosts", raw.propDefault(Raw._socksNonProxyHosts_NDX));
         putIfAbsent(props, "awt.toolkit", raw.propDefault(Raw._awt_toolkit_NDX));
         putIfAbsent(props, "java.awt.headless", raw.propDefault(Raw._java_awt_headless_NDX));
-        putIfAbsent(props, "java.awt.graphicsenv", raw.propDefault(Raw._java_awt_graphicsenv_NDX));
         putIfAbsent(props, "sun.arch.abi", raw.propDefault(Raw._sun_arch_abi_NDX));
         putIfAbsent(props, "sun.arch.data.model", raw.propDefault(Raw._sun_arch_data_model_NDX));
         putIfAbsent(props, "sun.os.patch.level", raw.propDefault(Raw._sun_os_patch_level_NDX));
@@ -206,8 +205,7 @@
         @Native private static final int _http_proxyPort_NDX = 1 + _http_proxyHost_NDX;
         @Native private static final int _https_proxyHost_NDX = 1 + _http_proxyPort_NDX;
         @Native private static final int _https_proxyPort_NDX = 1 + _https_proxyHost_NDX;
-        @Native private static final int _java_awt_graphicsenv_NDX = 1 + _https_proxyPort_NDX;
-        @Native private static final int _java_awt_headless_NDX = 1 + _java_awt_graphicsenv_NDX;
+        @Native private static final int _java_awt_headless_NDX = 1 + _https_proxyPort_NDX;
         @Native private static final int _java_io_tmpdir_NDX = 1 + _java_awt_headless_NDX;
         @Native private static final int _line_separator_NDX = 1 + _java_io_tmpdir_NDX;
         @Native private static final int _os_arch_NDX = 1 + _line_separator_NDX;
--- a/src/java.base/share/native/libjava/System.c	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.base/share/native/libjava/System.c	Mon Apr 29 10:16:58 2019 -0700
@@ -208,19 +208,6 @@
 
     PUTPROP(propArray, _awt_toolkit_NDX, sprops->awt_toolkit);
 
-    /* Java2D properties */
-    /* Note: java.awt.graphicsenv is an implementation private property which
-     * just happens to have a java.* name because it is referenced in
-     * a java.awt class. It is the mechanism by which the implementation
-     * finds the appropriate class in the JRE for the platform.
-     * It is explicitly not designed to be overridden by clients as
-     * a way of replacing the implementation class, and in any case
-     * the mechanism by which the class is loaded is constrained to only
-     * find and load classes that are part of the JRE.
-     * This property may be removed if that mechanism is redesigned
-     */
-    PUTPROP(propArray, _java_awt_graphicsenv_NDX, sprops->graphics_env);
-
     PUTPROP_PlatformString(propArray, _java_io_tmpdir_NDX, sprops->tmp_dir);
 
     PUTPROP_PlatformString(propArray, _user_name_NDX, sprops->user_name);
--- a/src/java.base/share/native/libjava/java_props.h	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.base/share/native/libjava/java_props.h	Mon Apr 29 10:16:58 2019 -0700
@@ -68,7 +68,6 @@
     char *sun_stdout_encoding;
     char *sun_stderr_encoding;
 
-    char *graphics_env;
     char *awt_toolkit;
 
     char *unicode_encoding;     /* The default endianness of unicode
--- a/src/java.base/unix/native/libjava/java_props_md.c	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.base/unix/native/libjava/java_props_md.c	Mon Apr 29 10:16:58 2019 -0700
@@ -396,14 +396,12 @@
 
     /* Java 2D/AWT properties */
 #ifdef MACOSX
-    // Always the same GraphicsEnvironment and Toolkit on Mac OS X
-    sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
+    // Always the same Toolkit on Mac OS X
     sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";
 
     // check if we're in a GUI login session and set java.awt.headless=true if not
     sprops.awt_headless = isInAquaSession() ? NULL : "true";
 #else
-    sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
     sprops.awt_toolkit = "sun.awt.X11.XToolkit";
 #endif
 
--- a/src/java.base/windows/native/libjava/java_props_md.c	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.base/windows/native/libjava/java_props_md.c	Mon Apr 29 10:16:58 2019 -0700
@@ -376,9 +376,6 @@
         sprops.tmp_dir = _wcsdup(tmpdir);
     }
 
-    /* Java2D properties */
-    sprops.graphics_env = "sun.awt.Win32GraphicsEnvironment";
-
     /* OS properties */
     {
         char buf[100];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java	Mon Apr 29 10:16:58 2019 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+import java.awt.GraphicsEnvironment;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class PlatformGraphicsInfo {
+
+    static {
+        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+            System.loadLibrary("awt");
+            return null;
+        });
+    }
+
+    public static GraphicsEnvironment createGE() {
+        return new CGraphicsEnvironment();
+    }
+
+    /**
+     * Returns true if the WindowServer is available, false otherwise.
+     *
+     * @return true if the WindowServer is available, false otherwise
+     */
+    public static native boolean isInAquaSession();
+
+    public static boolean getDefaultHeadlessProperty() {
+         return !isInAquaSession();
+    }
+
+    /*
+     * Called from java.awt.GraphicsEnvironment when
+     * getDefaultHeadlessProperty() has returned true, and
+     * the application has called an API that requires headful.
+     */
+    public static String getDefaultHeadlessMessage() {
+        return
+            "\nThe application is not running in a desktop session,\n" +
+            "but this program performed an operation which requires it.";
+    }
+
+}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Mon Apr 29 10:16:58 2019 -0700
@@ -105,6 +105,7 @@
 import sun.awt.CGraphicsConfig;
 import sun.awt.CGraphicsDevice;
 import sun.awt.LightweightFrame;
+import sun.awt.PlatformGraphicsInfo;
 import sun.awt.SunToolkit;
 import sun.awt.datatransfer.DataTransferer;
 import sun.awt.util.ThreadGroupUtils;
@@ -163,7 +164,9 @@
             }
         });
 
-        if (!GraphicsEnvironment.isHeadless() && !isInAquaSession()) {
+        if (!GraphicsEnvironment.isHeadless() &&
+            !PlatformGraphicsInfo.isInAquaSession())
+        {
             throw new AWTError("WindowServer is not available");
         }
 
@@ -864,13 +867,6 @@
      */
     public static native boolean isEmbedded();
 
-    /**
-     * Returns true if the WindowServer is available, false otherwise.
-     *
-     * @return true if the WindowServer is available, false otherwise
-     */
-    private static native boolean isInAquaSession();
-
     /*
      * Activates application ignoring other apps.
      */
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Mon Apr 29 10:16:58 2019 -0700
@@ -805,14 +805,14 @@
 }
 
 /*
- * Class:     sun_lwawt_macosx_LWCToolkit
+ * Class:     sun_awt_PlatformGraphicsInfo
  * Method:    isInAquaSession
  * Signature: ()Z
  */
 JNIEXPORT jboolean JNICALL
-Java_sun_lwawt_macosx_LWCToolkit_isInAquaSession
+Java_sun_awt_PlatformGraphicsInfo_isInAquaSession
 (JNIEnv *env, jclass klass) {
-    // copied from java.base/macosx/native/libjava/java_props_macosx.c
+    // originally from java.base/macosx/native/libjava/java_props_macosx.c
     // environment variable to bypass the aqua session check
     char *ev = getenv("AWT_FORCE_HEADFUL");
     if (ev && (strncasecmp(ev, "true", 4) == 0)) {
--- a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java	Sun Apr 28 12:34:49 2019 +0530
+++ b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java	Mon Apr 29 10:16:58 2019 -0700
@@ -31,6 +31,7 @@
 import java.security.PrivilegedAction;
 import java.util.Locale;
 
+import sun.awt.PlatformGraphicsInfo;
 import sun.font.FontManager;
 import sun.font.FontManagerFactory;
 import sun.java2d.HeadlessGraphicsEnvironment;
@@ -84,38 +85,14 @@
 
         /**
          * Creates and returns the GraphicsEnvironment, according to the
-         * system property 'java.awt.graphicsenv'.
+         * platform-specific proxy class.
          *
          * @return the graphics environment
          */
         private static GraphicsEnvironment createGE() {
-            GraphicsEnvironment ge;
-            String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null));
-            try {
-//              long t0 = System.currentTimeMillis();
-                Class<?> geCls;
-                try {
-                    // First we try if the bootstrap class loader finds the
-                    // requested class. This way we can avoid to run in a privileged
-                    // block.
-                    geCls = Class.forName(nm);
-                } catch (ClassNotFoundException ex) {
-                    // If the bootstrap class loader fails, we try again with the
-                    // application class loader.
-                    ClassLoader cl = ClassLoader.getSystemClassLoader();
-                    geCls = Class.forName(nm, true, cl);
-                }
-                ge = (GraphicsEnvironment)geCls.getConstructor().newInstance();
-//              long t1 = System.currentTimeMillis();
-//              System.out.println("GE creation took " + (t1-t0)+ "ms.");
-                if (isHeadless()) {
-                    ge = new HeadlessGraphicsEnvironment(ge);
-                }
-            } catch (ClassNotFoundException e) {
-                throw new Error("Could not find class: "+nm);
-            } catch (ReflectiveOperationException | IllegalArgumentException e) {
-                throw new Error("Could not instantiate Graphics Environment: "
-                        + nm);
+            GraphicsEnvironment ge = PlatformGraphicsInfo.createGE();
+            if (isHeadless()) {
+                ge = new HeadlessGraphicsEnvironment(ge);
             }
             return ge;
         }
@@ -155,8 +132,7 @@
             getHeadlessProperty(); // initialize the values
         }
         return defaultHeadless != Boolean.TRUE ? null :
-            "\nNo X11 DISPLAY variable was set, " +
-            "but this program performed an operation which requires it.";
+            PlatformGraphicsInfo.getDefaultHeadlessMessage();
     }
 
     /**
@@ -169,16 +145,8 @@
                 String nm = System.getProperty("java.awt.headless");
 
                 if (nm == null) {
-                    final String osName = System.getProperty("os.name");
-                    final String display = System.getenv("DISPLAY");
                     headless = defaultHeadless =
-                                ("Linux".equals(osName) ||
-                                 "SunOS".equals(osName) ||
-                                 "FreeBSD".equals(osName) ||
-                                 "NetBSD".equals(osName) ||
-                                 "OpenBSD".equals(osName) ||
-                                 "AIX".equals(osName)) &&
-                                 (display == null || display.trim().isEmpty());
+                        PlatformGraphicsInfo.getDefaultHeadlessProperty();
                 } else {
                     headless = Boolean.valueOf(nm);
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java	Mon Apr 29 10:16:58 2019 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+import java.awt.GraphicsEnvironment;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class PlatformGraphicsInfo {
+
+    public static GraphicsEnvironment createGE() {
+        return new X11GraphicsEnvironment();
+    }
+
+    /**
+      * Called from java.awt.GraphicsEnvironment when
+      * to check if on this platform, the JDK should default to
+      * headless mode, in the case the application did specify
+      * a value for the java.awt.headless system property.
+      */
+    public static boolean getDefaultHeadlessProperty() {
+        return
+            AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
+
+               final String display = System.getenv("DISPLAY");
+               return  display == null || display.trim().isEmpty();
+            });
+    }
+
+    /**
+      * Called from java.awt.GraphicsEnvironment when
+      * getDefaultHeadlessProperty() has returned true, and
+      * the application has called an API that requires headful.
+      */
+    public static String getDefaultHeadlessMessage() {
+        return
+            "\nNo X11 DISPLAY variable was set,\n" +
+            "but this program performed an operation which requires it.";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java	Mon Apr 29 10:16:58 2019 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+import java.awt.GraphicsEnvironment;
+
+public class PlatformGraphicsInfo {
+
+    public static GraphicsEnvironment createGE() {
+        return new Win32GraphicsEnvironment();
+    }
+
+    public static boolean getDefaultHeadlessProperty() {
+        // On Windows, we assume we can always create headful apps.
+        // Here is where we can add code that would actually check.
+        return false;
+    }
+
+    /*
+     * Called from java.awt.GraphicsEnvironment when
+     * getDefaultHeadlessProperty() has returned true, and
+     * the application has called an API that requires headful.
+     */
+    public static String getDefaultHeadlessMessage() {
+        return
+            "\nThe application does not have desktop access,\n" +
+            "but this program performed an operation which requires it.";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/GraphicsEnvironment/CheckGraphicsEnvSystemProperty.java	Mon Apr 29 10:16:58 2019 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8130266
+ * @summary verify the GraphicsEnvironmement implementation class name is not
+ *          polluting system properties
+ */
+
+public class CheckGraphicsEnvSystemProperty {
+
+     public static void main(String[] args) {
+         String geProp = System.getProperty("java.awt.graphicsenv");
+         if (geProp != null) {
+             throw new RuntimeException("geProp = " + geProp);
+         }
+     }
+}