/* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management.remote.rmi; import com.sun.jmx.mbeanserver.Util;import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;import com.sun.jmx.remote.internal.ClientListenerInfo;import com.sun.jmx.remote.internal.ClientNotifForwarder;import com.sun.jmx.remote.internal.ProxyRef;import com.sun.jmx.remote.internal.IIOPHelper;import com.sun.jmx.remote.util.ClassLogger;import com.sun.jmx.remote.util.EnvHelp;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InvalidObjectException;import java.io.NotSerializableException;import java.io.ObjectInputStream;import java.io.ObjectStreamClass;import java.io.Serializable;import java.io.WriteAbortedException;import java.lang.ref.WeakReference;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Proxy;import java.net.MalformedURLException;import java.rmi.MarshalException;import java.rmi.MarshalledObject;import java.rmi.NoSuchObjectException;import java.rmi.Remote;import java.rmi.ServerException;import java.rmi.UnmarshalException;import java.rmi.server.RMIClientSocketFactory;import java.rmi.server.RemoteObject;import java.rmi.server.RemoteObjectInvocationHandler;import java.rmi.server.RemoteRef;import java.security.AccessController;import java.security.PrivilegedAction;import java.security.PrivilegedExceptionAction;import java.security.ProtectionDomain;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.Properties;import java.util.Set;import java.util.WeakHashMap;import javax.management.Attribute;import javax.management.AttributeList;import javax.management.AttributeNotFoundException;import javax.management.InstanceAlreadyExistsException;import javax.management.InstanceNotFoundException;import javax.management.IntrospectionException;import javax.management.InvalidAttributeValueException;import javax.management.ListenerNotFoundException;import javax.management.MBeanException;import javax.management.MBeanInfo;import javax.management.MBeanRegistrationException;import javax.management.MBeanServerConnection;import javax.management.MBeanServerDelegate;import javax.management.MBeanServerNotification;import javax.management.NotCompliantMBeanException;import javax.management.Notification;import javax.management.NotificationBroadcasterSupport;import javax.management.NotificationFilter;import javax.management.NotificationFilterSupport;import javax.management.NotificationListener;import javax.management.ObjectInstance;import javax.management.ObjectName;import javax.management.QueryExp;import javax.management.ReflectionException;import javax.management.remote.JMXConnectionNotification;import javax.management.remote.JMXConnector;import javax.management.remote.JMXConnectorFactory;import javax.management.remote.JMXServiceURL;import javax.management.remote.NotificationResult;import javax.management.remote.JMXAddressable;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.rmi.ssl.SslRMIClientSocketFactory;import javax.security.auth.Subject;import sun.rmi.server.UnicastRef2;import sun.rmi.transport.LiveRef; /** * <p>A connection to a remote RMI connector. Usually, such * connections are made using {@link * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}. * However, specialized applications can use this class directly, for * example with an {@link RMIServer} stub obtained without going * through JNDI.</p> * * @since 1.5 */public class RMIConnector implements JMXConnector, Serializable, JMXAddressable { private static final ClassLogger logger = new ClassLogger("javax.management.remote.rmi", "RMIConnector"); private static final long serialVersionUID = 817323035842634473L; private RMIConnector(RMIServer rmiServer, JMXServiceURL address, Map<String, ?> environment) { if (rmiServer == null && address == null) throw new IllegalArgumentException("rmiServer and jmxServiceURL both null"); initTransients(); this.rmiServer = rmiServer; this.jmxServiceURL = address; if (environment == null) { this.env = Collections.emptyMap(); } else { EnvHelp.checkAttributes(environment); this.env = Collections.unmodifiableMap(environment); } } /** * <p>Constructs an <code>RMIConnector</code> that will connect * the RMI connector server with the given address.</p> * * <p>The address can refer directly to the connector server, * using one of the following syntaxes:</p> * * <pre> * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em> * service:jmx:iiop://<em>[host[:port]]</em>/ior/<em>encoded-IOR</em> * </pre> * * <p>(Here, the square brackets <code>[]</code> are not part of the * address but indicate that the host and port are optional.)</p> * * <p>The address can instead indicate where to find an RMI stub * through JNDI, using one of the following syntaxes:</p> * * <pre> * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em> * service:jmx:iiop://<em>[host[:port]]</em>/jndi/<em>jndi-name</em> * </pre> * * <p>An implementation may also recognize additional address * syntaxes, for example:</p> * * <pre> * service:jmx:iiop://<em>[host[:port]]</em>/stub/<em>encoded-stub</em> * </pre> * * @param url the address of the RMI connector server. * * @param environment additional attributes specifying how to make * the connection. For JNDI-based addresses, these attributes can * usefully include JNDI attributes recognized by {@link * InitialContext#InitialContext(Hashtable) InitialContext}. This * parameter can be null, which is equivalent to an empty Map. * * @exception IllegalArgumentException if <code>url</code> * is null. */ public RMIConnector(JMXServiceURL url, Map<String,?> environment) { this(null, url, environment); } /** * <p>Constructs an <code>RMIConnector</code> using the given RMI stub. * * @param rmiServer an RMI stub representing the RMI connector server. * @param environment additional attributes specifying how to make * the connection. This parameter can be null, which is * equivalent to an empty Map. * * @exception IllegalArgumentException if <code>rmiServer</code> * is null. */ public RMIConnector(RMIServer rmiServer, Map<String,?> environment) { this(rmiServer, null, environment); } /** * <p>Returns a string representation of this object. In general, * the <code>toString</code> method returns a string that * "textually represents" this object. The result should be a * concise but informative representation that is easy for a * person to read.</p> * * @return a String representation of this object. **/ @Override public String toString() { final StringBuilder b = new StringBuilder(this.getClass().getName()); b.append(":"); if (rmiServer != null) { b.append(" rmiServer=").append(rmiServer.toString()); } if (jmxServiceURL != null) { if (rmiServer!=null) b.append(","); b.append(" jmxServiceURL=").append(jmxServiceURL.toString()); } return b.toString(); } /** * <p>The address of this connector.</p> * * @return the address of this connector, or null if it * does not have one. * * @since 1.6 */ public JMXServiceURL getAddress() { return jmxServiceURL; } //-------------------------------------------------------------------- // implements JMXConnector interface //-------------------------------------------------------------------- public void connect() throws IOException { connect(null); } public synchronized void connect(Map<String,?> environment) throws IOException { final boolean tracing = logger.traceOn(); String idstr = (tracing?"["+this.toString()+"]":null); if (terminated) { logger.trace("connect",idstr + " already closed."); throw new IOException("Connector closed"); } if (connected) { logger.trace("connect",idstr + " already connected."); return; } try { if (tracing) logger.trace("connect",idstr + " connecting..."); final Map<String, Object> usemap = new HashMap<String, Object>((this.env==null) ? Collections.<String, Object>emptyMap() : this.env); if (environment != null) { EnvHelp.checkAttributes(environment); usemap.putAll(environment); } // Get RMIServer stub from directory or URL encoding if needed. if (tracing) logger.trace("connect",idstr + " finding stub..."); RMIServer stub = (rmiServer!=null)?rmiServer: findRMIServer(jmxServiceURL, usemap); // Check for secure RMIServer stub if the corresponding // client-side environment property is set to "true". // boolean checkStub = EnvHelp.computeBooleanFromString( usemap, "jmx.remote.x.check.stub",false); if (checkStub) checkStub(stub, rmiServerImplStubClass); // Connect IIOP Stub if needed. if (tracing) logger.trace("connect",idstr + " connecting stub..."); stub = connectStub(stub,usemap); idstr = (tracing?"["+this.toString()+"]":null); // Calling newClient on the RMIServer stub. if (tracing) logger.trace("connect",idstr + " getting connection..."); Object credentials = usemap.get(CREDENTIALS); try { connection = getConnection(stub, credentials, checkStub); } catch (java.rmi.RemoteException re) { if (jmxServiceURL != null) { final String pro = jmxServiceURL.getProtocol(); final String path = jmxServiceURL.getURLPath(); if ("rmi".equals(pro) && path.startsWith("/jndi/iiop:")) { MalformedURLException mfe = new MalformedURLException( "Protocol is rmi but JNDI scheme is iiop: " + jmxServiceURL); mfe.initCause(re); throw mfe; } } throw re; } // Always use one of: // ClassLoader provided in Map at connect time, // or contextClassLoader at connect time. if (tracing) logger.trace("connect",idstr + " getting class loader..."); defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap); usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER, defaultClassLoader); rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap); env = usemap; final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap); communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod); connected = true; // The connectionId variable is used in doStart(), when // reconnecting, to identify the "old" connection. // connectionId = getConnectionId(); Notification connectedNotif = new JMXConnectionNotification(JMXConnectionNotification.OPENED, this, connectionId, clientNotifSeqNo++, "Successful connection", null); sendNotification(connectedNotif); if (tracing) logger.trace("connect",idstr + " done..."); } catch (IOException e) { if (tracing) logger.trace("connect",idstr + " failed to connect: " + e); throw e; } catch (RuntimeException e) { if (tracing) logger.trace("connect",idstr + " failed to connect: " + e); throw e; } catch (NamingException e) { final String msg = "Failed to retrieve RMIServer stub: " + e; if (tracing) logger.trace("connect",idstr + " " + msg); throw EnvHelp.initCause(new IOException(msg),e); } } public synchronized String getConnectionId() throws IOException { if (terminated || !connected) { if (logger.traceOn()) logger.trace("getConnectionId","["+this.toString()+ "] not connected."); throw new IOException("Not connected"); } // we do a remote call to have an IOException if the connection is broken. // see the bug 4939578 return connection.getConnectionId(); } public synchronized MBeanServerConnection getMBeanServerConnection() throws IOException { return getMBeanServerConnection(null); } public synchronized MBeanServerConnection getMBeanServerConnection(Subject delegationSubject) throws IOException { if (terminated) { if (logger.traceOn()) logger.trace("getMBeanServerConnection","[" + this.toString() + "] already closed."); throw new IOException("Connection closed"); } else if (!connected) { if (logger.traceOn()) logger.trace("getMBeanServerConnection","[" + this.toString() + "] is not connected."); throw new IOException("Not connected"); } MBeanServerConnection rmbsc = rmbscMap.get(delegationSubject); if (rmbsc != null) { return rmbsc; } rmbsc = new RemoteMBeanServerConnection(delegationSubject); rmbscMap.put(delegationSubject, rmbsc); return rmbsc; } public void addConnectionNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.addNotificationListener(listener, filter, handback); } public void removeConnectionNotificationListener(NotificationListener listener) throws ListenerNotFoundException { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.removeNotificationListener(listener); } public void removeConnectionNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.removeNotificationListener(listener, filter, handback); } private void sendNotification(Notification n) { connectionBroadcaster.sendNotification(n); } public synchronized void close() throws IOException { close(false); } // allows to do close after setting the flag "terminated" to true. // It is necessary to avoid a deadlock, see 6296324 private synchronized void close(boolean intern) throws IOException { final boolean tracing = logger.traceOn(); final boolean debug = logger.debugOn(); final String idstr = (tracing?"["+this.toString()+"]":null); if (!intern) { // Return if already cleanly closed. // if (terminated) { if (closeException == null) { if (tracing) logger.trace("close",idstr + " already closed."); return; } } else { terminated = true; } } if (closeException != null && tracing) { // Already closed, but not cleanly. Attempt again. // if (tracing) { logger.trace("close",idstr + " had failed: " + closeException); logger.trace("close",idstr + " attempting to close again."); } } String savedConnectionId = null; if (connected) { savedConnectionId = connectionId; } closeException = null; if (tracing) logger.trace("close",idstr + " closing."); if (communicatorAdmin != null) { communicatorAdmin.terminate(); } if (rmiNotifClient != null) { try { rmiNotifClient.terminate(); if (tracing) logger.trace("close",idstr + " RMI Notification client terminated."); } catch (RuntimeException x) { closeException = x; if (tracing) logger.trace("close",idstr + " Failed to terminate RMI Notification client: " + x); if (debug) logger.debug("close",x); } } if (connection != null) { try { connection.close();Lines 1–500 of 2576. Load more
/* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management.remote.rmi; import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.internal.ClientCommunicatorAdmin; import com.sun.jmx.remote.internal.ClientListenerInfo; import com.sun.jmx.remote.internal.ClientNotifForwarder; import com.sun.jmx.remote.internal.ProxyRef; import com.sun.jmx.remote.internal.IIOPHelper; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InvalidObjectException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.io.Serializable; import java.io.WriteAbortedException; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.rmi.MarshalException; import java.rmi.MarshalledObject; import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.ServerException; import java.rmi.UnmarshalException; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RemoteObject; import java.rmi.server.RemoteObjectInvocationHandler; import java.rmi.server.RemoteRef; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.WeakHashMap; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.InvalidAttributeValueException; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanRegistrationException; import javax.management.MBeanServerConnection; import javax.management.MBeanServerDelegate; import javax.management.MBeanServerNotification; import javax.management.NotCompliantMBeanException; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationFilter; import javax.management.NotificationFilterSupport; import javax.management.NotificationListener; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.QueryExp; import javax.management.ReflectionException; import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import javax.management.remote.NotificationResult; import javax.management.remote.JMXAddressable; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.security.auth.Subject; import sun.rmi.server.UnicastRef2; import sun.rmi.transport.LiveRef; /** * <p>A connection to a remote RMI connector. Usually, such * connections are made using {@link * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}. * However, specialized applications can use this class directly, for * example with an {@link RMIServer} stub obtained without going * through JNDI.</p> * * @since 1.5 */ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable { private static final ClassLogger logger = new ClassLogger("javax.management.remote.rmi", "RMIConnector"); private static final long serialVersionUID = 817323035842634473L; private RMIConnector(RMIServer rmiServer, JMXServiceURL address, Map<String, ?> environment) { if (rmiServer == null && address == null) throw new IllegalArgumentException("rmiServer and jmxServiceURL both null"); initTransients(); this.rmiServer = rmiServer; this.jmxServiceURL = address; if (environment == null) { this.env = Collections.emptyMap(); } else { EnvHelp.checkAttributes(environment); this.env = Collections.unmodifiableMap(environment); } } /** * <p>Constructs an <code>RMIConnector</code> that will connect * the RMI connector server with the given address.</p> * * <p>The address can refer directly to the connector server, * using one of the following syntaxes:</p> * * <pre> * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em> * service:jmx:iiop://<em>[host[:port]]</em>/ior/<em>encoded-IOR</em> * </pre> * * <p>(Here, the square brackets <code>[]</code> are not part of the * address but indicate that the host and port are optional.)</p> * * <p>The address can instead indicate where to find an RMI stub * through JNDI, using one of the following syntaxes:</p> * * <pre> * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em> * service:jmx:iiop://<em>[host[:port]]</em>/jndi/<em>jndi-name</em> * </pre> * * <p>An implementation may also recognize additional address * syntaxes, for example:</p> * * <pre> * service:jmx:iiop://<em>[host[:port]]</em>/stub/<em>encoded-stub</em> * </pre> * * @param url the address of the RMI connector server. * * @param environment additional attributes specifying how to make * the connection. For JNDI-based addresses, these attributes can * usefully include JNDI attributes recognized by {@link * InitialContext#InitialContext(Hashtable) InitialContext}. This * parameter can be null, which is equivalent to an empty Map. * * @exception IllegalArgumentException if <code>url</code> * is null. */ public RMIConnector(JMXServiceURL url, Map<String,?> environment) { this(null, url, environment); } /** * <p>Constructs an <code>RMIConnector</code> using the given RMI stub. * * @param rmiServer an RMI stub representing the RMI connector server. * @param environment additional attributes specifying how to make * the connection. This parameter can be null, which is * equivalent to an empty Map. * * @exception IllegalArgumentException if <code>rmiServer</code> * is null. */ public RMIConnector(RMIServer rmiServer, Map<String,?> environment) { this(rmiServer, null, environment); } /** * <p>Returns a string representation of this object. In general, * the <code>toString</code> method returns a string that * "textually represents" this object. The result should be a * concise but informative representation that is easy for a * person to read.</p> * * @return a String representation of this object. **/ @Override public String toString() { final StringBuilder b = new StringBuilder(this.getClass().getName()); b.append(":"); if (rmiServer != null) { b.append(" rmiServer=").append(rmiServer.toString()); } if (jmxServiceURL != null) { if (rmiServer!=null) b.append(","); b.append(" jmxServiceURL=").append(jmxServiceURL.toString()); } return b.toString(); } /** * <p>The address of this connector.</p> * * @return the address of this connector, or null if it * does not have one. * * @since 1.6 */ public JMXServiceURL getAddress() { return jmxServiceURL; } //-------------------------------------------------------------------- // implements JMXConnector interface //-------------------------------------------------------------------- public void connect() throws IOException { connect(null); } public synchronized void connect(Map<String,?> environment) throws IOException { final boolean tracing = logger.traceOn(); String idstr = (tracing?"["+this.toString()+"]":null); if (terminated) { logger.trace("connect",idstr + " already closed."); throw new IOException("Connector closed"); } if (connected) { logger.trace("connect",idstr + " already connected."); return; } try { if (tracing) logger.trace("connect",idstr + " connecting..."); final Map<String, Object> usemap = new HashMap<String, Object>((this.env==null) ? Collections.<String, Object>emptyMap() : this.env); if (environment != null) { EnvHelp.checkAttributes(environment); usemap.putAll(environment); } // Get RMIServer stub from directory or URL encoding if needed. if (tracing) logger.trace("connect",idstr + " finding stub..."); RMIServer stub = (rmiServer!=null)?rmiServer: findRMIServer(jmxServiceURL, usemap); // Check for secure RMIServer stub if the corresponding // client-side environment property is set to "true". // boolean checkStub = EnvHelp.computeBooleanFromString( usemap, "jmx.remote.x.check.stub",false); if (checkStub) checkStub(stub, rmiServerImplStubClass); // Connect IIOP Stub if needed. if (tracing) logger.trace("connect",idstr + " connecting stub..."); stub = connectStub(stub,usemap); idstr = (tracing?"["+this.toString()+"]":null); // Calling newClient on the RMIServer stub. if (tracing) logger.trace("connect",idstr + " getting connection..."); Object credentials = usemap.get(CREDENTIALS); try { connection = getConnection(stub, credentials, checkStub); } catch (java.rmi.RemoteException re) { if (jmxServiceURL != null) { final String pro = jmxServiceURL.getProtocol(); final String path = jmxServiceURL.getURLPath(); if ("rmi".equals(pro) && path.startsWith("/jndi/iiop:")) { MalformedURLException mfe = new MalformedURLException( "Protocol is rmi but JNDI scheme is iiop: " + jmxServiceURL); mfe.initCause(re); throw mfe; } } throw re; } // Always use one of: // ClassLoader provided in Map at connect time, // or contextClassLoader at connect time. if (tracing) logger.trace("connect",idstr + " getting class loader..."); defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap); usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER, defaultClassLoader); rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap); env = usemap; final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap); communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod); connected = true; // The connectionId variable is used in doStart(), when // reconnecting, to identify the "old" connection. // connectionId = getConnectionId(); Notification connectedNotif = new JMXConnectionNotification(JMXConnectionNotification.OPENED, this, connectionId, clientNotifSeqNo++, "Successful connection", null); sendNotification(connectedNotif); if (tracing) logger.trace("connect",idstr + " done..."); } catch (IOException e) { if (tracing) logger.trace("connect",idstr + " failed to connect: " + e); throw e; } catch (RuntimeException e) { if (tracing) logger.trace("connect",idstr + " failed to connect: " + e); throw e; } catch (NamingException e) { final String msg = "Failed to retrieve RMIServer stub: " + e; if (tracing) logger.trace("connect",idstr + " " + msg); throw EnvHelp.initCause(new IOException(msg),e); } } public synchronized String getConnectionId() throws IOException { if (terminated || !connected) { if (logger.traceOn()) logger.trace("getConnectionId","["+this.toString()+ "] not connected."); throw new IOException("Not connected"); } // we do a remote call to have an IOException if the connection is broken. // see the bug 4939578 return connection.getConnectionId(); } public synchronized MBeanServerConnection getMBeanServerConnection() throws IOException { return getMBeanServerConnection(null); } public synchronized MBeanServerConnection getMBeanServerConnection(Subject delegationSubject) throws IOException { if (terminated) { if (logger.traceOn()) logger.trace("getMBeanServerConnection","[" + this.toString() + "] already closed."); throw new IOException("Connection closed"); } else if (!connected) { if (logger.traceOn()) logger.trace("getMBeanServerConnection","[" + this.toString() + "] is not connected."); throw new IOException("Not connected"); } MBeanServerConnection rmbsc = rmbscMap.get(delegationSubject); if (rmbsc != null) { return rmbsc; } rmbsc = new RemoteMBeanServerConnection(delegationSubject); rmbscMap.put(delegationSubject, rmbsc); return rmbsc; } public void addConnectionNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.addNotificationListener(listener, filter, handback); } public void removeConnectionNotificationListener(NotificationListener listener) throws ListenerNotFoundException { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.removeNotificationListener(listener); } public void removeConnectionNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException { if (listener == null) throw new NullPointerException("listener"); connectionBroadcaster.removeNotificationListener(listener, filter, handback); } private void sendNotification(Notification n) { connectionBroadcaster.sendNotification(n); } public synchronized void close() throws IOException { close(false); } // allows to do close after setting the flag "terminated" to true. // It is necessary to avoid a deadlock, see 6296324 private synchronized void close(boolean intern) throws IOException { final boolean tracing = logger.traceOn(); final boolean debug = logger.debugOn(); final String idstr = (tracing?"["+this.toString()+"]":null); if (!intern) { // Return if already cleanly closed. // if (terminated) { if (closeException == null) { if (tracing) logger.trace("close",idstr + " already closed."); return; } } else { terminated = true; } } if (closeException != null && tracing) { // Already closed, but not cleanly. Attempt again. // if (tracing) { logger.trace("close",idstr + " had failed: " + closeException); logger.trace("close",idstr + " attempting to close again."); } } String savedConnectionId = null; if (connected) { savedConnectionId = connectionId; } closeException = null; if (tracing) logger.trace("close",idstr + " closing."); if (communicatorAdmin != null) { communicatorAdmin.terminate(); } if (rmiNotifClient != null) { try { rmiNotifClient.terminate(); if (tracing) logger.trace("close",idstr + " RMI Notification client terminated."); } catch (RuntimeException x) { closeException = x; if (tracing) logger.trace("close",idstr + " Failed to terminate RMI Notification client: " + x); if (debug) logger.debug("close",x); } } if (connection != null) { try { connection.close();