172 * Export that target via the Ref.
173 **/
174 public RemoteStub exportObject(Remote impl, Object data)
175 throws RemoteException
176 {
177 forceStubUse = true;
178 return (RemoteStub) exportObject(impl, data, false);
179 }
180
181 /**
182 * Export this object, create the skeleton and stubs for this
183 * dispatcher. Create a stub based on the type of the impl,
184 * initialize it with the appropriate remote reference. Create the
185 * target defined by the impl, dispatcher (this) and stub.
186 * Export that target via the Ref.
187 */
188 public Remote exportObject(Remote impl, Object data,
189 boolean permanent)
190 throws RemoteException
191 {
192 Class implClass = impl.getClass();
193 Remote stub;
194
195 try {
196 stub = Util.createProxy(implClass, getClientRef(), forceStubUse);
197 } catch (IllegalArgumentException e) {
198 throw new ExportException(
199 "remote object implements illegal remote interface", e);
200 }
201 if (stub instanceof RemoteStub) {
202 setSkeleton(impl);
203 }
204
205 Target target =
206 new Target(impl, this, stub, ref.getObjID(), permanent);
207 ref.exportObject(target);
208 hashToMethod_Map = hashToMethod_Maps.get(implClass);
209 return stub;
210 }
211
212 /**
310 throw new UnmarshalException(
311 "error unmarshalling arguments", e);
312 } catch (ClassNotFoundException e) {
313 throw new UnmarshalException(
314 "error unmarshalling arguments", e);
315 } finally {
316 call.releaseInputStream();
317 }
318
319 // make upcall on remote object
320 Object result;
321 try {
322 result = method.invoke(obj, params);
323 } catch (InvocationTargetException e) {
324 throw e.getTargetException();
325 }
326
327 // marshal return value
328 try {
329 ObjectOutput out = call.getResultStream(true);
330 Class rtype = method.getReturnType();
331 if (rtype != void.class) {
332 marshalValue(rtype, result, out);
333 }
334 } catch (IOException ex) {
335 throw new MarshalException("error marshalling return", ex);
336 /*
337 * This throw is problematic because when it is caught below,
338 * we attempt to marshal it back to the client, but at this
339 * point, a "normal return" has already been indicated,
340 * so marshalling an exception will corrupt the stream.
341 * This was the case with skeletons as well; there is no
342 * immediately obvious solution without a protocol change.
343 */
344 }
345 } catch (Throwable e) {
346 logCallException(e);
347
348 ObjectOutput out = call.getResultStream(false);
349 if (e instanceof Error) {
350 e = new ServerError(
520 */
521 public void readExternal(ObjectInput in)
522 throws IOException, ClassNotFoundException
523 {
524 // object is re-exported elsewhere (e.g., by UnicastRemoteObject)
525 ref = null;
526 skel = null;
527 }
528
529
530 /**
531 * A weak hash map, mapping classes to hash maps that map method
532 * hashes to method objects.
533 **/
534 private static class HashToMethod_Maps
535 extends WeakClassHashMap<Map<Long,Method>>
536 {
537 HashToMethod_Maps() {}
538
539 protected Map<Long,Method> computeValue(Class<?> remoteClass) {
540 Map<Long,Method> map = new HashMap<Long,Method>();
541 for (Class<?> cl = remoteClass;
542 cl != null;
543 cl = cl.getSuperclass())
544 {
545 for (Class<?> intf : cl.getInterfaces()) {
546 if (Remote.class.isAssignableFrom(intf)) {
547 for (Method method : intf.getMethods()) {
548 final Method m = method;
549 /*
550 * Set this Method object to override language
551 * access checks so that the dispatcher can invoke
552 * methods from non-public remote interfaces.
553 */
554 AccessController.doPrivileged(
555 new PrivilegedAction<Void>() {
556 public Void run() {
557 m.setAccessible(true);
558 return null;
559 }
560 });
|
172 * Export that target via the Ref.
173 **/
174 public RemoteStub exportObject(Remote impl, Object data)
175 throws RemoteException
176 {
177 forceStubUse = true;
178 return (RemoteStub) exportObject(impl, data, false);
179 }
180
181 /**
182 * Export this object, create the skeleton and stubs for this
183 * dispatcher. Create a stub based on the type of the impl,
184 * initialize it with the appropriate remote reference. Create the
185 * target defined by the impl, dispatcher (this) and stub.
186 * Export that target via the Ref.
187 */
188 public Remote exportObject(Remote impl, Object data,
189 boolean permanent)
190 throws RemoteException
191 {
192 Class<?> implClass = impl.getClass();
193 Remote stub;
194
195 try {
196 stub = Util.createProxy(implClass, getClientRef(), forceStubUse);
197 } catch (IllegalArgumentException e) {
198 throw new ExportException(
199 "remote object implements illegal remote interface", e);
200 }
201 if (stub instanceof RemoteStub) {
202 setSkeleton(impl);
203 }
204
205 Target target =
206 new Target(impl, this, stub, ref.getObjID(), permanent);
207 ref.exportObject(target);
208 hashToMethod_Map = hashToMethod_Maps.get(implClass);
209 return stub;
210 }
211
212 /**
310 throw new UnmarshalException(
311 "error unmarshalling arguments", e);
312 } catch (ClassNotFoundException e) {
313 throw new UnmarshalException(
314 "error unmarshalling arguments", e);
315 } finally {
316 call.releaseInputStream();
317 }
318
319 // make upcall on remote object
320 Object result;
321 try {
322 result = method.invoke(obj, params);
323 } catch (InvocationTargetException e) {
324 throw e.getTargetException();
325 }
326
327 // marshal return value
328 try {
329 ObjectOutput out = call.getResultStream(true);
330 Class<?> rtype = method.getReturnType();
331 if (rtype != void.class) {
332 marshalValue(rtype, result, out);
333 }
334 } catch (IOException ex) {
335 throw new MarshalException("error marshalling return", ex);
336 /*
337 * This throw is problematic because when it is caught below,
338 * we attempt to marshal it back to the client, but at this
339 * point, a "normal return" has already been indicated,
340 * so marshalling an exception will corrupt the stream.
341 * This was the case with skeletons as well; there is no
342 * immediately obvious solution without a protocol change.
343 */
344 }
345 } catch (Throwable e) {
346 logCallException(e);
347
348 ObjectOutput out = call.getResultStream(false);
349 if (e instanceof Error) {
350 e = new ServerError(
520 */
521 public void readExternal(ObjectInput in)
522 throws IOException, ClassNotFoundException
523 {
524 // object is re-exported elsewhere (e.g., by UnicastRemoteObject)
525 ref = null;
526 skel = null;
527 }
528
529
530 /**
531 * A weak hash map, mapping classes to hash maps that map method
532 * hashes to method objects.
533 **/
534 private static class HashToMethod_Maps
535 extends WeakClassHashMap<Map<Long,Method>>
536 {
537 HashToMethod_Maps() {}
538
539 protected Map<Long,Method> computeValue(Class<?> remoteClass) {
540 Map<Long,Method> map = new HashMap<>();
541 for (Class<?> cl = remoteClass;
542 cl != null;
543 cl = cl.getSuperclass())
544 {
545 for (Class<?> intf : cl.getInterfaces()) {
546 if (Remote.class.isAssignableFrom(intf)) {
547 for (Method method : intf.getMethods()) {
548 final Method m = method;
549 /*
550 * Set this Method object to override language
551 * access checks so that the dispatcher can invoke
552 * methods from non-public remote interfaces.
553 */
554 AccessController.doPrivileged(
555 new PrivilegedAction<Void>() {
556 public Void run() {
557 m.setAccessible(true);
558 return null;
559 }
560 });
|