This commit is contained in:
Tim Bell 2008-11-21 20:53:37 -08:00
commit 210b864811
8 changed files with 299 additions and 42 deletions

View File

@ -70,6 +70,7 @@ import javax.management.JMRuntimeException;
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 @@ public class DefaultMBeanServerInterceptor
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);
}

View File

@ -44,6 +44,7 @@ import javax.management.Descriptor;
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 @@ abstract class MBeanIntrospector<M> {
}
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(

View File

@ -101,7 +101,7 @@ public class CompositeDataSupport
* 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.
*

View File

@ -49,13 +49,34 @@ public final class LocalRMIServerSocketFactory implements RMIServerSocketFactory
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;
}

View File

@ -770,6 +770,7 @@ public class ExtendedCharsets
new String[] {
"cp834",
"ibm834",
"834",
"ibm-834"
});

View File

@ -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 @@ GetJavaProperties(JNIEnv* env)
{
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 @@ GetJavaProperties(JNIEnv* env)
* 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 @@ GetJavaProperties(JNIEnv* env)
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) {

View File

@ -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 @@ public class AnnotatedNotificationInfoTest {
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 @@ public class AnnotatedNotificationInfoTest {
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 @@ public class AnnotatedNotificationInfoTest {
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 @@ public class AnnotatedNotificationInfoTest {
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);
}
}

View File

@ -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");
}
}