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/sun/rmi/transport/StreamRemoteCall.java (1 of 18352 files). Show all

Unified · Split

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