changeset 10401:98e76c78f04f jdk-9+164

8177751: Update FX implementation to prepare for renaming of Module and Layer classes Reviewed-by: jgiles, mchung, ddhill, vadim
author prr
date Wed, 29 Mar 2017 15:56:53 -0700
parents 9c7bfb6de43c
children d45bffd48779 aa6114dd876c
files modules/javafx.fxml/src/main/java/javafx/fxml/FXML.java modules/javafx.graphics/src/main/java/com/sun/javafx/application/LauncherImpl.java modules/javafx.graphics/src/main/java/com/sun/javafx/application/ModuleAccess.java modules/javafx.graphics/src/main/java/javafx/application/Application.java modules/javafx.web/src/test/java/test/javafx/scene/web/TestBase.java
diffstat 5 files changed, 135 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.fxml/src/main/java/javafx/fxml/FXML.java	Wed Mar 29 09:44:49 2017 +1300
+++ b/modules/javafx.fxml/src/main/java/javafx/fxml/FXML.java	Wed Mar 29 15:56:53 2017 -0700
@@ -30,19 +30,18 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.lang.module.ModuleDescriptor;
-import java.lang.reflect.Module;
 
 /**
  * Annotation that tags a field or method as accessible to markup.
  * If the object being annotated is in a named module then it must
  * be reflectively accessible to the {@code javafx.fxml} module.
  * An object is reflectively accessible if the module containing that
- * object {@link Module#isOpen opens} the containing package to the
+ * object opens (see {@code Module.isOpen}) the containing package to the
  * {@code javafx.fxml} module, either in its {@link ModuleDescriptor}
  * (e.g., in its module-info.class) or by calling {@link Module#addOpens}.
  * An object is also reflectively accessible if it is declared as a public
  * member, is in a public class, and the module containing that class
- * {@link Module#isExported(String,Module) exports}
+ * exports (see {@code Module.isExported(String,Module)})
  * the containing package to the {@code javafx.fxml} module.
  * If the object is not reflectively accessible to the {@code javafx.fxml}
  * module, then the {@link FXMLLoader} will fail with an
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/application/LauncherImpl.java	Wed Mar 29 09:44:49 2017 +1300
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/application/LauncherImpl.java	Wed Mar 29 15:56:53 2017 -0700
@@ -35,9 +35,7 @@
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Layer;
 import java.lang.reflect.Method;
-import java.lang.reflect.Module;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -256,7 +254,7 @@
         String preloaderClassName = null;
         String[] appArgs = args;
         ClassLoader appLoader = null;
-        Module mainModule = null;
+        ModuleAccess mainModule = null;
 
         if (launchMode.equals(LAUNCH_MODE_JAR)) {
             Attributes jarAttrs = getJarAttributes(launchName);
@@ -328,14 +326,7 @@
                 mainClassName = launchName.substring(i+1);
             }
 
-            // main module is in the boot layer
-            Layer layer = Layer.boot();
-            Optional<Module> om = layer.findModule(moduleName);
-            if (!om.isPresent()) {
-                // should not happen
-                throw new InternalError("Module " + moduleName + " not in boot Layer");
-            }
-            mainModule = om.get();
+            mainModule = ModuleAccess.load(moduleName);
 
             // get main class from module descriptor
             if (mainClassName == null) {
@@ -369,7 +360,7 @@
 
                 // then invoke the second part of this launcher using reflection
                 Method lawa = launcherClass.getMethod("launchApplicationWithArgs",
-                        new Class[] { Module.class, String.class, String.class, (new String[0]).getClass()});
+                        new Class[] { ModuleAccess.class, String.class, String.class, (new String[0]).getClass()});
 
                 // set the thread context class loader before we continue, or it won't load properly
                 Thread.currentThread().setContextClassLoader(appLoader);
@@ -385,7 +376,7 @@
     // wrapper for Class.forName that handles cases where diacritical marks in the name
     // cause the class to not be loaded, also largely copied from LauncherHelper.java
     // this method returns null if the class cannot be loaded
-    private static Class<?> loadClass(final Module mainModule, final String className) {
+    private static Class<?> loadClass(final ModuleAccess mainModule, final String className) {
         Class<?> clz = null;
         final ClassLoader loader = Thread.currentThread().getContextClassLoader();
 
@@ -394,7 +385,7 @@
         // a MF_JAVAFX_CLASS_PATH attribute which is deprecated
 
         if (mainModule != null) {
-            clz = Class.forName(mainModule, className);
+            clz = mainModule.classForName(className);
         } else {
             try {
                 clz = Class.forName(className, true, loader);
@@ -408,7 +399,7 @@
             String cn = Normalizer.normalize(className, Normalizer.Form.NFC);
 
             if (mainModule != null) {
-                clz = Class.forName(mainModule, cn);
+                clz = mainModule.classForName(cn);
             } else {
                 try {
                     clz = Class.forName(cn, true, loader);
@@ -420,7 +411,7 @@
     }
 
     // Must be public since we could be called from a different class loader
-    public static void launchApplicationWithArgs(final Module mainModule,
+    public static void launchApplicationWithArgs(final ModuleAccess mainModule,
             final String mainClassName,
             final String preloaderClassName, String[] args) {
         try {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/application/ModuleAccess.java	Wed Mar 29 15:56:53 2017 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017, 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 com.sun.javafx.application;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+public final class ModuleAccess {
+
+    private final Object module;
+    private ModuleAccess(Object m) {
+        this.module = m;
+    }
+
+    ModuleDescriptor getDescriptor() {
+        try {
+            return (ModuleDescriptor) getDescriptorMethod.invoke(module);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    String getName() {
+        try {
+            return (String) getModuleNameMethod.invoke(module);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    Class<?> classForName(String name) {
+        try {
+            return (Class<?>) classForNameMethod.invoke(null, module, name);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    static ModuleAccess load(String moduleName) {
+        // main module is in the boot layer
+        try {
+            Object layer = bootLayerMethod.invoke(null);
+
+            Optional<?> om =
+                (Optional<?>)findModuleMethod.invoke(layer, moduleName);
+            if (!om.isPresent()) {
+                // should not happen
+                throw new
+                   InternalError("Module " + moduleName + " not in boot Layer");
+            }
+            return new ModuleAccess(om.get());
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private static final Method bootLayerMethod;
+    private static final Method getModuleNameMethod;
+    private static final Method findModuleMethod;
+    private static final Method getDescriptorMethod;
+    private static final Method classForNameMethod;
+
+    static {
+        Class<?> cModuleClass = null;
+        Method mGetModule = null;
+        Method mGetLayer = null;
+        Method mGetDescriptor = null;
+        Method mGetName = null;
+        Method mBootLayers = null;
+        Method mfindModule = null;
+        Method mClassForName = null;
+
+        try {
+            mGetModule = Class.class.getMethod("getModule");
+            cModuleClass = mGetModule.getReturnType();
+            mGetLayer = cModuleClass.getMethod("getLayer");
+            mGetDescriptor = cModuleClass.getMethod("getDescriptor");
+            mGetName = cModuleClass.getMethod("getName");
+
+            Class<?> layerClass = mGetLayer.getReturnType();
+            mBootLayers = layerClass.getMethod("boot");
+            mfindModule = layerClass.getMethod("findModule", String.class);
+
+            mClassForName =
+                Class.class.getMethod("forName", cModuleClass, String.class);
+
+        } catch (NoSuchMethodException e) {
+            throw new InternalError("Module reflection failed", e);
+        }
+
+        bootLayerMethod = mBootLayers;
+        getModuleNameMethod = mGetName;
+        getDescriptorMethod = mGetDescriptor;
+        findModuleMethod = mfindModule;
+        classForNameMethod = mClassForName;
+    }
+}
--- a/modules/javafx.graphics/src/main/java/javafx/application/Application.java	Wed Mar 29 09:44:49 2017 +1300
+++ b/modules/javafx.graphics/src/main/java/javafx/application/Application.java	Wed Mar 29 15:56:53 2017 -0700
@@ -25,7 +25,6 @@
 
 package javafx.application;
 
-import java.lang.reflect.Module;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.List;
@@ -69,7 +68,7 @@
  * that do nothing.</p>
  * <p>The {@code Application} subclass must be declared public, must have a
  * public no-argument constructor, and the
- * containing package must be {@link Module#isExported(String,Module) exported}
+ * containing package must be exported (see {@code Module.isExported(String,Module)})
  * to the {@code javafx.graphics} module.</p>
  *
  * <p>Calling {@link Platform#exit} is the preferred way to explicitly terminate
@@ -212,8 +211,8 @@
      * This is equivalent to launch(TheClass.class, args) where TheClass is the
      * immediately enclosing class of the method that called launch. It must
      * be a public subclass of Application with a public no-argument
-     * constructor, in a package that is
-     * {@link Module#isExported(String,Module) exported} to at least the
+     * constructor, in a package that is exported
+     * (see {@code Module.isExported(String,Module)}) to at least the
      * {@code javafx.graphics} module, or a RuntimeException will be thrown.
      *
      * <p>
--- a/modules/javafx.web/src/test/java/test/javafx/scene/web/TestBase.java	Wed Mar 29 09:44:49 2017 +1300
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/TestBase.java	Wed Mar 29 15:56:53 2017 -0700
@@ -295,7 +295,7 @@
     public boolean isJigsawMode() {
         Class clazz = null;
         try {
-            clazz = Class.forName("java.lang.reflect.Module", false, TestBase.class.getClassLoader());
+            clazz = Class.forName("java.lang.reflect.ModuleDescriptor", false, TestBase.class.getClassLoader());
         } catch (Exception e) { }
 
         return clazz != null;