提交 99132dc0 编写于 作者: S sjiang

6760712: Provide a connector server option that causes it not to prevent the VM from exiting

Reviewed-by: emcmanus
上级 7bc415b1
/*
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
......@@ -798,6 +799,24 @@ public class EnvHelp {
JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true);
}
/**
* <p>Name of the attribute that specifies whether a connector server
* should not prevent the VM from exiting
*/
public static final String JMX_SERVER_DAEMON = "jmx.remote.x.daemon";
/**
* Returns true if {@value SERVER_DAEMON} is specified in the {@code env}
* as a key and its value is a String and it is equal to true ignoring case.
*
* @param env
* @return
*/
public static boolean isServerDaemon(Map env) {
return (env != null) &&
("true".equalsIgnoreCase((String)env.get(JMX_SERVER_DAEMON)));
}
// /**
// * <p>Name of the attribute that specifies an EventRelay object to use.
// */
......
......@@ -38,6 +38,9 @@ import java.util.Collections;
import javax.security.auth.Subject;
import com.sun.jmx.remote.internal.RMIExporter;
import com.sun.jmx.remote.util.EnvHelp;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;
/**
* <p>An {@link RMIServer} object that is exported through JRMP and that
......@@ -93,12 +96,27 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
}
private void export(Remote obj) throws RemoteException {
RMIExporter exporter =
final RMIExporter exporter =
(RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
if (exporter == null)
UnicastRemoteObject.exportObject(obj, port, csf, ssf);
else
final boolean daemon = EnvHelp.isServerDaemon(env);
if (daemon && exporter != null) {
throw new IllegalArgumentException("If "+EnvHelp.JMX_SERVER_DAEMON+
" is specified as true, "+RMIExporter.EXPORTER_ATTRIBUTE+
" cannot be used to specify an exporter!");
}
if (daemon) {
if (csf == null && ssf == null) {
new UnicastServerRef(port).exportObject(obj, null, true);
} else {
new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
}
} else if (exporter != null) {
exporter.exportObject(obj, port, csf, ssf);
} else {
UnicastRemoteObject.exportObject(obj, port, csf, ssf);
}
}
private void unexport(Remote obj, boolean force)
......
/*
* 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
* 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
* @bug 6760712
* @summary test the connector server option that causes it not to prevent the
* VM from exiting
* @author Shanliang JIANG, Eamonn McManus
* @run main/othervm DaemonRMIExporterTest
*/
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServerFactory;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
// Test the connector server option that causes it not to prevent the VM
// from exiting. It's tricky to test exactly that, though possible. If
// we're being run from within jtreg, then jtreg has threads of its own
// that will prevent the VM from exiting. What's more it will kill all
// threads that the test created as soon as the main method returns,
// including the ones that would prevent the VM from exiting without the
// special option.
// Here we check that the test code does not create
// any permanent non-daemon threads, by recording the initial set of
// non-daemon threads (including at least one from jtreg), doing our stuff,
// then waiting for there to be no non-daemon threads that were not in
// the initial set.
public class DaemonRMIExporterTest {
public static void main(String[] args) throws Exception {
Set<Thread> initialNonDaemonThreads = getNonDaemonThreads();
JMXServiceURL addr = new JMXServiceURL("rmi", null, 0);
System.out.println("DaemonRMIExporterTest: Creating a RMIConnectorServer on " + addr);
Map<String, ?> env =
Collections.singletonMap("jmx.remote.x.daemon", "true");
JMXConnectorServer server =
JMXConnectorServerFactory.newJMXConnectorServer(addr,
env,
MBeanServerFactory.createMBeanServer());
server.start();
System.out.println("DaemonRMIExporterTest: Started the server on " + server.getAddress());
System.out.println("DaemonRMIExporterTest: Connecting a client to the server ...");
final JMXConnector conn = JMXConnectorFactory.connect(server.getAddress());
conn.getMBeanServerConnection().getDefaultDomain();
System.out.println("DaemonRMIExporterTest: Closing the client ...");
conn.close();
System.out.println("DaemonRMIExporterTest No more user code to execute, the VM should " +
"exit normally, otherwise will be blocked forever if the bug is not fixed.");
long deadline = System.currentTimeMillis() + 10000;
ok: {
while (System.currentTimeMillis() < deadline) {
Set<Thread> nonDaemonThreads = getNonDaemonThreads();
nonDaemonThreads.removeAll(initialNonDaemonThreads);
if (nonDaemonThreads.isEmpty())
break ok;
System.out.println("Non-daemon threads: " + nonDaemonThreads);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
throw new Exception("TEST FAILED: non-daemon threads remain");
}
System.out.println("TEST PASSED");
}
private static Set<Thread> getNonDaemonThreads() {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while (tg.getParent() != null)
tg = tg.getParent();
Thread[] threads = null;
for (int size = 10; size < 10000; size *= 2) {
threads = new Thread[size];
int n = tg.enumerate(threads, true);
if (n < size) {
threads = Arrays.copyOf(threads, n);
break;
}
}
Set<Thread> ndThreads = new HashSet<Thread>();
for (Thread t : threads) {
if (!t.isDaemon())
ndThreads.add(t);
}
return ndThreads;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册