/* | 
|
 * Copyright (c) 1996, 2013, 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 java.rmi.server;  | 
|
import java.rmi.*;  | 
|
import sun.rmi.server.UnicastServerRef;  | 
|
import sun.rmi.server.UnicastServerRef2;  | 
|
/** | 
|
 * Used for exporting a remote object with JRMP and obtaining a stub | 
|
 * that communicates to the remote object. Stubs are either generated | 
|
 * at runtime using dynamic proxy objects, or they are generated statically | 
|
 * at build time, typically using the {@code rmic} tool. | 
|
 * | 
|
 * <p><strong>Deprecated: Static Stubs.</strong> <em>Support for statically | 
|
 * generated stubs is deprecated. This includes the API in this class that | 
|
 * requires the use of static stubs, as well as the runtime support for | 
|
 * loading static stubs.  Generating stubs dynamically is preferred, using one | 
|
 * of the five non-deprecated ways of exporting objects as listed below. Do | 
|
 * not run {@code rmic} to generate static stub classes. It is unnecessary, and | 
|
 * it is also deprecated.</em> | 
|
 * | 
|
 * <p>There are six ways to export remote objects: | 
|
 * | 
|
 * <ol> | 
|
 * | 
|
 * <li>Subclassing {@code UnicastRemoteObject} and calling the | 
|
 * {@link #UnicastRemoteObject()} constructor. | 
|
 * | 
|
 * <li>Subclassing {@code UnicastRemoteObject} and calling the | 
|
 * {@link #UnicastRemoteObject(int) UnicastRemoteObject(port)} constructor. | 
|
 * | 
|
 * <li>Subclassing {@code UnicastRemoteObject} and calling the | 
|
 * {@link #UnicastRemoteObject(int, RMIClientSocketFactory, RMIServerSocketFactory) | 
|
 * UnicastRemoteObject(port, csf, ssf)} constructor. | 
|
 * | 
|
 * <li>Calling the | 
|
 * {@link #exportObject(Remote) exportObject(Remote)} method. | 
|
 * <strong>Deprecated.</strong> | 
|
 * | 
|
 * <li>Calling the | 
|
 * {@link #exportObject(Remote, int) exportObject(Remote, port)} method. | 
|
 * | 
|
 * <li>Calling the | 
|
 * {@link #exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory) | 
|
 * exportObject(Remote, port, csf, ssf)} method. | 
|
 * | 
|
 * </ol> | 
|
 * | 
|
 * <p>The fourth technique, {@link #exportObject(Remote)}, | 
|
 * always uses statically generated stubs and is deprecated. | 
|
 * | 
|
 * <p>The other five techniques all use the following approach: if the | 
|
 * {@code java.rmi.server.ignoreStubClasses} property is {@code true} | 
|
 * (case insensitive) or if a static stub cannot be found, stubs are generated | 
|
 * dynamically using {@link java.lang.reflect.Proxy Proxy} objects. Otherwise, | 
|
 * static stubs are used. | 
|
 * | 
|
 * <p>The default value of the | 
|
 * {@code java.rmi.server.ignoreStubClasses} property is {@code false}. | 
|
 * | 
|
 * <p>Statically generated stubs are typically pregenerated from the | 
|
 * remote object's class using the {@code rmic} tool. A static stub is | 
|
 * loaded and an instance of that stub class is constructed as described | 
|
 * below. | 
|
 * | 
|
 * <ul> | 
|
 * | 
|
 * <li>A "root class" is determined as follows: if the remote object's | 
|
 * class directly implements an interface that extends {@link Remote}, then | 
|
 * the remote object's class is the root class; otherwise, the root class is | 
|
 * the most derived superclass of the remote object's class that directly | 
|
 * implements an interface that extends {@code Remote}. | 
|
 * | 
|
 * <li>The name of the stub class to load is determined by concatenating | 
|
 * the binary name of the root class with the suffix {@code _Stub}. | 
|
 * | 
|
 * <li>The stub class is loaded by name using the class loader of the root | 
|
 * class. The stub class must extend {@link RemoteStub} and must have a | 
|
 * public constructor that has one parameter of type {@link RemoteRef}. | 
|
 * | 
|
 * <li>Finally, an instance of the stub class is constructed with a | 
|
 * {@link RemoteRef}. | 
|
 * | 
|
 * <li>If the appropriate stub class could not be found, or if the stub class | 
|
 * could not be loaded, or if a problem occurs creating the stub instance, a | 
|
 * {@link StubNotFoundException} is thrown. | 
|
 * | 
|
 * </ul> | 
|
 * | 
|
 * <p>Stubs are dynamically generated by constructing an instance of | 
|
 * a {@link java.lang.reflect.Proxy Proxy} with the following characteristics: | 
|
 * | 
|
 * <ul> | 
|
 * | 
|
 * <li>The proxy's class is defined by the class loader of the remote | 
|
 * object's class. | 
|
 * | 
|
 * <li>The proxy implements all the remote interfaces implemented by the | 
|
 * remote object's class. | 
|
 * | 
|
 * <li>The proxy's invocation handler is a {@link | 
|
 * RemoteObjectInvocationHandler} instance constructed with a | 
|
 * {@link RemoteRef}. | 
|
 * | 
|
 * <li>If the proxy could not be created, a {@link StubNotFoundException} | 
|
 * will be thrown. | 
|
 * | 
|
 * </ul> | 
|
 * | 
|
 * @implNote | 
|
 * Depending upon which constructor or static method is used for exporting an | 
|
 * object, {@link RMISocketFactory} may be used for creating sockets. | 
|
 * By default, server sockets created by {@link RMISocketFactory} | 
|
 * listen on all network interfaces. See the | 
|
 * {@link RMISocketFactory} class and the section | 
|
 * <a href="{@docRoot}/../platform/rmi/spec/rmi-server29.html">RMI Socket Factories</a> | 
|
 * in the | 
|
 * <a href="{@docRoot}/../platform/rmi/spec/rmiTOC.html">Java RMI Specification</a>. | 
|
 * | 
|
 * @author  Ann Wollrath | 
|
 * @author  Peter Jones | 
|
 * @since   JDK1.1 | 
|
**/  | 
|
public class UnicastRemoteObject extends RemoteServer {  | 
|
    /** | 
|
     * @serial port number on which to export object | 
|
*/  | 
|
private int port = 0;  | 
|
    /** | 
|
     * @serial client-side socket factory (if any) | 
|
*/  | 
|
private RMIClientSocketFactory csf = null;  | 
|
    /** | 
|
     * @serial server-side socket factory (if any) to use when | 
|
     * exporting object | 
|
*/  | 
|
private RMIServerSocketFactory ssf = null;  | 
|
    /* indicate compatibility with JDK 1.1.x version of class */ | 
|
private static final long serialVersionUID = 4974527148936298033L;  | 
|
    /** | 
|
     * Creates and exports a new UnicastRemoteObject object using an | 
|
     * anonymous port. | 
|
     * | 
|
     * <p>The object is exported with a server socket | 
|
     * created using the {@link RMISocketFactory} class. | 
|
     * | 
|
     * @throws RemoteException if failed to export object | 
|
     * @since JDK1.1 | 
|
*/  | 
|
protected UnicastRemoteObject() throws RemoteException  | 
|
    { | 
|
this(0);  | 
|
}  | 
|
    /** | 
|
     * Creates and exports a new UnicastRemoteObject object using the | 
|
     * particular supplied port. | 
|
     * | 
|
     * <p>The object is exported with a server socket | 
|
     * created using the {@link RMISocketFactory} class. | 
|
     * | 
|
     * @param port the port number on which the remote object receives calls | 
|
     * (if <code>port</code> is zero, an anonymous port is chosen) | 
|
     * @throws RemoteException if failed to export object | 
|
     * @since 1.2 | 
|
*/  | 
|
protected UnicastRemoteObject(int port) throws RemoteException  | 
|
    { | 
|
this.port = port;  | 
|
exportObject((Remote) this, port);  | 
|
}  | 
|
    /** | 
|
     * Creates and exports a new UnicastRemoteObject object using the | 
|
     * particular supplied port and socket factories. | 
|
     * | 
|
     * <p>Either socket factory may be {@code null}, in which case | 
|
     * the corresponding client or server socket creation method of | 
|
     * {@link RMISocketFactory} is used instead. | 
|
     * | 
|
     * @param port the port number on which the remote object receives calls | 
|
     * (if <code>port</code> is zero, an anonymous port is chosen) | 
|
     * @param csf the client-side socket factory for making calls to the | 
|
     * remote object | 
|
     * @param ssf the server-side socket factory for receiving remote calls | 
|
     * @throws RemoteException if failed to export object | 
|
     * @since 1.2 | 
|
*/  | 
|
protected UnicastRemoteObject(int port,  | 
|
RMIClientSocketFactory csf,  | 
|
RMIServerSocketFactory ssf)  | 
|
throws RemoteException  | 
|
    { | 
|
this.port = port;  | 
|
this.csf = csf;  | 
|
this.ssf = ssf;  | 
|
exportObject((Remote) this, port, csf, ssf);  | 
|
}  | 
|
    /** | 
|
     * Re-export the remote object when it is deserialized. | 
|
*/  | 
|
private void readObject(java.io.ObjectInputStream in)  | 
|
throws java.io.IOException, java.lang.ClassNotFoundException  | 
|
    { | 
|
in.defaultReadObject();  | 
|
reexport();  | 
|
}  | 
|
    /** | 
|
     * Returns a clone of the remote object that is distinct from | 
|
     * the original. | 
|
     * | 
|
     * @exception CloneNotSupportedException if clone failed due to | 
|
     * a RemoteException. | 
|
     * @return the new remote object | 
|
     * @since JDK1.1 | 
|
*/  | 
|
public Object clone() throws CloneNotSupportedException  | 
|
    { | 
|
        try { | 
|
UnicastRemoteObject cloned = (UnicastRemoteObject) super.clone();  | 
|
cloned.reexport();  | 
|
return cloned;  | 
|
} catch (RemoteException e) {  | 
|
throw new ServerCloneException("Clone failed", e);  | 
|
}  | 
|
}  | 
|
    /* | 
|
     * Exports this UnicastRemoteObject using its initialized fields because | 
|
     * its creation bypassed running its constructors (via deserialization | 
|
     * or cloning, for example). | 
|
*/  | 
|
private void reexport() throws RemoteException  | 
|
    { | 
|
if (csf == null && ssf == null) {  | 
|
exportObject((Remote) this, port);  | 
|
        } else { | 
|
exportObject((Remote) this, port, csf, ssf);  | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Exports the remote object to make it available to receive incoming | 
|
     * calls using an anonymous port. This method will always return a | 
|
     * statically generated stub. | 
|
     * | 
|
     * <p>The object is exported with a server socket | 
|
     * created using the {@link RMISocketFactory} class. | 
|
     * | 
|
     * @param obj the remote object to be exported | 
|
     * @return remote object stub | 
|
     * @exception RemoteException if export fails | 
|
     * @since JDK1.1 | 
|
     * @deprecated This method is deprecated because it supports only static stubs. | 
|
     * Use {@link #exportObject(Remote, int) exportObject(Remote, port)} or | 
|
     * {@link #exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory) | 
|
     * exportObject(Remote, port, csf, ssf)} | 
|
     * instead. | 
|
*/  | 
|
@Deprecated  | 
|
public static RemoteStub exportObject(Remote obj)  | 
|
throws RemoteException  | 
|
    { | 
|
        /* | 
|
         * Use UnicastServerRef constructor passing the boolean value true | 
|
         * to indicate that only a generated stub class should be used.  A | 
|
         * generated stub class must be used instead of a dynamic proxy | 
|
         * because the return value of this method is RemoteStub which a | 
|
         * dynamic proxy class cannot extend. | 
|
*/  | 
|
return (RemoteStub) exportObject(obj, new UnicastServerRef(true));  | 
|
}  | 
|
    /** | 
|
     * Exports the remote object to make it available to receive incoming | 
|
     * calls, using the particular supplied port. | 
|
     * | 
|
     * <p>The object is exported with a server socket | 
|
     * created using the {@link RMISocketFactory} class. | 
|
     * | 
|
     * @param obj the remote object to be exported | 
|
     * @param port the port to export the object on | 
|
     * @return remote object stub | 
|
     * @exception RemoteException if export fails | 
|
     * @since 1.2 | 
|
*/  | 
|
public static Remote exportObject(Remote obj, int port)  | 
|
throws RemoteException  | 
|
    { | 
|
return exportObject(obj, new UnicastServerRef(port));  | 
|
}  | 
|
    /** | 
|
     * Exports the remote object to make it available to receive incoming | 
|
     * calls, using a transport specified by the given socket factory. | 
|
     * | 
|
     * <p>Either socket factory may be {@code null}, in which case | 
|
     * the corresponding client or server socket creation method of | 
|
     * {@link RMISocketFactory} is used instead. | 
|
     * | 
|
     * @param obj the remote object to be exported | 
|
     * @param port the port to export the object on | 
|
     * @param csf the client-side socket factory for making calls to the | 
|
     * remote object | 
|
     * @param ssf the server-side socket factory for receiving remote calls | 
|
     * @return remote object stub | 
|
     * @exception RemoteException if export fails | 
|
     * @since 1.2 | 
|
*/  | 
|
public static Remote exportObject(Remote obj, int port,  | 
|
RMIClientSocketFactory csf,  | 
|
RMIServerSocketFactory ssf)  | 
|
throws RemoteException  | 
|
    { | 
|
return exportObject(obj, new UnicastServerRef2(port, csf, ssf));  | 
|
}  | 
|
    /** | 
|
     * Removes the remote object, obj, from the RMI runtime. If | 
|
     * successful, the object can no longer accept incoming RMI calls. | 
|
     * If the force parameter is true, the object is forcibly unexported | 
|
     * even if there are pending calls to the remote object or the | 
|
     * remote object still has calls in progress.  If the force | 
|
     * parameter is false, the object is only unexported if there are | 
|
     * no pending or in progress calls to the object. | 
|
     * | 
|
     * @param obj the remote object to be unexported | 
|
     * @param force if true, unexports the object even if there are | 
|
     * pending or in-progress calls; if false, only unexports the object | 
|
     * if there are no pending or in-progress calls | 
|
     * @return true if operation is successful, false otherwise | 
|
     * @exception NoSuchObjectException if the remote object is not | 
|
     * currently exported | 
|
     * @since 1.2 | 
|
*/  | 
|
public static boolean unexportObject(Remote obj, boolean force)  | 
|
throws java.rmi.NoSuchObjectException  | 
|
    { | 
|
return sun.rmi.transport.ObjectTable.unexportObject(obj, force);  | 
|
}  | 
|
    /** | 
|
     * Exports the specified object using the specified server ref. | 
|
*/  | 
|
private static Remote exportObject(Remote obj, UnicastServerRef sref)  | 
|
throws RemoteException  | 
|
    { | 
|
        // if obj extends UnicastRemoteObject, set its ref. | 
|
if (obj instanceof UnicastRemoteObject) {  | 
|
((UnicastRemoteObject) obj).ref = sref;  | 
|
}  | 
|
return sref.exportObject(obj, null, false);  | 
|
}  | 
|
}  |