changeset 1005:fa87de6b1ac3

6661448: Make the SNMP agent optional when OPENJDK=true and IMPORT_BINARY_PLUGS=false Reviewed-by: mchung, ohair
author dfuchs
date Thu, 12 Mar 2009 15:36:14 +0100
parents aa48deaf9af4
children e90ce2ac06a8
files make/com/sun/jmx/Makefile make/java/management/Makefile make/javax/management/Makefile make/sun/management/Makefile src/share/classes/sun/management/Agent.java test/com/sun/jmx/snmp/SnmpOidHashCode.java test/com/sun/jmx/snmp/TimeTicksWrapping.java
diffstat 7 files changed, 268 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/make/com/sun/jmx/Makefile	Mon Mar 09 09:56:58 2009 -0400
+++ b/make/com/sun/jmx/Makefile	Thu Mar 12 15:36:14 2009 +0100
@@ -41,7 +41,15 @@
 # Note : some targets are double colon rules and some single colon rules
 # within common included gmk files : that is why the following for loop
 # has been duplicated.
-SUBDIRS = snmp
+
+# When building the openjdk, build snmp only if importing binary plugs,
+ifdef OPENJDK
+  ifeq ($(IMPORT_BINARY_PLUGS),true)
+    SUBDIRS = snmp
+  endif
+else
+  SUBDIRS = snmp
+endif
 
 all build:
 	$(SUBDIRS-loop)
--- a/make/java/management/Makefile	Mon Mar 09 09:56:58 2009 -0400
+++ b/make/java/management/Makefile	Thu Mar 12 15:36:14 2009 +0100
@@ -46,6 +46,8 @@
 #
 include FILES_c.gmk
 
+# We don't need snmp here.
+AUTO_JAVA_PRUNE = snmp
 AUTO_FILES_JAVA_DIRS = java/lang/management com/sun/management sun/management
 
 include Exportedfiles.gmk
--- a/make/javax/management/Makefile	Mon Mar 09 09:56:58 2009 -0400
+++ b/make/javax/management/Makefile	Thu Mar 12 15:36:14 2009 +0100
@@ -35,6 +35,7 @@
 #
 # Files to compile
 #
+AUTO_JAVA_PRUNE = snmp
 AUTO_FILES_JAVA_DIRS = javax/management com/sun/jmx com/sun/management/jmx 
 
 #
--- a/make/sun/management/Makefile	Mon Mar 09 09:56:58 2009 -0400
+++ b/make/sun/management/Makefile	Thu Mar 12 15:36:14 2009 +0100
@@ -35,7 +35,16 @@
 
 all build:: properties aclfile jmxremotefiles
 
-SUBDIRS = snmp jmxremote
+# When building the openjdk, build snmp only if importing binary plugs,
+ifdef OPENJDK
+  ifeq ($(IMPORT_BINARY_PLUGS),true)
+    SUBDIRS = snmp
+  endif
+else
+  SUBDIRS = snmp
+endif
+SUBDIRS += jmxremote
+ 
 all build clean clobber::
 	$(SUBDIRS-loop)
 
--- a/src/share/classes/sun/management/Agent.java	Mon Mar 09 09:56:58 2009 -0400
+++ b/src/share/classes/sun/management/Agent.java	Thu Mar 12 15:36:14 2009 +0100
@@ -31,9 +31,9 @@
 import java.io.BufferedInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.text.MessageFormat;
 import java.util.Properties;
-import java.util.Enumeration;
 import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.lang.management.ManagementFactory;
@@ -41,7 +41,6 @@
 
 import javax.management.remote.JMXConnectorServer;
 
-import sun.management.snmp.AdaptorBootstrap;
 import sun.management.jmxremote.ConnectorBootstrap;
 import static sun.management.AgentConfigurationError.*;
 import sun.misc.VMSupport;
@@ -69,6 +68,9 @@
     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";
+
     // invoked by -javaagent or -Dcom.sun.management.agent.class
     public static void premain(String args) throws Exception {
         agentmain(args);
@@ -128,7 +130,7 @@
 
         try {
             if (snmpPort != null) {
-                AdaptorBootstrap.initialize(snmpPort, props);
+                loadSnmpAgent(snmpPort, props);
             }
 
             /*
@@ -204,6 +206,36 @@
         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 x) {
+            // The SNMP packages are not present: throws an exception.
+            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
+        } catch (NoSuchMethodException x) {
+            // should not happen...
+            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);
+        } catch (IllegalAccessException x) {
+            // should not happen...
+            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
+        }
+    }
+
     // read config file and initialize the properties
     private static void readConfiguration(String fname, Properties p) {
         if (fname == null) {
--- a/test/com/sun/jmx/snmp/SnmpOidHashCode.java	Mon Mar 09 09:56:58 2009 -0400
+++ b/test/com/sun/jmx/snmp/SnmpOidHashCode.java	Thu Mar 12 15:36:14 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  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
@@ -28,7 +28,8 @@
  * @build   SnmpOidHashCode
  * @run     main SnmpOidHashCode
  */
-import com.sun.jmx.snmp.SnmpOid;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 
 public class SnmpOidHashCode {
     public static final String[] oids = {
@@ -57,16 +58,81 @@
         ".39."+0xFFFFFFFFL
     };
 
+    // We use an SnmpOidBuilder in order to adapt this test case to a
+    // configuration where the SNMP packages are not present in rt.jar.
+    //
+    public static final class SnmpOidBuilder {
+        public static final String SNMP_OID_CLASS_NAME =
+            "com.sun.jmx.snmp.SnmpOid";
+        private static final Class<?> SNMP_OID_CLASS;
+        private static final Constructor<?> SNMP_OID_CTOR;
+        static {
+            Class<?> snmpOidClass;
+            try {
+                snmpOidClass =
+                    Class.forName(SNMP_OID_CLASS_NAME, true, null);
+            } catch (ClassNotFoundException x) {
+                snmpOidClass = null;
+                System.err.println("WARNING: can't load "+SNMP_OID_CLASS_NAME);
+            } catch (NoClassDefFoundError x) {
+                snmpOidClass = null;
+                System.err.println("WARNING: can't load "+SNMP_OID_CLASS_NAME);
+            }
+            SNMP_OID_CLASS = snmpOidClass;
+            if (SNMP_OID_CLASS != null) {
+                try {
+                  SNMP_OID_CTOR = snmpOidClass.getConstructor(String.class);
+                } catch (Exception x) {
+                    throw new ExceptionInInitializerError(x);
+                }
+            } else {
+                SNMP_OID_CTOR = null;
+            }
+        }
+
+        public static boolean isSnmpPresent() {
+            System.out.println(SnmpOidHashCode.class.getName()+
+                    ": Testing for SNMP Packages...");
+            return SNMP_OID_CLASS != null;
+        }
+
+        public static Object newSnmpOid(String oid)
+            throws InstantiationException,
+                   IllegalAccessException,
+                   InvocationTargetException {
+            return SNMP_OID_CTOR.newInstance(oid);
+        }
+
+    }
+
+    private static Object newSnmpOid(String oid) throws Exception {
+        try {
+            return SnmpOidBuilder.newSnmpOid(oid);
+        } catch (InvocationTargetException x) {
+            final Throwable cause = x.getCause();
+            if (cause instanceof Exception) throw (Exception)cause;
+            if (cause instanceof Error) throw (Error)cause;
+            throw x;
+        }
+    }
+
     public static void main(String args[]) {
+        if (!SnmpOidBuilder.isSnmpPresent()) {
+            System.err.println("WARNING: "+
+                    SnmpOidBuilder.SNMP_OID_CLASS_NAME+" not present.");
+            System.err.println(SnmpOidHashCode.class.getName()+
+                    ": test skipped.");
+            return;
+        }
         try {
             int errCount=0;
             int collisions=0;
             for (int i=0;i<oids.length;i++) {
                 System.out.println("Testing " + oids[i]);
-                final SnmpOid o1 = new SnmpOid(oids[i]);
+                final Object o1 = newSnmpOid(oids[i]);
                 final int startCount=errCount;
                 for (int j=0;j<oids.length;j++) {
-                    final SnmpOid o2 = new SnmpOid(oids[j]);
+                    final Object o2 = newSnmpOid(oids[j]);
                     if (o1.equals(o2)) {
                         if (!(oids[i].equals(oids[j]))) {
                             System.err.println("OIDs differ but " +
--- a/test/com/sun/jmx/snmp/TimeTicksWrapping.java	Mon Mar 09 09:56:58 2009 -0400
+++ b/test/com/sun/jmx/snmp/TimeTicksWrapping.java	Thu Mar 12 15:36:14 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  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
@@ -29,33 +29,158 @@
  * @build   TimeTicksWrapping
  * @run     main TimeTicksWrapping
  */
-import com.sun.jmx.snmp.SnmpTimeticks;
-import com.sun.jmx.snmp.SnmpUnsignedInt;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
 public class TimeTicksWrapping {
+    // We use an SnmpTimeticksBuilder in order to adapt this test case to a
+    // configuration where the SNMP packages are not present in rt.jar.
+    //
+    public static final class SnmpTimeticksBuilder {
+        public static final long   MAX_VALUE = 0x0ffffffffL;
+        public static final String SNMP_TIME_TICKS_CLASS_NAME =
+            "com.sun.jmx.snmp.SnmpTimeticks";
+        private static final Class<?> SNMP_TIME_TICKS_CLASS;
+        private static final Constructor<?> SNMP_long_CTOR;
+        private static final Constructor<?> SNMP_LONG_CTOR;
+        private static final Method SNMP_LONG_VALUE;
+        static {
+            Class<?> snmpTimeTicksClass;
+            try {
+                snmpTimeTicksClass =
+                    Class.forName(SNMP_TIME_TICKS_CLASS_NAME, true, null);
+            } catch (ClassNotFoundException x) {
+                snmpTimeTicksClass = null;
+                System.err.println("WARNING: can't load "+
+                        SNMP_TIME_TICKS_CLASS_NAME);
+            } catch (NoClassDefFoundError x) {
+                snmpTimeTicksClass = null;
+                System.err.println("WARNING: can't load "+
+                        SNMP_TIME_TICKS_CLASS_NAME);
+            }
+            SNMP_TIME_TICKS_CLASS = snmpTimeTicksClass;
+            if (SNMP_TIME_TICKS_CLASS != null) {
+                try {
+                  SNMP_long_CTOR =
+                          SNMP_TIME_TICKS_CLASS.getConstructor(long.class);
+                } catch (Exception x) {
+                    throw new ExceptionInInitializerError(x);
+                }
+            } else {
+                SNMP_long_CTOR = null;
+            }
+            if (SNMP_TIME_TICKS_CLASS != null) {
+                try {
+                  SNMP_LONG_CTOR =
+                          SNMP_TIME_TICKS_CLASS.getConstructor(Long.class);
+                } catch (Exception x) {
+                    throw new ExceptionInInitializerError(x);
+                }
+            } else {
+                SNMP_LONG_CTOR = null;
+            }
+            if (SNMP_TIME_TICKS_CLASS != null) {
+                try {
+                  SNMP_LONG_VALUE =
+                          SNMP_TIME_TICKS_CLASS.getMethod("longValue");
+                } catch (Exception x) {
+                    throw new ExceptionInInitializerError(x);
+                }
+            } else {
+                SNMP_LONG_VALUE = null;
+            }
+
+        }
+
+        private final Object timeticks;
+
+        public SnmpTimeticksBuilder(long ticks) throws Exception {
+            timeticks = newSnmpTimeticks(ticks);
+        }
+        public SnmpTimeticksBuilder(Long ticks) throws Exception {
+            timeticks = newSnmpTimeticks(ticks);
+        }
+        public long longValue() throws Exception {
+            return longValue(timeticks);
+        }
+
+        public static boolean isSnmpPresent() {
+            System.out.println(TimeTicksWrapping.class.getName()+
+                    ": Testing for SNMP Packages...");
+            return SNMP_TIME_TICKS_CLASS != null;
+        }
+
+        private static Object newSnmpTimeticks(long time)
+                throws Exception {
+            try {
+                return SNMP_long_CTOR.newInstance(time);
+            } catch (InvocationTargetException x) {
+                final Throwable cause = x.getCause();
+                if (cause instanceof Exception) throw (Exception) cause;
+                if (cause instanceof Error) throw (Error) cause;
+                throw x;
+            }
+        }
+
+        private static Object newSnmpTimeticks(Long time)
+            throws Exception {
+            try {
+                return SNMP_LONG_CTOR.newInstance(time);
+            } catch (InvocationTargetException x) {
+                final Throwable cause = x.getCause();
+                if (cause instanceof Exception) throw (Exception) cause;
+                if (cause instanceof Error) throw (Error) cause;
+                throw x;
+            }
+        }
+
+        private static long longValue(Object o)
+                throws Exception {
+            try {
+                return ((Long)SNMP_LONG_VALUE.invoke(o)).longValue();
+            } catch (InvocationTargetException x) {
+                final Throwable cause = x.getCause();
+                if (cause instanceof Exception) throw (Exception) cause;
+                if (cause instanceof Error) throw (Error) cause;
+                throw x;
+            }
+        }
+
+    }
+
     public static final long[] oks = {
         0L, 1L, (long)Integer.MAX_VALUE, (long)Integer.MAX_VALUE*2,
         (long)Integer.MAX_VALUE*2+1L, (long)Integer.MAX_VALUE*2+2L,
         (long)Integer.MAX_VALUE*3,
-        SnmpUnsignedInt.MAX_VALUE, SnmpUnsignedInt.MAX_VALUE+1L,
-        SnmpUnsignedInt.MAX_VALUE*3-1L, Long.MAX_VALUE
+        SnmpTimeticksBuilder.MAX_VALUE, SnmpTimeticksBuilder.MAX_VALUE+1L,
+        SnmpTimeticksBuilder.MAX_VALUE*3-1L, Long.MAX_VALUE
     };
 
     public static final long[] kos = {
         -1L, (long)Integer.MIN_VALUE, (long)Integer.MIN_VALUE*2,
         (long)Integer.MIN_VALUE*2-1L, (long)Integer.MIN_VALUE*3,
-        -SnmpUnsignedInt.MAX_VALUE, -(SnmpUnsignedInt.MAX_VALUE+1L),
-        -(SnmpUnsignedInt.MAX_VALUE*3-1L), Long.MIN_VALUE
+        -SnmpTimeticksBuilder.MAX_VALUE, -(SnmpTimeticksBuilder.MAX_VALUE+1L),
+        -(SnmpTimeticksBuilder.MAX_VALUE*3-1L), Long.MIN_VALUE
     };
 
+
     public static void main(String args[]) {
+        if (!SnmpTimeticksBuilder.isSnmpPresent()) {
+            System.err.println("WARNING: "+
+                    SnmpTimeticksBuilder.SNMP_TIME_TICKS_CLASS_NAME+
+                    " not present.");
+            System.err.println(TimeTicksWrapping.class.getName()+
+                    ": test skipped.");
+            return;
+        }
         try {
-            SnmpTimeticks t;
+            SnmpTimeticksBuilder t = null;
 
             for (int i=0;i<oks.length;i++) {
                 final long t1,t2,t3;
-                t1 = (new SnmpTimeticks(oks[i])).longValue();
-                t2 = (new SnmpTimeticks(new Long(oks[i]))).longValue();
+                t1 = (new SnmpTimeticksBuilder(oks[i])).longValue();
+                t2 = (new SnmpTimeticksBuilder(new Long(oks[i]))).longValue();
                 t3 = oks[i]%0x0100000000L;
                 if (t1 != t3)
                     throw new Exception("Value should have wrapped: " +
@@ -64,16 +189,16 @@
                     throw new Exception("Value should have wrapped: " +
                                         "Long("+oks[i]+") expected: " + t3);
 
-                if (t1 > SnmpUnsignedInt.MAX_VALUE)
+                if (t1 > SnmpTimeticksBuilder.MAX_VALUE)
                     throw new Exception("Value should have wrapped " +
                                         "for " + oks[i] + ": " +
                                         t1 + " exceeds max: " +
-                                        SnmpUnsignedInt.MAX_VALUE);
-                if (t2 > SnmpUnsignedInt.MAX_VALUE)
+                                        SnmpTimeticksBuilder.MAX_VALUE);
+                if (t2 > SnmpTimeticksBuilder.MAX_VALUE)
                     throw new Exception("Value should have wrapped " +
                                         "for " + oks[i] + ": " +
                                         t2 + " exceeds max: " +
-                                        SnmpUnsignedInt.MAX_VALUE);
+                                        SnmpTimeticksBuilder.MAX_VALUE);
 
                 if (t1 < 0)
                     throw new Exception("Value should have wrapped: " +
@@ -90,14 +215,14 @@
 
             for (int i=0;i<kos.length;i++) {
                 try {
-                    t = new SnmpTimeticks(kos[i]);
+                    t = new SnmpTimeticksBuilder(kos[i]);
                     throw new Exception("Value should have been rejected: " +
                                         kos[i]);
                 } catch (IllegalArgumentException x) {
                     // OK!
                 }
                 try {
-                    t = new SnmpTimeticks(new Long(kos[i]));
+                    t = new SnmpTimeticksBuilder(new Long(kos[i]));
                     throw new Exception("Value should have been rejected: " +
                                         "Long("+kos[i]+")");
                 } catch (IllegalArgumentException x) {