Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java
41154 views
1
/*
2
* Copyright (c) 1996, 2021, 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.ObjectInputFilter;
33
import java.io.ObjectOutput;
34
import java.io.StreamCorruptedException;
35
import java.rmi.RemoteException;
36
import java.rmi.MarshalException;
37
import java.rmi.UnmarshalException;
38
import java.rmi.server.ObjID;
39
import java.rmi.server.RemoteCall;
40
import java.security.AccessController;
41
import java.security.PrivilegedAction;
42
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
@SuppressWarnings("removal")
143
public ObjectInput getInputStream() throws IOException {
144
if (in == null) {
145
Transport.transportLog.log(Log.VERBOSE, "getting input stream");
146
147
in = new ConnectionInputStream(conn.getInputStream());
148
if (filter != null) {
149
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
150
in.setObjectInputFilter(filter);
151
return null;
152
});
153
}
154
}
155
return in;
156
}
157
158
/**
159
* Release the input stream, this would allow some transports to release
160
* the channel early.
161
*/
162
public void releaseInputStream() throws IOException {
163
/* WARNING: Currently, the UnicastRef.java invoke methods rely
164
* upon this method not throwing an IOException.
165
*/
166
167
try {
168
if (in != null) {
169
// execute MarshalInputStream "done" callbacks
170
try {
171
in.done();
172
} catch (RuntimeException e) {
173
}
174
175
// add saved references to DGC table
176
in.registerRefs();
177
178
/* WARNING: The connection being passed to done may have
179
* already been freed.
180
*/
181
in.done(conn);
182
}
183
conn.releaseInputStream();
184
} finally {
185
in = null;
186
}
187
}
188
189
/**
190
* Discard any post-processing of refs the InputStream.
191
*/
192
public void discardPendingRefs() {
193
in.discardRefs();
194
}
195
196
/**
197
* Returns an output stream (may put out header information
198
* relating to the success of the call).
199
* @param success If true, indicates normal return, else indicates
200
* exceptional return.
201
* @exception StreamCorruptedException If result stream previously
202
* acquired
203
* @exception IOException For any other problem with I/O.
204
*/
205
public ObjectOutput getResultStream(boolean success) throws IOException {
206
/* make sure result code only marshaled once. */
207
if (resultStarted)
208
throw new StreamCorruptedException("result already in progress");
209
else
210
resultStarted = true;
211
212
// write out return header
213
// return header, part 1 (read by Transport)
214
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
215
wr.writeByte(TransportConstants.Return);// transport op
216
getOutputStream(true); // creates a MarshalOutputStream
217
// return header, part 2 (read by client-side RemoteCall)
218
if (success) //
219
out.writeByte(TransportConstants.NormalReturn);
220
else
221
out.writeByte(TransportConstants.ExceptionalReturn);
222
out.writeID(); // write id for gcAck
223
return out;
224
}
225
226
/**
227
* Do whatever it takes to execute the call.
228
*/
229
@SuppressWarnings("fallthrough")
230
public void executeCall() throws Exception {
231
byte returnType;
232
233
// read result header
234
DGCAckHandler ackHandler = null;
235
try {
236
if (out != null) {
237
ackHandler = out.getDGCAckHandler();
238
}
239
releaseOutputStream();
240
DataInputStream rd = new DataInputStream(conn.getInputStream());
241
byte op = rd.readByte();
242
if (op != TransportConstants.Return) {
243
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
244
Transport.transportLog.log(Log.BRIEF,
245
"transport return code invalid: " + op);
246
}
247
throw new UnmarshalException("Transport return code invalid");
248
}
249
getInputStream();
250
returnType = in.readByte();
251
in.readID(); // id for DGC acknowledgement
252
} catch (UnmarshalException e) {
253
throw e;
254
} catch (IOException e) {
255
throw new UnmarshalException("Error unmarshaling return header",
256
e);
257
} finally {
258
if (ackHandler != null) {
259
ackHandler.release();
260
}
261
}
262
263
// read return value
264
switch (returnType) {
265
case TransportConstants.NormalReturn:
266
break;
267
268
case TransportConstants.ExceptionalReturn:
269
Object ex;
270
try {
271
ex = in.readObject();
272
} catch (Exception e) {
273
discardPendingRefs();
274
throw new UnmarshalException("Error unmarshaling return", e);
275
}
276
277
// An exception should have been received,
278
// if so throw it, else flag error
279
if (ex instanceof Exception) {
280
exceptionReceivedFromServer((Exception) ex);
281
} else {
282
discardPendingRefs();
283
throw new UnmarshalException("Return type not Exception");
284
}
285
// Exception is thrown before fallthrough can occur
286
default:
287
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
288
Transport.transportLog.log(Log.BRIEF,
289
"return code invalid: " + returnType);
290
}
291
throw new UnmarshalException("Return code invalid");
292
}
293
}
294
295
/**
296
* Routine that causes the stack traces of remote exceptions to be
297
* filled in with the current stack trace on the client. Detail
298
* exceptions are filled in iteratively.
299
*/
300
protected void exceptionReceivedFromServer(Exception ex) throws Exception {
301
serverException = ex;
302
303
StackTraceElement[] serverTrace = ex.getStackTrace();
304
StackTraceElement[] clientTrace = (new Throwable()).getStackTrace();
305
StackTraceElement[] combinedTrace =
306
new StackTraceElement[serverTrace.length + clientTrace.length];
307
System.arraycopy(serverTrace, 0, combinedTrace, 0,
308
serverTrace.length);
309
System.arraycopy(clientTrace, 0, combinedTrace, serverTrace.length,
310
clientTrace.length);
311
ex.setStackTrace(combinedTrace);
312
313
/*
314
* Log the details of a server exception thrown as a result of a
315
* remote method invocation.
316
*/
317
if (UnicastRef.clientCallLog.isLoggable(Log.BRIEF)) {
318
/* log call exception returned from server before it is rethrown */
319
TCPEndpoint ep = (TCPEndpoint) conn.getChannel().getEndpoint();
320
UnicastRef.clientCallLog.log(Log.BRIEF, "outbound call " +
321
"received exception: [" + ep.getHost() + ":" +
322
ep.getPort() + "] exception: ", ex);
323
}
324
325
throw ex;
326
}
327
328
/*
329
* method to retrieve possible server side exceptions (which will
330
* be throw from exceptionReceivedFromServer(...) )
331
*/
332
public Exception getServerException() {
333
return serverException;
334
}
335
336
public void done() throws IOException {
337
/* WARNING: Currently, the UnicastRef.java invoke methods rely
338
* upon this method not throwing an IOException.
339
*/
340
341
releaseInputStream();
342
}
343
}
344
345