< prev index next >

jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java

Print this page

        

@@ -37,14 +37,18 @@
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 
 import jdk.internal.misc.JavaNioAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.util.logging.LoggingSupport;
+
 import java.util.ArrayList;
 import java.util.List;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.PrivilegedAction;
+
 /**
  * ManagementFactoryHelper provides static factory methods to create
  * instances of the management interface.
  */
 public class ManagementFactoryHelper {

@@ -139,17 +143,21 @@
         }
         return result;
     }
 
     public static PlatformLoggingMXBean getPlatformLoggingMXBean() {
-        if (LoggingSupport.isAvailable()) {
+        if (LoggingMXBeanSupport.isAvailable()) {
             return PlatformLoggingImpl.instance;
         } else {
             return null;
         }
     }
 
+    public static boolean isPlatformLoggingMXBeanAvailable() {
+        return LoggingMXBeanSupport.isAvailable();
+    }
+
     /**
      * The logging MXBean object is an instance of
      * PlatformLoggingMXBean and java.util.logging.LoggingMXBean
      * but it can't directly implement two MXBean interfaces
      * as a compliant MXBean implements exactly one MXBean interface,

@@ -163,12 +171,48 @@
     */
     public interface LoggingMXBean
         extends PlatformLoggingMXBean, java.util.logging.LoggingMXBean {
     }
 
+    // This is a trick: if java.util.logging is not present then
+    // attempting to access something that implements
+    // java.util.logging.LoggingMXBean will trigger a CNFE.
+    // So we cannot directly call any static method or access any static field
+    // on PlatformLoggingImpl, as we would risk raising a CNFE.
+    // Instead we use this intermediate LoggingMXBeanSupport class to determine
+    // whether java.util.logging is present, and load the actual LoggingMXBean
+    // implementation.
+    //
+    static final class LoggingMXBeanSupport {
+        final static Object loggingImpl =
+                AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            @Override
+            public Object run() {
+                try {
+                    // create a LoggingProxyImpl instance when
+                    // java.util.logging classes exist
+                    Class<?> c = Class.forName("java.util.logging.Logging", true, null);
+                    Constructor<?> cons = c.getDeclaredConstructor();
+                    cons.setAccessible(true);
+                    return cons.newInstance();
+                } catch (ClassNotFoundException cnf) {
+                    return null;
+                } catch (NoSuchMethodException | InstantiationException
+                        | IllegalAccessException | InvocationTargetException e) {
+                    throw new AssertionError(e);
+                }
+            }});
+
+        static boolean isAvailable() {
+            return loggingImpl != null;
+        }
+    }
+
     static class PlatformLoggingImpl implements LoggingMXBean
     {
+        final static java.util.logging.LoggingMXBean impl =
+                (java.util.logging.LoggingMXBean) LoggingMXBeanSupport.loggingImpl;
         final static PlatformLoggingMXBean instance = new PlatformLoggingImpl();
         final static String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
 
         private volatile ObjectName objname;  // created lazily
         @Override

@@ -186,26 +230,26 @@
             return result;
         }
 
         @Override
         public java.util.List<String> getLoggerNames() {
-            return LoggingSupport.getLoggerNames();
+            return impl.getLoggerNames();
         }
 
         @Override
         public String getLoggerLevel(String loggerName) {
-            return LoggingSupport.getLoggerLevel(loggerName);
+            return impl.getLoggerLevel(loggerName);
         }
 
         @Override
         public void setLoggerLevel(String loggerName, String levelName) {
-            LoggingSupport.setLoggerLevel(loggerName, levelName);
+            impl.setLoggerLevel(loggerName, levelName);
         }
 
         @Override
         public String getParentLoggerName(String loggerName) {
-            return LoggingSupport.getParentLoggerName(loggerName);
+            return impl.getParentLoggerName(loggerName);
         }
     }
 
     private static List<BufferPoolMXBean> bufferPools = null;
     public static synchronized List<BufferPoolMXBean> getBufferPoolMXBeans() {
< prev index next >