History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/rmi/server/RemoteObject.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/rmi/server/RemoteObject.java+458−0
@@ -0,0 +1,458 @@
1+/*
2+ * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
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 java.rmi.server;
27+
28+import java.rmi.Remote;
29+import java.rmi.NoSuchObjectException;
30+import java.lang.reflect.Proxy;
31+import sun.rmi.server.Util;
32+
33+/**
34+ * The <code>RemoteObject</code> class implements the
35+ * <code>java.lang.Object</code> behavior for remote objects.
36+ * <code>RemoteObject</code> provides the remote semantics of Object by
37+ * implementing methods for hashCode, equals, and toString.
38+ *
39+ * @author Ann Wollrath
40+ * @author Laird Dornin
41+ * @author Peter Jones
42+ * @since JDK1.1
43+ */
44+public abstract class RemoteObject implements Remote, java.io.Serializable {
45+
46+ /** The object's remote reference. */
47+ transient protected RemoteRef ref;
48+
49+ /** indicate compatibility with JDK 1.1.x version of class */
50+ private static final long serialVersionUID = -3215090123894869218L;
51+
52+ /**
53+ * Creates a remote object.
54+ */
55+ protected RemoteObject() {
56+ ref = null;
57+ }
58+
59+ /**
60+ * Creates a remote object, initialized with the specified remote
61+ * reference.
62+ * @param newref remote reference
63+ */
64+ protected RemoteObject(RemoteRef newref) {
65+ ref = newref;
66+ }
67+
68+ /**
69+ * Returns the remote reference for the remote object.
70+ *
71+ * <p>Note: The object returned from this method may be an instance of
72+ * an implementation-specific class. The <code>RemoteObject</code>
73+ * class ensures serialization portability of its instances' remote
74+ * references through the behavior of its custom
75+ * <code>writeObject</code> and <code>readObject</code> methods. An
76+ * instance of <code>RemoteRef</code> should not be serialized outside
77+ * of its <code>RemoteObject</code> wrapper instance or the result may
78+ * be unportable.
79+ *
80+ * @return remote reference for the remote object
81+ * @since 1.2
82+ */
83+ public RemoteRef getRef() {
84+ return ref;
85+ }
86+
87+ /**
88+ * Returns the stub for the remote object <code>obj</code> passed
89+ * as a parameter. This operation is only valid <i>after</i>
90+ * the object has been exported.
91+ * @param obj the remote object whose stub is needed
92+ * @return the stub for the remote object, <code>obj</code>.
93+ * @exception NoSuchObjectException if the stub for the
94+ * remote object could not be found.
95+ * @since 1.2
96+ */
97+ public static Remote toStub(Remote obj) throws NoSuchObjectException {
98+ if (obj instanceof RemoteStub ||
99+ (obj != null &&
100+ Proxy.isProxyClass(obj.getClass()) &&
101+ Proxy.getInvocationHandler(obj) instanceof
102+ RemoteObjectInvocationHandler))
103+ {
104+ return obj;
105+ } else {
106+ return sun.rmi.transport.ObjectTable.getStub(obj);
107+ }
108+ }
109+
110+ /**
111+ * Returns a hashcode for a remote object. Two remote object stubs
112+ * that refer to the same remote object will have the same hash code
113+ * (in order to support remote objects as keys in hash tables).
114+ *
115+ * @see java.util.Hashtable
116+ */
117+ public int hashCode() {
118+ return (ref == null) ? super.hashCode() : ref.remoteHashCode();
119+ }
120+
121+ /**
122+ * Compares two remote objects for equality.
123+ * Returns a boolean that indicates whether this remote object is
124+ * equivalent to the specified Object. This method is used when a
125+ * remote object is stored in a hashtable.
126+ * If the specified Object is not itself an instance of RemoteObject,
127+ * then this method delegates by returning the result of invoking the
128+ * <code>equals</code> method of its parameter with this remote object
129+ * as the argument.
130+ * @param obj the Object to compare with
131+ * @return true if these Objects are equal; false otherwise.
132+ * @see java.util.Hashtable
133+ */
134+ public boolean equals(Object obj) {
135+ if (obj instanceof RemoteObject) {
136+ if (ref == null) {
137+ return obj == this;
138+ } else {
139+ return ref.remoteEquals(((RemoteObject)obj).ref);
140+ }
141+ } else if (obj != null) {
142+ /*
143+ * Fix for 4099660: if object is not an instance of RemoteObject,
144+ * use the result of its equals method, to support symmetry is a
145+ * remote object implementation class that does not extend
146+ * RemoteObject wishes to support equality with its stub objects.
147+ */
148+ return obj.equals(this);
149+ } else {
150+ return false;
151+ }
152+ }
153+
154+ /**
155+ * Returns a String that represents the value of this remote object.
156+ */
157+ public String toString() {
158+ String classname = Util.getUnqualifiedName(getClass());
159+ return (ref == null) ? classname :
160+ classname + "[" + ref.remoteToString() + "]";
161+ }
162+
163+ /**
164+ * <code>writeObject</code> for custom serialization.
165+ *
166+ * <p>This method writes this object's serialized form for this class
167+ * as follows:
168+ *
169+ * <p>The {@link RemoteRef#getRefClass(java.io.ObjectOutput) getRefClass}
170+ * method is invoked on this object's <code>ref</code> field
171+ * to obtain its external ref type name.
172+ * If the value returned by <code>getRefClass</code> was
173+ * a non-<code>null</code> string of length greater than zero,
174+ * the <code>writeUTF</code> method is invoked on <code>out</code>
175+ * with the value returned by <code>getRefClass</code>, and then
176+ * the <code>writeExternal</code> method is invoked on
177+ * this object's <code>ref</code> field passing <code>out</code>
178+ * as the argument; otherwise,
179+ * the <code>writeUTF</code> method is invoked on <code>out</code>
180+ * with a zero-length string (<code>""</code>), and then
181+ * the <code>writeObject</code> method is invoked on <code>out</code>
182+ * passing this object's <code>ref</code> field as the argument.
183+ *
184+ * @serialData
185+ *
186+ * The serialized data for this class comprises a string (written with
187+ * <code>ObjectOutput.writeUTF</code>) that is either the external
188+ * ref type name of the contained <code>RemoteRef</code> instance
189+ * (the <code>ref</code> field) or a zero-length string, followed by
190+ * either the external form of the <code>ref</code> field as written by
191+ * its <code>writeExternal</code> method if the string was of non-zero
192+ * length, or the serialized form of the <code>ref</code> field as
193+ * written by passing it to the serialization stream's
194+ * <code>writeObject</code> if the string was of zero length.
195+ *
196+ * <p>If this object is an instance of
197+ * {@link RemoteStub} or {@link RemoteObjectInvocationHandler}
198+ * that was returned from any of
199+ * the <code>UnicastRemoteObject.exportObject</code> methods
200+ * and custom socket factories are not used,
201+ * the external ref type name is <code>"UnicastRef"</code>.
202+ *
203+ * If this object is an instance of
204+ * <code>RemoteStub</code> or <code>RemoteObjectInvocationHandler</code>
205+ * that was returned from any of
206+ * the <code>UnicastRemoteObject.exportObject</code> methods
207+ * and custom socket factories are used,
208+ * the external ref type name is <code>"UnicastRef2"</code>.
209+ *
210+ * If this object is an instance of
211+ * <code>RemoteStub</code> or <code>RemoteObjectInvocationHandler</code>
212+ * that was returned from any of
213+ * the <code>java.rmi.activation.Activatable.exportObject</code> methods,
214+ * the external ref type name is <code>"ActivatableRef"</code>.
215+ *
216+ * If this object is an instance of
217+ * <code>RemoteStub</code> or <code>RemoteObjectInvocationHandler</code>
218+ * that was returned from
219+ * the <code>RemoteObject.toStub</code> method (and the argument passed
220+ * to <code>toStub</code> was not itself a <code>RemoteStub</code>),
221+ * the external ref type name is a function of how the remote object
222+ * passed to <code>toStub</code> was exported, as described above.
223+ *
224+ * If this object is an instance of
225+ * <code>RemoteStub</code> or <code>RemoteObjectInvocationHandler</code>
226+ * that was originally created via deserialization,
227+ * the external ref type name is the same as that which was read
228+ * when this object was deserialized.
229+ *
230+ * <p>If this object is an instance of
231+ * <code>java.rmi.server.UnicastRemoteObject</code> that does not
232+ * use custom socket factories,
233+ * the external ref type name is <code>"UnicastServerRef"</code>.
234+ *
235+ * If this object is an instance of
236+ * <code>UnicastRemoteObject</code> that does
237+ * use custom socket factories,
238+ * the external ref type name is <code>"UnicastServerRef2"</code>.
239+ *
240+ * <p>Following is the data that must be written by the
241+ * <code>writeExternal</code> method and read by the
242+ * <code>readExternal</code> method of <code>RemoteRef</code>
243+ * implementation classes that correspond to the each of the
244+ * defined external ref type names:
245+ *
246+ * <p>For <code>"UnicastRef"</code>:
247+ *
248+ * <ul>
249+ *
250+ * <li>the hostname of the referenced remote object,
251+ * written by {@link java.io.ObjectOutput#writeUTF(String)}
252+ *
253+ * <li>the port of the referenced remote object,
254+ * written by {@link java.io.ObjectOutput#writeInt(int)}
255+ *
256+ * <li>the data written as a result of calling
257+ * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)}
258+ * on the <code>ObjID</code> instance contained in the reference
259+ *
260+ * <li>the boolean value <code>false</code>,
261+ * written by {@link java.io.ObjectOutput#writeBoolean(boolean)}
262+ *
263+ * </ul>
264+ *
265+ * <p>For <code>"UnicastRef2"</code> with a
266+ * <code>null</code> client socket factory:
267+ *
268+ * <ul>
269+ *
270+ * <li>the byte value <code>0x00</code>
271+ * (indicating <code>null</code> client socket factory),
272+ * written by {@link java.io.ObjectOutput#writeByte(int)}
273+ *
274+ * <li>the hostname of the referenced remote object,
275+ * written by {@link java.io.ObjectOutput#writeUTF(String)}
276+ *
277+ * <li>the port of the referenced remote object,
278+ * written by {@link java.io.ObjectOutput#writeInt(int)}
279+ *
280+ * <li>the data written as a result of calling
281+ * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)}
282+ * on the <code>ObjID</code> instance contained in the reference
283+ *
284+ * <li>the boolean value <code>false</code>,
285+ * written by {@link java.io.ObjectOutput#writeBoolean(boolean)}
286+ *
287+ * </ul>
288+ *
289+ * <p>For <code>"UnicastRef2"</code> with a
290+ * non-<code>null</code> client socket factory:
291+ *
292+ * <ul>
293+ *
294+ * <li>the byte value <code>0x01</code>
295+ * (indicating non-<code>null</code> client socket factory),
296+ * written by {@link java.io.ObjectOutput#writeByte(int)}
297+ *
298+ * <li>the hostname of the referenced remote object,
299+ * written by {@link java.io.ObjectOutput#writeUTF(String)}
300+ *
301+ * <li>the port of the referenced remote object,
302+ * written by {@link java.io.ObjectOutput#writeInt(int)}
303+ *
304+ * <li>a client socket factory (object of type
305+ * <code>java.rmi.server.RMIClientSocketFactory</code>),
306+ * written by passing it to an invocation of
307+ * <code>writeObject</code> on the stream instance
308+ *
309+ * <li>the data written as a result of calling
310+ * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)}
311+ * on the <code>ObjID</code> instance contained in the reference
312+ *
313+ * <li>the boolean value <code>false</code>,
314+ * written by {@link java.io.ObjectOutput#writeBoolean(boolean)}
315+ *
316+ * </ul>
317+ *
318+ * <p>For <code>"ActivatableRef"</code> with a
319+ * <code>null</code> nested remote reference:
320+ *
321+ * <ul>
322+ *
323+ * <li>an instance of
324+ * <code>java.rmi.activation.ActivationID</code>,
325+ * written by passing it to an invocation of
326+ * <code>writeObject</code> on the stream instance
327+ *
328+ * <li>a zero-length string (<code>""</code>),
329+ * written by {@link java.io.ObjectOutput#writeUTF(String)}
330+ *
331+ * </ul>
332+ *
333+ * <p>For <code>"ActivatableRef"</code> with a
334+ * non-<code>null</code> nested remote reference:
335+ *
336+ * <ul>
337+ *
338+ * <li>an instance of
339+ * <code>java.rmi.activation.ActivationID</code>,
340+ * written by passing it to an invocation of
341+ * <code>writeObject</code> on the stream instance
342+ *
343+ * <li>the external ref type name of the nested remote reference,
344+ * which must be <code>"UnicastRef2"</code>,
345+ * written by {@link java.io.ObjectOutput#writeUTF(String)}
346+ *
347+ * <li>the external form of the nested remote reference,
348+ * written by invoking its <code>writeExternal</code> method
349+ * with the stream instance
350+ * (see the description of the external form for
351+ * <code>"UnicastRef2"</code> above)
352+ *
353+ * </ul>
354+ *
355+ * <p>For <code>"UnicastServerRef"</code> and
356+ * <code>"UnicastServerRef2"</code>, no data is written by the
357+ * <code>writeExternal</code> method or read by the
358+ * <code>readExternal</code> method.
359+ */
360+ private void writeObject(java.io.ObjectOutputStream out)
361+ throws java.io.IOException, java.lang.ClassNotFoundException
362+ {
363+ if (ref == null) {
364+ throw new java.rmi.MarshalException("Invalid remote object");
365+ } else {
366+ String refClassName = ref.getRefClass(out);
367+ if (refClassName == null || refClassName.length() == 0) {
368+ /*
369+ * No reference class name specified, so serialize
370+ * remote reference.
371+ */
372+ out.writeUTF("");
373+ out.writeObject(ref);
374+ } else {
375+ /*
376+ * Built-in reference class specified, so delegate
377+ * to reference to write out its external form.
378+ */
379+ out.writeUTF(refClassName);
380+ ref.writeExternal(out);
381+ }
382+ }
383+ }
384+
385+ /**
386+ * <code>readObject</code> for custom serialization.
387+ *
388+ * <p>This method reads this object's serialized form for this class
389+ * as follows:
390+ *
391+ * <p>The <code>readUTF</code> method is invoked on <code>in</code>
392+ * to read the external ref type name for the <code>RemoteRef</code>
393+ * instance to be filled in to this object's <code>ref</code> field.
394+ * If the string returned by <code>readUTF</code> has length zero,
395+ * the <code>readObject</code> method is invoked on <code>in</code>,
396+ * and than the value returned by <code>readObject</code> is cast to
397+ * <code>RemoteRef</code> and this object's <code>ref</code> field is
398+ * set to that value.
399+ * Otherwise, this object's <code>ref</code> field is set to a
400+ * <code>RemoteRef</code> instance that is created of an
401+ * implementation-specific class corresponding to the external ref
402+ * type name returned by <code>readUTF</code>, and then
403+ * the <code>readExternal</code> method is invoked on
404+ * this object's <code>ref</code> field.
405+ *
406+ * <p>If the external ref type name is
407+ * <code>"UnicastRef"</code>, <code>"UnicastServerRef"</code>,
408+ * <code>"UnicastRef2"</code>, <code>"UnicastServerRef2"</code>,
409+ * or <code>"ActivatableRef"</code>, a corresponding
410+ * implementation-specific class must be found, and its
411+ * <code>readExternal</code> method must read the serial data
412+ * for that external ref type name as specified to be written
413+ * in the <b>serialData</b> documentation for this class.
414+ * If the external ref type name is any other string (of non-zero
415+ * length), a <code>ClassNotFoundException</code> will be thrown,
416+ * unless the implementation provides an implementation-specific
417+ * class corresponding to that external ref type name, in which
418+ * case this object's <code>ref</code> field will be set to an
419+ * instance of that implementation-specific class.
420+ */
421+ private void readObject(java.io.ObjectInputStream in)
422+ throws java.io.IOException, java.lang.ClassNotFoundException
423+ {
424+ String refClassName = in.readUTF();
425+ if (refClassName == null || refClassName.length() == 0) {
426+ /*
427+ * No reference class name specified, so construct
428+ * remote reference from its serialized form.
429+ */
430+ ref = (RemoteRef) in.readObject();
431+ } else {
432+ /*
433+ * Built-in reference class specified, so delegate to
434+ * internal reference class to initialize its fields from
435+ * its external form.
436+ */
437+ String internalRefClassName =
438+ RemoteRef.packagePrefix + "." + refClassName;
439+ Class refClass = Class.forName(internalRefClassName);
440+ try {
441+ ref = (RemoteRef) refClass.newInstance();
442+
443+ /*
444+ * If this step fails, assume we found an internal
445+ * class that is not meant to be a serializable ref
446+ * type.
447+ */
448+ } catch (InstantiationException e) {
449+ throw new ClassNotFoundException(internalRefClassName, e);
450+ } catch (IllegalAccessException e) {
451+ throw new ClassNotFoundException(internalRefClassName, e);
452+ } catch (ClassCastException e) {
453+ throw new ClassNotFoundException(internalRefClassName, e);
454+ }
455+ ref.readExternal(in);
456+ }
457+ }
458+}