Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/rmi/activation/ActivationID.java
38918 views
1
/*
2
* Copyright (c) 1997, 2017, 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.activation;
27
28
import java.io.IOException;
29
import java.io.InvalidObjectException;
30
import java.io.ObjectInputStream;
31
import java.io.ObjectOutputStream;
32
import java.io.Serializable;
33
import java.lang.reflect.InvocationHandler;
34
import java.lang.reflect.Proxy;
35
import java.rmi.MarshalledObject;
36
import java.rmi.Remote;
37
import java.rmi.RemoteException;
38
import java.rmi.UnmarshalException;
39
import java.rmi.server.RemoteObject;
40
import java.rmi.server.RemoteObjectInvocationHandler;
41
import java.rmi.server.RemoteRef;
42
import java.rmi.server.UID;
43
import java.security.AccessControlContext;
44
import java.security.AccessController;
45
import java.security.Permissions;
46
import java.security.PrivilegedActionException;
47
import java.security.PrivilegedExceptionAction;
48
import java.security.ProtectionDomain;
49
50
/**
51
* Activation makes use of special identifiers to denote remote
52
* objects that can be activated over time. An activation identifier
53
* (an instance of the class <code>ActivationID</code>) contains several
54
* pieces of information needed for activating an object:
55
* <ul>
56
* <li> a remote reference to the object's activator (a {@link
57
* java.rmi.server.RemoteRef RemoteRef}
58
* instance), and
59
* <li> a unique identifier (a {@link java.rmi.server.UID UID}
60
* instance) for the object. </ul> <p>
61
*
62
* An activation identifier for an object can be obtained by registering
63
* an object with the activation system. Registration is accomplished
64
* in a few ways: <ul>
65
* <li>via the <code>Activatable.register</code> method
66
* <li>via the first <code>Activatable</code> constructor (that takes
67
* three arguments and both registers and exports the object, and
68
* <li>via the first <code>Activatable.exportObject</code> method
69
* that takes the activation descriptor, object and port as arguments;
70
* this method both registers and exports the object. </ul>
71
*
72
* @author Ann Wollrath
73
* @see Activatable
74
* @since 1.2
75
*/
76
public class ActivationID implements Serializable {
77
/**
78
* the object's activator
79
*/
80
private transient Activator activator;
81
82
/**
83
* the object's unique id
84
*/
85
private transient UID uid = new UID();
86
87
/** indicate compatibility with the Java 2 SDK v1.2 version of class */
88
private static final long serialVersionUID = -4608673054848209235L;
89
90
/** an AccessControlContext with no permissions */
91
private static final AccessControlContext NOPERMS_ACC;
92
static {
93
Permissions perms = new Permissions();
94
ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
95
NOPERMS_ACC = new AccessControlContext(pd);
96
}
97
98
/**
99
* The constructor for <code>ActivationID</code> takes a single
100
* argument, activator, that specifies a remote reference to the
101
* activator responsible for activating the object associated with
102
* this identifier. An instance of <code>ActivationID</code> is globally
103
* unique.
104
*
105
* @param activator reference to the activator responsible for
106
* activating the object
107
* @throws UnsupportedOperationException if and only if activation is
108
* not supported by this implementation
109
* @since 1.2
110
*/
111
public ActivationID(Activator activator) {
112
this.activator = activator;
113
}
114
115
/**
116
* Activate the object for this id.
117
*
118
* @param force if true, forces the activator to contact the group
119
* when activating the object (instead of returning a cached reference);
120
* if false, returning a cached value is acceptable.
121
* @return the reference to the active remote object
122
* @exception ActivationException if activation fails
123
* @exception UnknownObjectException if the object is unknown
124
* @exception RemoteException if remote call fails
125
* @since 1.2
126
*/
127
public Remote activate(boolean force)
128
throws ActivationException, UnknownObjectException, RemoteException
129
{
130
try {
131
MarshalledObject<? extends Remote> mobj =
132
activator.activate(this, force);
133
return AccessController.doPrivileged(
134
new PrivilegedExceptionAction<Remote>() {
135
public Remote run() throws IOException, ClassNotFoundException {
136
return mobj.get();
137
}
138
}, NOPERMS_ACC);
139
} catch (PrivilegedActionException pae) {
140
Exception ex = pae.getException();
141
if (ex instanceof RemoteException) {
142
throw (RemoteException) ex;
143
} else {
144
throw new UnmarshalException("activation failed", ex);
145
}
146
}
147
148
}
149
150
/**
151
* Returns a hashcode for the activation id. Two identifiers that
152
* refer to the same remote object will have the same hash code.
153
*
154
* @see java.util.Hashtable
155
* @since 1.2
156
*/
157
public int hashCode() {
158
return uid.hashCode();
159
}
160
161
/**
162
* Compares two activation ids for content equality.
163
* Returns true if both of the following conditions are true:
164
* 1) the unique identifiers equivalent (by content), and
165
* 2) the activator specified in each identifier
166
* refers to the same remote object.
167
*
168
* @param obj the Object to compare with
169
* @return true if these Objects are equal; false otherwise.
170
* @see java.util.Hashtable
171
* @since 1.2
172
*/
173
public boolean equals(Object obj) {
174
if (obj instanceof ActivationID) {
175
ActivationID id = (ActivationID) obj;
176
return (uid.equals(id.uid) && activator.equals(id.activator));
177
} else {
178
return false;
179
}
180
}
181
182
/**
183
* <code>writeObject</code> for custom serialization.
184
*
185
* <p>This method writes this object's serialized form for
186
* this class as follows:
187
*
188
* <p>The <code>writeObject</code> method is invoked on
189
* <code>out</code> passing this object's unique identifier
190
* (a {@link java.rmi.server.UID UID} instance) as the argument.
191
*
192
* <p>Next, the {@link
193
* java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
194
* getRefClass} method is invoked on the activator's
195
* <code>RemoteRef</code> instance to obtain its external ref
196
* type name. Next, the <code>writeUTF</code> method is
197
* invoked on <code>out</code> with the value returned by
198
* <code>getRefClass</code>, and then the
199
* <code>writeExternal</code> method is invoked on the
200
* <code>RemoteRef</code> instance passing <code>out</code>
201
* as the argument.
202
*
203
* @serialData The serialized data for this class comprises a
204
* <code>java.rmi.server.UID</code> (written with
205
* <code>ObjectOutput.writeObject</code>) followed by the
206
* external ref type name of the activator's
207
* <code>RemoteRef</code> instance (a string written with
208
* <code>ObjectOutput.writeUTF</code>), followed by the
209
* external form of the <code>RemoteRef</code> instance as
210
* written by its <code>writeExternal</code> method.
211
*
212
* <p>The external ref type name of the
213
* <code>RemoteRef</Code> instance is
214
* determined using the definitions of external ref type
215
* names specified in the {@link java.rmi.server.RemoteObject
216
* RemoteObject} <code>writeObject</code> method
217
* <b>serialData</b> specification. Similarly, the data
218
* written by the <code>writeExternal</code> method and read
219
* by the <code>readExternal</code> method of
220
* <code>RemoteRef</code> implementation classes
221
* corresponding to each of the defined external ref type
222
* names is specified in the {@link
223
* java.rmi.server.RemoteObject RemoteObject}
224
* <code>writeObject</code> method <b>serialData</b>
225
* specification.
226
**/
227
private void writeObject(ObjectOutputStream out)
228
throws IOException, ClassNotFoundException
229
{
230
out.writeObject(uid);
231
232
RemoteRef ref;
233
if (activator instanceof RemoteObject) {
234
ref = ((RemoteObject) activator).getRef();
235
} else if (Proxy.isProxyClass(activator.getClass())) {
236
InvocationHandler handler = Proxy.getInvocationHandler(activator);
237
if (!(handler instanceof RemoteObjectInvocationHandler)) {
238
throw new InvalidObjectException(
239
"unexpected invocation handler");
240
}
241
ref = ((RemoteObjectInvocationHandler) handler).getRef();
242
243
} else {
244
throw new InvalidObjectException("unexpected activator type");
245
}
246
out.writeUTF(ref.getRefClass(out));
247
ref.writeExternal(out);
248
}
249
250
/**
251
* <code>readObject</code> for custom serialization.
252
*
253
* <p>This method reads this object's serialized form for this
254
* class as follows:
255
*
256
* <p>The <code>readObject</code> method is invoked on
257
* <code>in</code> to read this object's unique identifier
258
* (a {@link java.rmi.server.UID UID} instance).
259
*
260
* <p>Next, the <code>readUTF</code> method is invoked on
261
* <code>in</code> to read the external ref type name of the
262
* <code>RemoteRef</code> instance for this object's
263
* activator. Next, the <code>RemoteRef</code>
264
* instance is created of an implementation-specific class
265
* corresponding to the external ref type name (returned by
266
* <code>readUTF</code>), and the <code>readExternal</code>
267
* method is invoked on that <code>RemoteRef</code> instance
268
* to read the external form corresponding to the external
269
* ref type name.
270
*
271
* <p>Note: If the external ref type name is
272
* <code>"UnicastRef"</code>, <code>"UnicastServerRef"</code>,
273
* <code>"UnicastRef2"</code>, <code>"UnicastServerRef2"</code>,
274
* or <code>"ActivatableRef"</code>, a corresponding
275
* implementation-specific class must be found, and its
276
* <code>readExternal</code> method must read the serial data
277
* for that external ref type name as specified to be written
278
* in the <b>serialData</b> documentation for this class.
279
* If the external ref type name is any other string (of non-zero
280
* length), a <code>ClassNotFoundException</code> will be thrown,
281
* unless the implementation provides an implementation-specific
282
* class corresponding to that external ref type name, in which
283
* case the <code>RemoteRef</code> will be an instance of
284
* that implementation-specific class.
285
*/
286
private void readObject(ObjectInputStream in)
287
throws IOException, ClassNotFoundException
288
{
289
uid = (UID)in.readObject();
290
291
try {
292
Class<? extends RemoteRef> refClass =
293
Class.forName(RemoteRef.packagePrefix + "." + in.readUTF())
294
.asSubclass(RemoteRef.class);
295
RemoteRef ref = refClass.newInstance();
296
ref.readExternal(in);
297
activator = (Activator)
298
Proxy.newProxyInstance(null,
299
new Class<?>[] { Activator.class },
300
new RemoteObjectInvocationHandler(ref));
301
302
} catch (InstantiationException e) {
303
throw (IOException)
304
new InvalidObjectException(
305
"Unable to create remote reference").initCause(e);
306
} catch (IllegalAccessException e) {
307
throw (IOException)
308
new InvalidObjectException(
309
"Unable to create remote reference").initCause(e);
310
}
311
}
312
}
313
314