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/sun/rmi/transport/StreamRemoteCall.java
38831 views
1
/*
2
* Copyright (c) 1996, 2019, 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 sun.rmi.transport;
27
28
import java.io.DataInputStream;
29
import java.io.DataOutputStream;
30
import java.io.IOException;
31
import java.io.ObjectInput;
32
import java.io.ObjectOutput;
33
import java.io.StreamCorruptedException;
34
import java.rmi.RemoteException;
35
import java.rmi.MarshalException;
36
import java.rmi.UnmarshalException;
37
import java.rmi.server.ObjID;
38
import java.rmi.server.RemoteCall;
39
import java.security.AccessController;
40
import java.security.PrivilegedAction;
41
42
import sun.misc.ObjectInputFilter;
43
import sun.rmi.runtime.Log;
44
import sun.rmi.server.UnicastRef;
45
import sun.rmi.transport.tcp.TCPEndpoint;
46
47
/**
48
* Stream-based implementation of the RemoteCall interface.
49
*
50
* @author Ann Wollrath
51
*/
52
@SuppressWarnings("deprecation")
53
public class StreamRemoteCall implements RemoteCall {
54
private ConnectionInputStream in = null;
55
private ConnectionOutputStream out = null;
56
private Connection conn;
57
private ObjectInputFilter filter = null;
58
private boolean resultStarted = false;
59
private Exception serverException = null;
60
61
public StreamRemoteCall(Connection c) {
62
conn = c;
63
}
64
65
public StreamRemoteCall(Connection c, ObjID id, int op, long hash)
66
throws RemoteException
67
{
68
try {
69
conn = c;
70
Transport.transportLog.log(Log.VERBOSE,
71
"write remote call header...");
72
73
// write out remote call header info...
74
// call header, part 1 (read by Transport)
75
conn.getOutputStream().write(TransportConstants.Call);
76
getOutputStream(); // creates a MarshalOutputStream
77
id.write(out); // object id (target of call)
78
// call header, part 2 (read by Dispatcher)
79
out.writeInt(op); // method number (operation index)
80
out.writeLong(hash); // stub/skeleton hash
81
} catch (IOException e) {
82
throw new MarshalException("Error marshaling call header", e);
83
}
84
}
85
86
/**
87
* Return the connection associated with this call.
88
*/
89
public Connection getConnection() {
90
return conn;
91
}
92
93
/**
94
* Return the output stream the stub/skeleton should put arguments/results
95
* into.
96
*/
97
public ObjectOutput getOutputStream() throws IOException {
98
return getOutputStream(false);
99
}
100
101
private ObjectOutput getOutputStream(boolean resultStream)
102
throws IOException
103
{
104
if (out == null) {
105
Transport.transportLog.log(Log.VERBOSE, "getting output stream");
106
107
out = new ConnectionOutputStream(conn, resultStream);
108
}
109
return out;
110
}
111
112
/**
113
* Release the outputStream Currently, will not complain if the
114
* output stream is released more than once.
115
*/
116
public void releaseOutputStream() throws IOException {
117
try {
118
if (out != null) {
119
try {
120
out.flush();
121
} finally {
122
out.done(); // always start DGC ack timer
123
}
124
}
125
conn.releaseOutputStream();
126
} finally {
127
out = null;
128
}
129
}
130
131
public void setObjectInputFilter(ObjectInputFilter filter) {
132
if (in != null) {
133
throw new IllegalStateException("set filter must occur before calling getInputStream");
134
}
135
this.filter = filter;
136
}
137
138
/**
139
* Get the InputStream the stub/skeleton should get results/arguments
140
* from.
141
*/
142
public ObjectInput getInputStream() throws IOException {
143
if (in == null) {
144
Transport.transportLog.log(Log.VERBOSE, "getting input stream");
145
146
in = new ConnectionInputStream(conn.getInputStream());
147
if (filter != null) {
148
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
149
ObjectInputFilter.Config.setObjectInputFilter(in, filter);
150
return null;
151
});
152
}
153
}
154
return in;
155
}
156
157
/**
158
* Release the input stream, this would allow some transports to release
159
* the channel early.
160
*/
161
public void releaseInputStream() throws IOException {
162
/* WARNING: Currently, the UnicastRef.java invoke methods rely
163
* upon this method not throwing an IOException.
164
*/
165
166
try {
167
if (in != null) {
168
// execute MarshalInputStream "done" callbacks
169
try {
170
in.done();
171
} catch (RuntimeException e) {
172
}
173
174
// add saved references to DGC table
175
in.registerRefs();
176
177
/* WARNING: The connection being passed to done may have
178
* already been freed.
179
*/
180
in.done(conn);
181
}
182
conn.releaseInputStream();
183
} finally {
184
in = null;
185
}
186
}
187
188
/**
189
* Discard any post-processing of refs the InputStream.
190
*/
191
public void discardPendingRefs() {
192
in.discardRefs();
193
}
194
195
/**
196
* Returns an output stream (may put out header information
197
* relating to the success of the call).
198
* @param success If true, indicates normal return, else indicates
199
* exceptional return.
200
* @exception StreamCorruptedException If result stream previously
201
* acquired
202
* @exception IOException For any other problem with I/O.
203
*/
204
public ObjectOutput getResultStream(boolean success) throws IOException {
205
/* make sure result code only marshaled once. */
206
if (resultStarted)
207
throw new StreamCorruptedException("result already in progress");
208
else
209
resultStarted = true;
210
211
// write out return header
212
// return header, part 1 (read by Transport)
213
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
214
wr.writeByte(TransportConstants.Return);// transport op
215
getOutputStream(true); // creates a MarshalOutputStream
216
// return header, part 2 (read by client-side RemoteCall)
217
if (success) //
218
out.writeByte(TransportConstants.NormalReturn);
219
else
220
out.writeByte(TransportConstants.ExceptionalReturn);
221
out.writeID(); // write id for gcAck
222
return out;
223
}
224
225
/**
226
* Do whatever it takes to execute the call.
227
*/
228
@SuppressWarnings("fallthrough")
229
public void executeCall() throws Exception {
230
byte returnType;
231
232
// read result header
233
DGCAckHandler ackHandler = null;
234
try {
235
if (out != null) {
236
ackHandler = out.getDGCAckHandler();
237
}
238
releaseOutputStream();
239
DataInputStream rd = new DataInputStream(conn.getInputStream());
240
byte op = rd.readByte();
241
if (op != TransportConstants.Return) {
242
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
243
Transport.transportLog.log(Log.BRIEF,
244
"transport return code invalid: " + op);
245
}
246
throw new UnmarshalException("Transport return code invalid");
247
}
248
getInputStream();
249
returnType = in.readByte();
250
in.readID(); // id for DGC acknowledgement
251
} catch (UnmarshalException e) {
252
throw e;
253
} catch (IOException e) {
254
throw new UnmarshalException("Error unmarshaling return header",
255
e);
256
} finally {
257
if (ackHandler != null) {
258
ackHandler.release();
259
}
260
}
261
262
// read return value
263
switch (returnType) {
264
case TransportConstants.NormalReturn:
265
break;
266
267
case TransportConstants.ExceptionalReturn:
268
Object ex;
269
try {
270
ex = in.readObject();
271
} catch (Exception e) {
272
discardPendingRefs();
273
throw new UnmarshalException("Error unmarshaling return", e);
274
}
275
276
// An exception should have been received,
277
// if so throw it, else flag error
278
if (ex instanceof Exception) {
279
exceptionReceivedFromServer((Exception) ex);
280
} else {
281
discardPendingRefs();
282
throw new UnmarshalException("Return type not Exception");
283
}
284
// Exception is thrown before fallthrough can occur
285
default:
286
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
287
Transport.transportLog.log(Log.BRIEF,
288
"return code invalid: " + returnType);
289
}
290
throw new UnmarshalException("Return code invalid");
291
}
292
}
293
294
/**
295
* Routine that causes the stack traces of remote exceptions to be
296
* filled in with the current stack trace on the client. Detail
297
* exceptions are filled in iteratively.
298
*/
299
protected void exceptionReceivedFromServer(Exception ex) throws Exception {
300
serverException = ex;
301
302
StackTraceElement[] serverTrace = ex.getStackTrace();
303
StackTraceElement[] clientTrace = (new Throwable()).getStackTrace();
304
StackTraceElement[] combinedTrace =
305
new StackTraceElement[serverTrace.length + clientTrace.length];
306
System.arraycopy(serverTrace, 0, combinedTrace, 0,
307
serverTrace.length);
308
System.arraycopy(clientTrace, 0, combinedTrace, serverTrace.length,
309
clientTrace.length);
310
ex.setStackTrace(combinedTrace);
311
312
/*
313
* Log the details of a server exception thrown as a result of a
314
* remote method invocation.
315
*/
316
if (UnicastRef.clientCallLog.isLoggable(Log.BRIEF)) {
317
/* log call exception returned from server before it is rethrown */
318
TCPEndpoint ep = (TCPEndpoint) conn.getChannel().getEndpoint();
319
UnicastRef.clientCallLog.log(Log.BRIEF, "outbound call " +
320
"received exception: [" + ep.getHost() + ":" +
321
ep.getPort() + "] exception: ", ex);
322
}
323
324
throw ex;
325
}
326
327
/*
328
* method to retrieve possible server side exceptions (which will
329
* be throw from exceptionReceivedFromServer(...) )
330
*/
331
public Exception getServerException() {
332
return serverException;
333
}
334
335
public void done() throws IOException {
336
/* WARNING: Currently, the UnicastRef.java invoke methods rely
337
* upon this method not throwing an IOException.
338
*/
339
340
releaseInputStream();
341
}
342
}
343
344