8131061: Use of -Dcom.sun.management.snmp needs to be examined for modules
authorvtewari
Tue, 06 Sep 2016 14:11:12 +0530
changeset 40743 a775e4de954f
parent 40742 3697a4ff4721
child 40744 63f7e1b92f2a
8131061: Use of -Dcom.sun.management.snmp needs to be examined for modules Reviewed-by: mchung, dfuchs
jdk/src/java.management/share/classes/module-info.java
jdk/src/java.management/share/classes/sun/management/Agent.java
jdk/src/java.management/share/classes/sun/management/spi/AgentProvider.java
--- a/jdk/src/java.management/share/classes/module-info.java	Tue Sep 06 13:57:03 2016 +0530
+++ b/jdk/src/java.management/share/classes/module-info.java	Tue Sep 06 14:11:12 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -50,6 +50,7 @@
     uses javax.management.remote.JMXConnectorProvider;
     uses javax.management.remote.JMXConnectorServerProvider;
     uses sun.management.spi.PlatformMBeanProvider;
+    uses sun.management.spi.AgentProvider;
 
     provides javax.security.auth.spi.LoginModule
         with com.sun.jmx.remote.security.FileLoginModule;
--- a/jdk/src/java.management/share/classes/sun/management/Agent.java	Tue Sep 06 13:57:03 2016 +0530
+++ b/jdk/src/java.management/share/classes/sun/management/Agent.java	Tue Sep 06 14:11:12 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -31,17 +31,19 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
 import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.Properties;
 import java.util.ResourceBundle;
+import java.util.ServiceLoader;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
@@ -53,6 +55,7 @@
 import sun.management.jdp.JdpController;
 import sun.management.jdp.JdpException;
 import jdk.internal.vm.VMSupport;
+import sun.management.spi.AgentProvider;
 
 /**
  * This Agent is started by the VM when -Dcom.sun.management.snmp or
@@ -248,8 +251,8 @@
             "com.sun.management.enableThreadContentionMonitoring";
     private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
             "com.sun.management.jmxremote.localConnectorAddress";
-    private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME =
-            "sun.management.snmp.AdaptorBootstrap";
+    private static final String SNMP_AGENT_NAME =
+            "SnmpAgent";
 
     private static final String JDP_DEFAULT_ADDRESS = "224.0.23.178";
     private static final int JDP_DEFAULT_PORT = 7095;
@@ -429,7 +432,7 @@
 
         try {
             if (snmpPort != null) {
-                loadSnmpAgent(snmpPort, props);
+                loadSnmpAgent(props);
             }
 
             /*
@@ -554,28 +557,24 @@
         return mgmtProps;
     }
 
-    private static void loadSnmpAgent(String snmpPort, Properties props) {
-        try {
-            // invoke the following through reflection:
-            //     AdaptorBootstrap.initialize(snmpPort, props);
-            final Class<?> adaptorClass =
-                    Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME, true, null);
-            final Method initializeMethod =
-                    adaptorClass.getMethod("initialize",
-                    String.class, Properties.class);
-            initializeMethod.invoke(null, snmpPort, props);
-        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException x) {
-            // snmp runtime doesn't exist - initialization fails
-            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, x);
-        } catch (InvocationTargetException x) {
-            final Throwable cause = x.getCause();
-            if (cause instanceof RuntimeException) {
-                throw (RuntimeException) cause;
-            } else if (cause instanceof Error) {
-                throw (Error) cause;
-            }
-            // should not happen...
-            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, cause);
+    private static void loadSnmpAgent(Properties props) {
+        /*
+         * Load the jdk.snmp service
+         */
+        AgentProvider provider = AccessController.doPrivileged(
+            (PrivilegedAction<AgentProvider>) () -> {
+                for(AgentProvider aProvider : ServiceLoader.loadInstalled(AgentProvider.class)) {
+                    if(aProvider.getName().equals(SNMP_AGENT_NAME))
+                        return aProvider;
+                }
+                return null;
+            },  null
+        );
+
+        if (provider != null) {
+            provider.startAgent(props);
+         } else { // snmp runtime doesn't exist - initialization fails
+            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management/share/classes/sun/management/spi/AgentProvider.java	Tue Sep 06 14:11:12 2016 +0530
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, 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.management.spi;
+
+import java.util.Properties;
+
+/**
+ * Service interface for management agent
+ */
+public abstract class AgentProvider {
+
+    /**
+     * Instantiates a new AgentProvider.
+     *
+     * @throws SecurityException if the subclass (and calling code) does not
+     * have
+     * {@code RuntimePermission("sun.management.spi.AgentProvider.subclass")}
+     */
+    protected AgentProvider() {
+        this(checkSubclassPermission());
+    }
+
+    private AgentProvider(Void unused) {
+    }
+
+    private static Void checkSubclassPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission(AgentProvider.class.getName() + ".subclass"));
+        }
+        return null;
+    }
+
+    /**
+     * Gets the name of the agent provider.
+     *
+     * @return name of agent provider
+     */
+    public abstract String getName();
+
+    /**
+     * Initializes and starts the agent.
+     *
+     * @throws IllegalStateException if this agent has already been started.
+     */
+    public abstract void startAgent();
+
+    /**
+     * Initializes and starts the agent at given port and with given properties
+     *
+     * @param props environment variables for agent
+     *
+     * @throws IllegalStateException if this agent has already been started.
+     */
+    public abstract void startAgent(Properties props);
+
+    /**
+     * Checks if agent is started and not terminated.
+     *
+     * @return true if agent is running, false otherwise.
+     */
+    public abstract boolean isActive();
+
+    /**
+     * Stops this agent.
+     *
+     * @throws IllegalStateException if this agent is not started.
+     */
+    public abstract void stopAgent();
+}