001 /*
002 * Copyright 1996-2003 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package java.rmi.server;
026
027 import java.rmi.*;
028 import sun.rmi.server.UnicastServerRef;
029 import sun.rmi.server.UnicastServerRef2;
030
031 /**
032 * Used for exporting a remote object with JRMP and obtaining a stub
033 * that communicates to the remote object.
034 *
035 * <p>For the constructors and static <code>exportObject</code> methods
036 * below, the stub for a remote object being exported is obtained as
037 * follows:
038 *
039 * <p><ul>
040 *
041 * <li>If the remote object is exported using the {@link
042 * #exportObject(Remote) UnicastRemoteObject.exportObject(Remote)} method,
043 * a stub class (typically pregenerated from the remote object's class
044 * using the <code>rmic</code> tool) is loaded and an instance of that stub
045 * class is constructed as follows.
046 * <ul>
047 *
048 * <li>A "root class" is determined as follows: if the remote object's
049 * class directly implements an interface that extends {@link Remote}, then
050 * the remote object's class is the root class; otherwise, the root class is
051 * the most derived superclass of the remote object's class that directly
052 * implements an interface that extends <code>Remote</code>.
053 *
054 * <li>The name of the stub class to load is determined by concatenating
055 * the binary name of the root class with the suffix <code>"_Stub"</code>.
056 *
057 * <li>The stub class is loaded by name using the class loader of the root
058 * class. The stub class must extend {@link RemoteStub} and must have a
059 * public constructor that has one parameter, of type {@link RemoteRef}.
060 *
061 * <li>Finally, an instance of the stub class is constructed with a
062 * {@link RemoteRef}.
063 * </ul>
064 *
065 * <li>If the appropriate stub class could not be found, or the stub class
066 * could not be loaded, or a problem occurs creating the stub instance, a
067 * {@link StubNotFoundException} is thrown.
068 *
069 * <p>
070 * <li>For all other means of exporting:
071 * <p><ul>
072 *
073 * <li>If the remote object's stub class (as defined above) could not be
074 * loaded or the system property
075 * <code>java.rmi.server.ignoreStubClasses</code> is set to
076 * <code>"true"</code> (case insensitive), a {@link
077 * java.lang.reflect.Proxy} instance is constructed with the following
078 * properties:
079 *
080 * <ul>
081 *
082 * <li>The proxy's class is defined by the class loader of the remote
083 * object's class.
084 *
085 * <li>The proxy implements all the remote interfaces implemented by the
086 * remote object's class.
087 *
088 * <li>The proxy's invocation handler is a {@link
089 * RemoteObjectInvocationHandler} instance constructed with a
090 * {@link RemoteRef}.
091 *
092 * <li>If the proxy could not be created, a {@link StubNotFoundException}
093 * will be thrown.
094 * </ul>
095 *
096 * <p>
097 * <li>Otherwise, an instance of the remote object's stub class (as
098 * described above) is used as the stub.
099 *
100 * </ul>
101 * </ul>
102 *
103 * @version 1.39, 05/05/07
104 * @author Ann Wollrath
105 * @author Peter Jones
106 * @since JDK1.1
107 **/
108 public class UnicastRemoteObject extends RemoteServer {
109
110 /**
111 * @serial port number on which to export object
112 */
113 private int port = 0;
114
115 /**
116 * @serial client-side socket factory (if any)
117 */
118 private RMIClientSocketFactory csf = null;
119
120 /**
121 * @serial server-side socket factory (if any) to use when
122 * exporting object
123 */
124 private RMIServerSocketFactory ssf = null;
125
126 /* indicate compatibility with JDK 1.1.x version of class */
127 private static final long serialVersionUID = 4974527148936298033L;
128
129 /**
130 * Creates and exports a new UnicastRemoteObject object using an
131 * anonymous port.
132 * @throws RemoteException if failed to export object
133 * @since JDK1.1
134 */
135 protected UnicastRemoteObject() throws RemoteException {
136 this (0);
137 }
138
139 /**
140 * Creates and exports a new UnicastRemoteObject object using the
141 * particular supplied port.
142 * @param port the port number on which the remote object receives calls
143 * (if <code>port</code> is zero, an anonymous port is chosen)
144 * @throws RemoteException if failed to export object
145 * @since 1.2
146 */
147 protected UnicastRemoteObject(int port) throws RemoteException {
148 this .port = port;
149 exportObject((Remote) this , port);
150 }
151
152 /**
153 * Creates and exports a new UnicastRemoteObject object using the
154 * particular supplied port and socket factories.
155 * @param port the port number on which the remote object receives calls
156 * (if <code>port</code> is zero, an anonymous port is chosen)
157 * @param csf the client-side socket factory for making calls to the
158 * remote object
159 * @param ssf the server-side socket factory for receiving remote calls
160 * @throws RemoteException if failed to export object
161 * @since 1.2
162 */
163 protected UnicastRemoteObject(int port, RMIClientSocketFactory csf,
164 RMIServerSocketFactory ssf) throws RemoteException {
165 this .port = port;
166 this .csf = csf;
167 this .ssf = ssf;
168 exportObject((Remote) this , port, csf, ssf);
169 }
170
171 /**
172 * Re-export the remote object when it is deserialized.
173 */
174 private void readObject(java.io.ObjectInputStream in)
175 throws java.io.IOException,
176 java.lang.ClassNotFoundException {
177 in.defaultReadObject();
178 reexport();
179 }
180
181 /**
182 * Returns a clone of the remote object that is distinct from
183 * the original.
184 *
185 * @exception CloneNotSupportedException if clone failed due to
186 * a RemoteException.
187 * @return the new remote object
188 * @since JDK1.1
189 */
190 public Object clone() throws CloneNotSupportedException {
191 try {
192 UnicastRemoteObject cloned = (UnicastRemoteObject) super
193 .clone();
194 cloned.reexport();
195 return cloned;
196 } catch (RemoteException e) {
197 throw new ServerCloneException("Clone failed", e);
198 }
199 }
200
201 /*
202 * Exports this UnicastRemoteObject using its initialized fields because
203 * its creation bypassed running its constructors (via deserialization
204 * or cloning, for example).
205 */
206 private void reexport() throws RemoteException {
207 if (csf == null && ssf == null) {
208 exportObject((Remote) this , port);
209 } else {
210 exportObject((Remote) this , port, csf, ssf);
211 }
212 }
213
214 /**
215 * Exports the remote object to make it available to receive incoming
216 * calls using an anonymous port.
217 * @param obj the remote object to be exported
218 * @return remote object stub
219 * @exception RemoteException if export fails
220 * @since JDK1.1
221 */
222 public static RemoteStub exportObject(Remote obj)
223 throws RemoteException {
224 /*
225 * Use UnicastServerRef constructor passing the boolean value true
226 * to indicate that only a generated stub class should be used. A
227 * generated stub class must be used instead of a dynamic proxy
228 * because the return value of this method is RemoteStub which a
229 * dynamic proxy class cannot extend.
230 */
231 return (RemoteStub) exportObject(obj,
232 new UnicastServerRef(true));
233 }
234
235 /**
236 * Exports the remote object to make it available to receive incoming
237 * calls, using the particular supplied port.
238 * @param obj the remote object to be exported
239 * @param port the port to export the object on
240 * @return remote object stub
241 * @exception RemoteException if export fails
242 * @since 1.2
243 */
244 public static Remote exportObject(Remote obj, int port)
245 throws RemoteException {
246 return exportObject(obj, new UnicastServerRef(port));
247 }
248
249 /**
250 * Exports the remote object to make it available to receive incoming
251 * calls, using a transport specified by the given socket factory.
252 * @param obj the remote object to be exported
253 * @param port the port to export the object on
254 * @param csf the client-side socket factory for making calls to the
255 * remote object
256 * @param ssf the server-side socket factory for receiving remote calls
257 * @return remote object stub
258 * @exception RemoteException if export fails
259 * @since 1.2
260 */
261 public static Remote exportObject(Remote obj, int port,
262 RMIClientSocketFactory csf, RMIServerSocketFactory ssf)
263 throws RemoteException {
264
265 return exportObject(obj, new UnicastServerRef2(port, csf, ssf));
266 }
267
268 /**
269 * Removes the remote object, obj, from the RMI runtime. If
270 * successful, the object can no longer accept incoming RMI calls.
271 * If the force parameter is true, the object is forcibly unexported
272 * even if there are pending calls to the remote object or the
273 * remote object still has calls in progress. If the force
274 * parameter is false, the object is only unexported if there are
275 * no pending or in progress calls to the object.
276 *
277 * @param obj the remote object to be unexported
278 * @param force if true, unexports the object even if there are
279 * pending or in-progress calls; if false, only unexports the object
280 * if there are no pending or in-progress calls
281 * @return true if operation is successful, false otherwise
282 * @exception NoSuchObjectException if the remote object is not
283 * currently exported
284 * @since 1.2
285 */
286 public static boolean unexportObject(Remote obj, boolean force)
287 throws java.rmi.NoSuchObjectException {
288 return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
289 }
290
291 /**
292 * Exports the specified object using the specified server ref.
293 */
294 private static Remote exportObject(Remote obj, UnicastServerRef sref)
295 throws RemoteException {
296 // if obj extends UnicastRemoteObject, set its ref.
297 if (obj instanceof UnicastRemoteObject) {
298 ((UnicastRemoteObject) obj).ref = sref;
299 }
300 return sref.exportObject(obj, null, false);
301 }
302 }
|