Merge
authortbell
Fri, 21 Nov 2008 20:53:37 -0800
changeset 1630 27ede89dcb9c
parent 1594 3cb2a607c347 (current diff)
parent 1629 9d0fa22f9ffe (diff)
child 1631 c4ebd0337a6c
Merge
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Fri Nov 21 20:53:37 2008 -0800
@@ -70,6 +70,7 @@
 import javax.management.ListenerNotFoundException;
 import javax.management.MBeanException;
 import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
 import javax.management.MBeanPermission;
 import javax.management.MBeanRegistration;
 import javax.management.MBeanRegistrationException;
@@ -1045,8 +1046,10 @@
             Object resource = getResource(mbean);
             MBeanInjector.inject(resource, mbs, name);
             if (MBeanInjector.injectsSendNotification(resource)) {
+                MBeanNotificationInfo[] mbnis =
+                        mbean.getMBeanInfo().getNotifications();
                 NotificationBroadcasterSupport nbs =
-                        new NotificationBroadcasterSupport();
+                        new NotificationBroadcasterSupport(mbnis);
                 MBeanInjector.injectSendNotification(resource, nbs);
                 mbean = NotifySupport.wrap(mbean, nbs);
             }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Fri Nov 21 20:53:37 2008 -0800
@@ -44,6 +44,7 @@
 import javax.management.ImmutableDescriptor;
 import javax.management.IntrospectionException;
 import javax.management.InvalidAttributeValueException;
+import javax.management.JMX;
 import javax.management.MBean;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanConstructorInfo;
@@ -538,21 +539,22 @@
     }
 
     static MBeanNotificationInfo[] findNotifications(Object moi) {
-        if (!(moi instanceof NotificationBroadcaster))
-            return null;
-        MBeanNotificationInfo[] mbn =
-                ((NotificationBroadcaster) moi).getNotificationInfo();
-        if (mbn == null || mbn.length == 0)
-            return findNotificationsFromAnnotations(moi.getClass());
-        MBeanNotificationInfo[] result =
-                new MBeanNotificationInfo[mbn.length];
-        for (int i = 0; i < mbn.length; i++) {
-            MBeanNotificationInfo ni = mbn[i];
-            if (ni.getClass() != MBeanNotificationInfo.class)
-                ni = (MBeanNotificationInfo) ni.clone();
-            result[i] = ni;
+        if (moi instanceof NotificationBroadcaster) {
+            MBeanNotificationInfo[] mbn =
+                    ((NotificationBroadcaster) moi).getNotificationInfo();
+            if (mbn != null && mbn.length > 0) {
+                MBeanNotificationInfo[] result =
+                        new MBeanNotificationInfo[mbn.length];
+                for (int i = 0; i < mbn.length; i++) {
+                    MBeanNotificationInfo ni = mbn[i];
+                    if (ni.getClass() != MBeanNotificationInfo.class)
+                        ni = (MBeanNotificationInfo) ni.clone();
+                    result[i] = ni;
+                }
+                return result;
+            }
         }
-        return result;
+        return findNotificationsFromAnnotations(moi.getClass());
     }
 
     private static MBeanNotificationInfo[] findNotificationsFromAnnotations(
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataSupport.java	Fri Nov 21 20:53:37 2008 -0800
@@ -101,7 +101,7 @@
      * the same size as <tt>itemNames</tt>; must not be null.
      *
      * @throws IllegalArgumentException <tt>compositeType</tt> is null, or
-     * <tt>itemNames[]</tt> or <tt>itemValues[]</tt> is null or empty, or one
+     * <tt>itemNames[]</tt> or <tt>itemValues[]</tt> is null, or one
      * of the elements in <tt>itemNames[]</tt> is a null or empty string, or
      * <tt>itemNames[]</tt> and <tt>itemValues[]</tt> are not of the same size.
      *
--- a/jdk/src/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java	Fri Nov 21 20:53:37 2008 -0800
@@ -49,13 +49,34 @@
         return new ServerSocket(port) {
             @Override
             public Socket accept() throws IOException {
-                Socket socket = super.accept();
-                InetAddress remoteAddr = socket.getInetAddress();
+                final Socket socket = super.accept();
+                final InetAddress remoteAddr = socket.getInetAddress();
                 final String msg = "The server sockets created using the " +
-                        "LocalRMIServerSocketFactory only accept connections " +
-                        "from clients running on the host where the RMI " +
-                        "remote objects have been exported.";
-                if (remoteAddr.isAnyLocalAddress()) {
+                       "LocalRMIServerSocketFactory only accept connections " +
+                       "from clients running on the host where the RMI " +
+                       "remote objects have been exported.";
+
+                if (remoteAddr == null) {
+                    // Though unlikeky, the socket could be already
+                    // closed... Send a more detailed message in
+                    // this case. Also avoid throwing NullPointerExceptiion
+                    //
+                    String details = "";
+                    if (socket.isClosed()) {
+                        details = " Socket is closed.";
+                    } else if (!socket.isConnected()) {
+                        details = " Socket is not connected";
+                    }
+                    try {
+                        socket.close();
+                    } catch (Exception ok) {
+                        // ok - this is just cleanup before throwing detailed
+                        // exception.
+                    }
+                    throw new IOException(msg +
+                            " Couldn't determine client address." +
+                            details);
+                } else if (remoteAddr.isLoopbackAddress()) {
                     // local address: accept the connection.
                     return socket;
                 }
--- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java	Fri Nov 21 20:53:37 2008 -0800
@@ -770,6 +770,7 @@
                 new String[] {
                     "cp834",
                     "ibm834",
+                    "834",
                     "ibm-834"
         });
 
--- a/jdk/src/windows/native/java/lang/java_props_md.c	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/src/windows/native/java/lang/java_props_md.c	Fri Nov 21 20:53:37 2008 -0800
@@ -38,6 +38,12 @@
 #define VER_PLATFORM_WIN32_WINDOWS 1
 #endif
 
+#ifndef PROCESSOR_ARCHITECTURE_AMD64
+#define PROCESSOR_ARCHITECTURE_AMD64 9
+#endif
+
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+
 #define SHELL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
 
 /* Encodings for Windows language groups. According to
@@ -674,9 +680,22 @@
     {
         char buf[100];
         OSVERSIONINFOEX ver;
+        SYSTEM_INFO si;
+        PGNSI pGNSI;
+
         ver.dwOSVersionInfoSize = sizeof(ver);
         GetVersionEx((OSVERSIONINFO *) &ver);
 
+        ZeroMemory(&si, sizeof(SYSTEM_INFO));
+        // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+        pGNSI = (PGNSI) GetProcAddress(
+                GetModuleHandle(TEXT("kernel32.dll")),
+                "GetNativeSystemInfo");
+        if(NULL != pGNSI)
+            pGNSI(&si);
+        else
+            GetSystemInfo(&si);
+
         /*
          * From msdn page on OSVERSIONINFOEX, current as of this
          * writing, decoding of dwMajorVersion and dwMinorVersion.
@@ -690,9 +709,14 @@
          * Windows 3.51                 3               51
          * Windows NT 4.0               4               0
          * Windows 2000                 5               0
-         * Windows XP                   5               1
+         * Windows XP 32 bit            5               1
          * Windows Server 2003 family   5               2
+         * Windows XP 64 bit            5               2
+         *       where ((&ver.wServicePackMinor) + 2) = 1
+         *       and  si.wProcessorArchitecture = 9
          * Windows Vista family         6               0
+         * Windows 2008                 6               0
+         *       where ((&ver.wServicePackMinor) + 2) = 1
          *
          * This mapping will presumably be augmented as new Windows
          * versions are released.
@@ -720,7 +744,25 @@
                 switch (ver.dwMinorVersion) {
                 case  0: sprops.os_name = "Windows 2000";         break;
                 case  1: sprops.os_name = "Windows XP";           break;
-                case  2: sprops.os_name = "Windows 2003";         break;
+                case  2:
+                   /*
+                    * From MSDN OSVERSIONINFOEX and SYSTEM_INFO documentation:
+                    *
+                    * "Because the version numbers for Windows Server 2003
+                    * and Windows XP 6u4 bit are identical, you must also test
+                    * whether the wProductType member is VER_NT_WORKSTATION.
+                    * and si.wProcessorArchitecture is
+                    * PROCESSOR_ARCHITECTURE_AMD64 (which is 9)
+                    * If it is, the operating system is Windows XP 64 bit;
+                    * otherwise, it is Windows Server 2003."
+                    */
+                    if(ver.wProductType == VER_NT_WORKSTATION &&
+                       si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+                        sprops.os_name = "Windows XP"; /* 64 bit */
+                    } else {
+                        sprops.os_name = "Windows 2003";
+                    }
+                    break;
                 default: sprops.os_name = "Windows NT (unknown)"; break;
                 }
             } else if (ver.dwMajorVersion == 6) {
--- a/jdk/test/javax/management/Introspector/AnnotatedNotificationInfoTest.java	Wed Jul 05 16:44:09 2017 +0200
+++ b/jdk/test/javax/management/Introspector/AnnotatedNotificationInfoTest.java	Fri Nov 21 20:53:37 2008 -0800
@@ -22,8 +22,8 @@
  */
 
 /*
- * @test %M% %I%
- * @bug 6323980
+ * @test
+ * @bug 6323980 6772779
  * @summary Test &#64;NotificationInfo annotation
  * @author Eamonn McManus
  * @run main/othervm -ea AnnotatedNotificationInfoTest
@@ -32,6 +32,7 @@
 import java.io.Serializable;
 import java.lang.management.ManagementFactory;
 import java.lang.reflect.Field;
+import java.util.Arrays;
 import javax.annotation.Resource;
 import javax.management.AttributeChangeNotification;
 import javax.management.Description;
@@ -134,6 +135,23 @@
 
     private static Object mbeanIntf5 = new Intf5Impl();
 
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static interface Intf6MBean {}
+
+    public static class Intf6 implements Intf6MBean {
+        @Resource
+        private volatile SendNotification send;
+    }
+
+    private static Object mbeanIntf6 = new Intf6();
+
     public static interface Impl1MBean {}
 
     @NotificationInfo(
@@ -202,22 +220,21 @@
 
     private static Object mbeanMBean2 = new MBean2();
 
-    // Following disabled until we support it
-//    @MBean
-//    @NotificationInfo(
-//            types = {"foo", "bar"},
-//            notificationClass = AttributeChangeNotification.class,
-//            description = @Description(
-//                value = "description",
-//                bundleBaseName = "bundle",
-//                key = "key"),
-//            descriptorFields = {"foo=bar"})
-//    public static class MBean3 {
-//        @Resource
-//        private volatile SendNotification send;
-//    }
-//
-//    private static Object mbeanMBean3 = new MBean3();
+    @MBean
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class MBean3 {
+        @Resource
+        private volatile SendNotification send;
+    }
+
+    private static Object mbeanMBean3 = new MBean3();
 
     @MXBean
     @NotificationInfo(
@@ -237,6 +254,23 @@
 
     private static Object mbeanMXBean2 = new MXBean2();
 
+    // Classes for the second test.  This tests the simplest case, which is
+    // the first example in the javadoc for @NotificationInfo.  Notice that
+    // this MBean is not a NotificationBroadcaster and does not inject a
+    // SendNotification!  That should possibly be an error, but it's currently
+    // allowed by the spec.
+    @NotificationInfo(types={"com.example.notifs.create",
+                             "com.example.notifs.destroy"})
+    public static interface CacheMBean {
+        public int getCachedNum();
+    }
+
+    public static class Cache implements CacheMBean {
+        public int getCachedNum() {
+            return 0;
+        }
+    }
+
     public static void main(String[] args) throws Exception {
         if (!AnnotatedNotificationInfoTest.class.desiredAssertionStatus())
             throw new Exception("Test must be run with -ea");
@@ -267,5 +301,14 @@
             assert mbnis[0].equals(expected) : mbnis[0];
             mbs.unregisterMBean(on);
         }
+
+        mbs.registerMBean(new Cache(), on);
+        MBeanInfo mbi = mbs.getMBeanInfo(on);
+        MBeanNotificationInfo[] mbnis = mbi.getNotifications();
+        assert mbnis.length == 1 : mbnis.length;
+        String[] types = mbnis[0].getNotifTypes();
+        String[] expectedTypes =
+                CacheMBean.class.getAnnotation(NotificationInfo.class).types();
+        assert Arrays.equals(types, expectedTypes) : Arrays.toString(types);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java	Fri Nov 21 20:53:37 2008 -0800
@@ -0,0 +1,145 @@
+/*
+ * Copyright 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
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ *  @test LocalRMIServerSocketFactoryTest.java
+ *  @bug 6774170
+ *  @summary Connect to a server socket returned by the LocalRMIServerSocketFactory.
+ *
+ *  @author Daniel Fuchs
+ *
+ *  @run compile -XDignore.symbol.file=true -source 1.6 -g LocalRMIServerSocketFactoryTest.java
+ *  @run main LocalRMIServerSocketFactoryTest
+ */
+
+import sun.management.jmxremote.LocalRMIServerSocketFactory;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.SynchronousQueue;
+
+public class LocalRMIServerSocketFactoryTest {
+
+    private static final SynchronousQueue<Exception> queue =
+            new SynchronousQueue<Exception>();
+
+    static final class Result extends Exception {
+
+        private Result() {
+            super("SUCCESS: No exception was thrown");
+        }
+        static final Result SUCCESS = new Result();
+    }
+
+    private static void checkError(String message) throws Exception {
+
+        // Wait for the server to set the error field.
+        final Exception x = queue.take();
+
+        if (x == Result.SUCCESS) {
+            return;
+        }
+
+
+        // case of 6674166: this is very unlikely to happen, even if
+        //     both 6674166 and 6774170 aren't fixed. If it happens
+        //     however, it might indicate that neither defects are fixed.
+
+        if (x instanceof NullPointerException) {
+            throw new Exception(message + " - " +
+                    "Congratulations! it seems you have triggered 6674166. " +
+                    "Neither 6674166 nor 6774170 seem to be fixed: " + x, x);
+        } else if (x instanceof IOException) {
+            throw new Exception(message + " - " +
+                    "Unexpected IOException. Maybe you triggered 6674166? " +
+                    x, x);
+        } else if (x != null) {
+            throw new Exception(message + " - " +
+                    "Ouch, that's bad. " +
+                    "This is a new kind of unexpected exception " +
+                    x, x);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        final LocalRMIServerSocketFactory f =
+                new LocalRMIServerSocketFactory();
+        final ServerSocket s = f.createServerSocket(0);
+        final int port = s.getLocalPort();
+        Thread t = new Thread() {
+
+            public void run() {
+                while (true) {
+                    Exception error = Result.SUCCESS;
+                    try {
+                        System.err.println("Accepting: ");
+                        final Socket ss = s.accept();
+                        System.err.println(ss.getInetAddress() + " accepted");
+                    } catch (Exception x) {
+                        x.printStackTrace();
+                        error = x;
+                    } finally {
+                        try {
+                            // wait for the client to get the exception.
+                            queue.put(error);
+                        } catch (Exception x) {
+                            // too bad!
+                            System.err.println("Could't send result to client!");
+                            x.printStackTrace();
+                            return;
+                        }
+                    }
+                }
+            }
+        };
+        t.setDaemon(true);
+        t.start();
+
+        System.err.println("new Socket((String)null, port)");
+        final Socket s1 = new Socket((String) null, port);
+        checkError("new Socket((String)null, port)");
+        s1.close();
+        System.err.println("new Socket((String)null, port): PASSED");
+
+        System.err.println("new Socket(InetAddress.getByName(null), port)");
+        final Socket s2 = new Socket(InetAddress.getByName(null), port);
+        checkError("new Socket(InetAddress.getByName(null), port)");
+        s2.close();
+        System.err.println("new Socket(InetAddress.getByName(null), port): PASSED");
+
+        System.err.println("new Socket(localhost, port)");
+        final Socket s3 = new Socket("localhost", port);
+        checkError("new Socket(localhost, port)");
+        s3.close();
+        System.err.println("new Socket(localhost, port): PASSED");
+
+        System.err.println("new Socket(127.0.0.1, port)");
+        final Socket s4 = new Socket("127.0.0.1", port);
+        checkError("new Socket(127.0.0.1, port)");
+        s4.close();
+        System.err.println("new Socket(127.0.0.1, port): PASSED");
+
+    }
+}