package com.onaro.sanscreen.client.jmxframework.service; import java.lang.reflect.Field; import java.util.Map; import javax.swing.SwingUtilities; import com.onaro.sanscreen.client.MainDirector; import com.onaro.sanscreen.client.jmxframework.FrameworkService; /** * MBean Shutdown service class. * Exposes functionality to shutdown the Client. Mainly used by UT. * * @author Rick Noel * */ @SuppressWarnings("nls") public class ShutdownService extends FrameworkService implements ShutdownServiceMBean { /** * Name of service. Used to look up service via JNDI */ public static final String NAME = "Shutdown Service"; // Using sun.awt.AppContext to work around Oracle bug in Java 7 only. @SuppressWarnings("restriction") private static sun.awt.AppContext mainThreadContext = null; public ShutdownService() { super(NAME); } @SuppressWarnings("restriction") @Override public void doStart() { // Using sun.awt.AppContext to work around Oracle bug in Java 7 only. if (mainThreadContext == null && System.getProperty("java.version").startsWith("1.7.")) { mainThreadContext = sun.awt.AppContext.getAppContext(); } } @Override public void doStop() { } @Override public String getStatus() { return "Running"; } /** * Main method of the service callable from JMX. Shuts down the client. */ @Override public void shutdown() { // Special shutdown required when running on Java 7 VM. if (mainThreadContext != null) { shutdown_java7(); } else { MainDirector.getMainDirector().exit(false); } } /** * Shuts down client when client is running on a Java 7 VM. *
* There is a bug introduced by Oracle in Java 7u25 that causes a null pointer exception * when the test tries to close the application. The NPE occurs within the Sun AWT Toolkit. * See Sun bug 8017776. * Unfortunately, this will not be fixed until Java 8. *
* Below is a workaround based on info discovered from various sources.
* Note we don't support Java 7 prior to update 25, so we use this workaround for all Java 7 VMs.
*/
@SuppressWarnings({"unchecked", "restriction"})
private void shutdown_java7() {
try {
// Change context to that used by MainDirector class (Swing thread).
final Field field = sun.awt.AppContext.class.getDeclaredField ("threadGroup2appContext"); //$NON-NLS-1$
field.setAccessible(true);
Map