< prev index next >

jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.management.remote.rmi;
  27 
  28 import com.sun.jmx.mbeanserver.Util;
  29 import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
  30 import com.sun.jmx.remote.internal.ClientListenerInfo;
  31 import com.sun.jmx.remote.internal.ClientNotifForwarder;
  32 import com.sun.jmx.remote.internal.ProxyRef;
  33 import com.sun.jmx.remote.util.ClassLogger;
  34 import com.sun.jmx.remote.util.EnvHelp;
  35 import java.io.ByteArrayInputStream;
  36 import java.io.IOException;
  37 import java.io.InputStream;
  38 import java.io.InvalidObjectException;
  39 import java.io.ObjectInputStream;
  40 import java.io.ObjectStreamClass;
  41 import java.io.Serializable;
  42 import java.lang.ref.WeakReference;
  43 import java.lang.reflect.Constructor;
  44 import java.lang.reflect.InvocationHandler;
  45 import java.lang.reflect.InvocationTargetException;
  46 import java.lang.reflect.Module;
  47 import java.lang.reflect.Proxy;
  48 import java.net.MalformedURLException;
  49 import java.rmi.MarshalledObject;
  50 import java.rmi.NoSuchObjectException;
  51 import java.rmi.Remote;
  52 import java.rmi.ServerException;


  89 import javax.management.NotificationFilterSupport;
  90 import javax.management.NotificationListener;
  91 import javax.management.ObjectInstance;
  92 import javax.management.ObjectName;
  93 import javax.management.QueryExp;
  94 import javax.management.ReflectionException;
  95 import javax.management.remote.JMXConnectionNotification;
  96 import javax.management.remote.JMXConnector;
  97 import javax.management.remote.JMXConnectorFactory;
  98 import javax.management.remote.JMXServiceURL;
  99 import javax.management.remote.NotificationResult;
 100 import javax.management.remote.JMXAddressable;
 101 import javax.naming.InitialContext;
 102 import javax.naming.NamingException;
 103 import javax.rmi.ssl.SslRMIClientSocketFactory;
 104 import javax.security.auth.Subject;
 105 import jdk.internal.module.Modules;
 106 import sun.reflect.misc.ReflectUtil;
 107 import sun.rmi.server.UnicastRef2;
 108 import sun.rmi.transport.LiveRef;

 109 
 110 /**
 111  * <p>A connection to a remote RMI connector.  Usually, such
 112  * connections are made using {@link
 113  * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}.
 114  * However, specialized applications can use this class directly, for
 115  * example with an {@link RMIServer} stub obtained without going
 116  * through JNDI.</p>
 117  *
 118  * @since 1.5
 119  */
 120 public class RMIConnector implements JMXConnector, Serializable, JMXAddressable {
 121 
 122     private static final ClassLogger logger =
 123             new ClassLogger("javax.management.remote.rmi", "RMIConnector");
 124 
 125     private static final long serialVersionUID = 817323035842634473L;
 126 


















 127     private RMIConnector(RMIServer rmiServer, JMXServiceURL address,
 128             Map<String, ?> environment) {
 129         if (rmiServer == null && address == null) throw new
 130                 IllegalArgumentException("rmiServer and jmxServiceURL both null");
 131         initTransients();
 132 
 133         this.rmiServer = rmiServer;
 134         this.jmxServiceURL = address;
 135         if (environment == null) {
 136             this.env = Collections.emptyMap();
 137         } else {
 138             EnvHelp.checkAttributes(environment);
 139             this.env = Collections.unmodifiableMap(environment);
 140         }
 141     }
 142 
 143     /**
 144      * <p>Constructs an {@code RMIConnector} that will connect
 145      * the RMI connector server with the given address.</p>
 146      *


1373                                 close(true);
1374                             } catch (Exception e) {
1375                                 // OK.
1376                                 // We are closing
1377                             }
1378                             throw ioe; // the connection is closed here.
1379                         } else {
1380                             // JDK-8049303 possible transient network problem,
1381                             // let's try one more time
1382                             retried = true;
1383                         }
1384                     }
1385                 }
1386             }
1387         }
1388 
1389         private void rethrowDeserializationException(IOException ioe)
1390                 throws ClassNotFoundException, IOException {
1391             // specially treating for an UnmarshalException
1392             if (ioe instanceof UnmarshalException) {
1393                 throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs


1394                            // fetch one by one with UnmarshalException
1395             }
1396 
1397             // Not serialization problem, return.
1398         }
1399 
1400         protected Integer addListenerForMBeanRemovedNotif()
1401         throws IOException, InstanceNotFoundException {
1402             NotificationFilterSupport clientFilter =
1403                     new NotificationFilterSupport();
1404             clientFilter.enableType(
1405                     MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
1406             MarshalledObject<NotificationFilter> sFilter =
1407                 new MarshalledObject<NotificationFilter>(clientFilter);
1408 
1409             Integer[] listenerIDs;
1410             final ObjectName[] names =
1411                 new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
1412             final MarshalledObject<NotificationFilter>[] filters =
1413                 Util.cast(new MarshalledObject<?>[] {sFilter});


1918        MBeanServerConnection.getAttribute (or whatever)
1919        -> RMIConnectionImpl_Stub.getAttribute
1920           -> ProxyRef.invoke(...getAttribute...)
1921              -> UnicastRef.invoke(...getAttribute...)
1922                 -> internal RMI stuff
1923 
1924        Here UnicastRef is the RemoteRef created when the stub was
1925        deserialized (which is of some RMI internal class).  It and the
1926        "internal RMI stuff" are loaded by the bootstrap loader, so are
1927        transparent to the stack search.  The first non-bootstrap
1928        loader found is our ProxyRefLoader, as required.
1929 
1930        In a future version of this code as integrated into J2SE 5,
1931        this workaround could be replaced by direct access to the
1932        internals of RMI.  For now, we use the same code base for J2SE
1933        and for the standalone Reference Implementation.
1934 
1935        The byte code below encodes the following class, compiled using
1936        J2SE 1.4.2 with the -g:none option.
1937 
1938         package com.sun.jmx.remote.internal;
1939 
1940         import java.lang.reflect.Method;
1941         import java.rmi.Remote;
1942         import java.rmi.server.RemoteRef;
1943         import com.sun.jmx.remote.internal.ProxyRef;
1944 
1945         public class PRef extends ProxyRef {
1946             public PRef(RemoteRef ref) {
1947                 super(ref);
1948             }
1949 
1950             public Object invoke(Remote obj, Method method,
1951                                  Object[] params, long opnum)
1952                     throws Exception {
1953                 return ref.invoke(obj, method, params, opnum);
1954             }
1955         }
1956      */
1957 
1958     private static final String rmiServerImplStubClassName =
1959         RMIServer.class.getName() + "Impl_Stub";
1960     private static final Class<?> rmiServerImplStubClass;
1961     private static final String rmiConnectionImplStubClassName =
1962             RMIConnection.class.getName() + "Impl_Stub";
1963     private static final Class<?> rmiConnectionImplStubClass;
1964     private static final String pRefClassName =
1965         "jdk.jmx.remote.internal.PRef";
1966     private static final Constructor<?> proxyRefConstructor;
1967     static {
1968         final String pRefByteCodeString =
1969                 "\312\376\272\276\0\0\0\60\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17"+
1970                 "\0\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/Remote"+
1971                 "Ref;)V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/"+
1972                 "reflect/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12E"+
1973                 "xceptions\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1"+
1974                 "\0\34jdk/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/inter"+
1975                 "nal/ProxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rm"+
1976                 "i/server/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5"+
1977                 "\0\0\0\0\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0\6*+\267"+
1978                 "\0\1\261\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0\6\0\0\0"+
1979                 "\17*\264\0\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0\4\0\1\0"+
1980                 "\14\0\0";
1981         final byte[] pRefByteCode =
1982                 NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
1983         PrivilegedExceptionAction<Constructor<?>> action =
1984                 new PrivilegedExceptionAction<Constructor<?>>() {
1985             public Constructor<?> run() throws Exception {
1986                 Class<RMIConnector> thisClass = RMIConnector.class;
1987                 ClassLoader thisLoader = thisClass.getClassLoader();
1988                 ProtectionDomain thisProtectionDomain =
1989                         thisClass.getProtectionDomain();
1990 
1991                 String proxyRefCName = ProxyRef.class.getName();
1992                 ClassLoader cl =
1993                         new NoCallStackClassLoader(pRefClassName,
1994                         pRefByteCode,
1995                         new String[] { proxyRefCName },
1996                         thisLoader,
1997                         thisProtectionDomain);
1998 
1999                 Module jmxModule = ProxyRef.class.getModule();
2000                 Module rmiModule = RemoteRef.class.getModule();




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.management.remote.rmi;
  27 

  28 import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
  29 import com.sun.jmx.remote.internal.ClientListenerInfo;
  30 import com.sun.jmx.remote.internal.ClientNotifForwarder;
  31 import com.sun.jmx.remote.internal.rmi.ProxyRef;
  32 import com.sun.jmx.remote.util.ClassLogger;
  33 import com.sun.jmx.remote.util.EnvHelp;
  34 import java.io.ByteArrayInputStream;
  35 import java.io.IOException;
  36 import java.io.InputStream;
  37 import java.io.InvalidObjectException;
  38 import java.io.ObjectInputStream;
  39 import java.io.ObjectStreamClass;
  40 import java.io.Serializable;
  41 import java.lang.ref.WeakReference;
  42 import java.lang.reflect.Constructor;
  43 import java.lang.reflect.InvocationHandler;
  44 import java.lang.reflect.InvocationTargetException;
  45 import java.lang.reflect.Module;
  46 import java.lang.reflect.Proxy;
  47 import java.net.MalformedURLException;
  48 import java.rmi.MarshalledObject;
  49 import java.rmi.NoSuchObjectException;
  50 import java.rmi.Remote;
  51 import java.rmi.ServerException;


  88 import javax.management.NotificationFilterSupport;
  89 import javax.management.NotificationListener;
  90 import javax.management.ObjectInstance;
  91 import javax.management.ObjectName;
  92 import javax.management.QueryExp;
  93 import javax.management.ReflectionException;
  94 import javax.management.remote.JMXConnectionNotification;
  95 import javax.management.remote.JMXConnector;
  96 import javax.management.remote.JMXConnectorFactory;
  97 import javax.management.remote.JMXServiceURL;
  98 import javax.management.remote.NotificationResult;
  99 import javax.management.remote.JMXAddressable;
 100 import javax.naming.InitialContext;
 101 import javax.naming.NamingException;
 102 import javax.rmi.ssl.SslRMIClientSocketFactory;
 103 import javax.security.auth.Subject;
 104 import jdk.internal.module.Modules;
 105 import sun.reflect.misc.ReflectUtil;
 106 import sun.rmi.server.UnicastRef2;
 107 import sun.rmi.transport.LiveRef;
 108 import java.io.NotSerializableException;
 109 
 110 /**
 111  * <p>A connection to a remote RMI connector.  Usually, such
 112  * connections are made using {@link
 113  * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}.
 114  * However, specialized applications can use this class directly, for
 115  * example with an {@link RMIServer} stub obtained without going
 116  * through JNDI.</p>
 117  *
 118  * @since 1.5
 119  */
 120 public class RMIConnector implements JMXConnector, Serializable, JMXAddressable {
 121 
 122     private static final ClassLogger logger =
 123             new ClassLogger("javax.management.remote.rmi", "RMIConnector");
 124 
 125     private static final long serialVersionUID = 817323035842634473L;
 126 
 127     static final class Util {
 128         private Util() {}
 129 
 130         /* This method can be used by code that is deliberately violating the
 131          * allowed checked casts.  Rather than marking the whole method containing
 132          * the code with @SuppressWarnings, you can use a call to this method for
 133          * the exact place where you need to escape the constraints.  Typically
 134          * you will "import static" this method and then write either
 135          *    X x = cast(y);
 136          * or, if that doesn't work (e.g. X is a type variable)
 137          *    Util.<X>cast(y);
 138          */
 139         @SuppressWarnings("unchecked")
 140         public static <T> T cast(Object x) {
 141             return (T) x;
 142         }
 143     }
 144 
 145     private RMIConnector(RMIServer rmiServer, JMXServiceURL address,
 146             Map<String, ?> environment) {
 147         if (rmiServer == null && address == null) throw new
 148                 IllegalArgumentException("rmiServer and jmxServiceURL both null");
 149         initTransients();
 150 
 151         this.rmiServer = rmiServer;
 152         this.jmxServiceURL = address;
 153         if (environment == null) {
 154             this.env = Collections.emptyMap();
 155         } else {
 156             EnvHelp.checkAttributes(environment);
 157             this.env = Collections.unmodifiableMap(environment);
 158         }
 159     }
 160 
 161     /**
 162      * <p>Constructs an {@code RMIConnector} that will connect
 163      * the RMI connector server with the given address.</p>
 164      *


1391                                 close(true);
1392                             } catch (Exception e) {
1393                                 // OK.
1394                                 // We are closing
1395                             }
1396                             throw ioe; // the connection is closed here.
1397                         } else {
1398                             // JDK-8049303 possible transient network problem,
1399                             // let's try one more time
1400                             retried = true;
1401                         }
1402                     }
1403                 }
1404             }
1405         }
1406 
1407         private void rethrowDeserializationException(IOException ioe)
1408                 throws ClassNotFoundException, IOException {
1409             // specially treating for an UnmarshalException
1410             if (ioe instanceof UnmarshalException) {
1411                 NotSerializableException nse = new NotSerializableException();
1412                 nse.initCause(ioe);
1413                 throw nse; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
1414                            // fetch one by one with UnmarshalException
1415             }
1416 
1417             // Not serialization problem, return.
1418         }
1419 
1420         protected Integer addListenerForMBeanRemovedNotif()
1421         throws IOException, InstanceNotFoundException {
1422             NotificationFilterSupport clientFilter =
1423                     new NotificationFilterSupport();
1424             clientFilter.enableType(
1425                     MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
1426             MarshalledObject<NotificationFilter> sFilter =
1427                 new MarshalledObject<NotificationFilter>(clientFilter);
1428 
1429             Integer[] listenerIDs;
1430             final ObjectName[] names =
1431                 new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
1432             final MarshalledObject<NotificationFilter>[] filters =
1433                 Util.cast(new MarshalledObject<?>[] {sFilter});


1938        MBeanServerConnection.getAttribute (or whatever)
1939        -> RMIConnectionImpl_Stub.getAttribute
1940           -> ProxyRef.invoke(...getAttribute...)
1941              -> UnicastRef.invoke(...getAttribute...)
1942                 -> internal RMI stuff
1943 
1944        Here UnicastRef is the RemoteRef created when the stub was
1945        deserialized (which is of some RMI internal class).  It and the
1946        "internal RMI stuff" are loaded by the bootstrap loader, so are
1947        transparent to the stack search.  The first non-bootstrap
1948        loader found is our ProxyRefLoader, as required.
1949 
1950        In a future version of this code as integrated into J2SE 5,
1951        this workaround could be replaced by direct access to the
1952        internals of RMI.  For now, we use the same code base for J2SE
1953        and for the standalone Reference Implementation.
1954 
1955        The byte code below encodes the following class, compiled using
1956        J2SE 1.4.2 with the -g:none option.
1957 
1958         package jdk.jmx.remote.internal.rmi;
1959 
1960         import java.lang.reflect.Method;
1961         import java.rmi.Remote;
1962         import java.rmi.server.RemoteRef;
1963         import com.sun.jmx.remote.internal.rmi.ProxyRef;
1964 
1965         public class PRef extends ProxyRef {
1966             public PRef(RemoteRef ref) {
1967                 super(ref);
1968             }
1969 
1970             public Object invoke(Remote obj, Method method,
1971                                  Object[] params, long opnum)
1972                     throws Exception {
1973                 return ref.invoke(obj, method, params, opnum);
1974             }
1975         }
1976      */
1977 
1978     private static final String rmiServerImplStubClassName =
1979         RMIServer.class.getName() + "Impl_Stub";
1980     private static final Class<?> rmiServerImplStubClass;
1981     private static final String rmiConnectionImplStubClassName =
1982             RMIConnection.class.getName() + "Impl_Stub";
1983     private static final Class<?> rmiConnectionImplStubClass;
1984     private static final String pRefClassName =
1985         "jdk.jmx.remote.internal.rmi.PRef";
1986     private static final Constructor<?> proxyRefConstructor;
1987     static {
1988         final String pRefByteCodeString =
1989                 "\312\376\272\276\0\0\0\65\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17"+
1990                 "\0\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/Remote"+
1991                 "Ref;)V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/"+
1992                 "reflect/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12E"+
1993                 "xceptions\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1"+
1994                 "\0 jdk/jmx/remote/internal/rmi/PRef\1\0(com/sun/jmx/remote/int"+
1995                 "ernal/rmi/ProxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Lj"+
1996                 "ava/rmi/server/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0"+
1997                 "\4\0\5\0\0\0\0\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0"+
1998                 "\6*+\267\0\1\261\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0"+
1999                 "\6\0\0\0\17*\264\0\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0"+
2000                 "\4\0\1\0\14\0\0";
2001         final byte[] pRefByteCode =
2002                 NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
2003         PrivilegedExceptionAction<Constructor<?>> action =
2004                 new PrivilegedExceptionAction<Constructor<?>>() {
2005             public Constructor<?> run() throws Exception {
2006                 Class<RMIConnector> thisClass = RMIConnector.class;
2007                 ClassLoader thisLoader = thisClass.getClassLoader();
2008                 ProtectionDomain thisProtectionDomain =
2009                         thisClass.getProtectionDomain();
2010 
2011                 String proxyRefCName = ProxyRef.class.getName();
2012                 ClassLoader cl =
2013                         new NoCallStackClassLoader(pRefClassName,
2014                         pRefByteCode,
2015                         new String[] { proxyRefCName },
2016                         thisLoader,
2017                         thisProtectionDomain);
2018 
2019                 Module jmxModule = ProxyRef.class.getModule();
2020                 Module rmiModule = RemoteRef.class.getModule();


< prev index next >