6760712: Provide a connector server option that causes it not to prevent the VM from exiting
Reviewed-by: emcmanus
This commit is contained in:
parent
0850f3ec01
commit
d2c931b222
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user