📄 rmiconnector.java
字号:
/* * @(#)RMIConnector.java 1.131 07/12/13 * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package javax.management.remote.rmi;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.ProxyInputStream;import com.sun.jmx.remote.internal.ProxyRef;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.CORBA.Stub;import javax.rmi.PortableRemoteObject;import javax.rmi.ssl.SslRMIClientSocketFactory;import javax.security.auth.Subject;import org.omg.CORBA.BAD_OPERATION;import org.omg.CORBA.ORB;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 * @since.unbundled 1.0 */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 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.EMPTY_MAP; } 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. **/ public String toString() { final StringBuffer b = new StringBuffer(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 usemap = new HashMap((this.env==null)?Collections.EMPTY_MAP: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"); 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); connection = getConnection(stub, credentials, checkStub); // 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 mbsc = (MBeanServerConnection) rmbscMap.get(delegationSubject); if (mbsc != null) return mbsc; mbsc = new RemoteMBeanServerConnection(delegationSubject); rmbscMap.put(delegationSubject, mbsc); return mbsc; } public void addConnectionNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { if (listener == null) throw new NullPointerException("listener");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -