提交 e153f3ac 编写于 作者: K kohsuke

support sending back exported objects to the caller.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@6627 71c3de6d-444a-0410-be80-ed276b4c234a
上级 603aeccf
......@@ -10,7 +10,6 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
......@@ -361,8 +360,7 @@ public class Channel implements VirtualChannel {
// proxy will unexport this instance when it's GC-ed on the remote machine.
final int id = export(instance);
return type.cast(Proxy.newProxyInstance( type.getClassLoader(), new Class[]{type},
new RemoteInvocationHandler(id,userProxy)));
return RemoteInvocationHandler.wrap(null,id,type,userProxy);
}
/*package*/ int export(Object instance) {
......
package hudson.remoting;
import java.io.ObjectStreamException;
/**
* Used internally in the remoting code to have the proxy object
* implement readResolve.
*
* @author Kohsuke Kawaguchi
*/
public interface IReadResolve {
Object readResolve() throws ObjectStreamException;
}
......@@ -3,6 +3,8 @@ package hudson.remoting;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
......@@ -35,6 +37,15 @@ final class RemoteInvocationHandler implements InvocationHandler, Serializable {
*/
private final boolean userProxy;
/**
* If true, indicates that this proxy object is being sent back
* to where it came from. If false, indicate sthat this proxy
* is being sent to the remote peer.
*
* Only used in the serialized form of this class.
*/
private boolean goingHome;
RemoteInvocationHandler(int id, boolean userProxy) {
this.oid = id;
this.userProxy = userProxy;
......@@ -53,7 +64,7 @@ final class RemoteInvocationHandler implements InvocationHandler, Serializable {
* Wraps an OID to the typed wrapper.
*/
public static <T> T wrap(Channel channel, int id, Class<T> type, boolean userProxy) {
return type.cast(Proxy.newProxyInstance( type.getClassLoader(), new Class[]{type},
return type.cast(Proxy.newProxyInstance( type.getClassLoader(), new Class[]{type,IReadResolve.class},
new RemoteInvocationHandler(channel,id,userProxy)));
}
......@@ -88,6 +99,13 @@ final class RemoteInvocationHandler implements InvocationHandler, Serializable {
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getDeclaringClass()==IReadResolve.class) {
// readResolve on the proxy.
// if we are going back to where we came from, replace the proxy by the real object
if(goingHome) return channel.getExportedObject(oid);
else return proxy;
}
if(channel==null)
throw new IllegalStateException("proxy is not connected to a channel");
......@@ -115,6 +133,11 @@ final class RemoteInvocationHandler implements InvocationHandler, Serializable {
ois.defaultReadObject();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
goingHome = channel!=null;
oos.defaultWriteObject();
}
/**
* Two proxies are the same iff they represent the same remote object.
*/
......
......@@ -20,7 +20,7 @@ interface ChannelRunner {
Class<? extends ChannelRunner>[] LIST = new Class[] {
InProcess.class,
Fork.class
// Fork.class
};
......
......@@ -56,6 +56,30 @@ public class SimpleTest extends RmiTestBase {
}
}
/**
* Makes sure that proxied object can be sent back to the origin and resolve correctly.
*/
public void test3() throws Exception {
Foo c = new Foo() {};
Foo r = channel.call(new Echo<Foo>(channel.export(Foo.class,c)));
assertSame(c,r);
}
public static interface Foo {}
private static class Echo<T> implements Callable<T,RuntimeException> {
private final T t;
Echo(T t) {
this.t = t;
}
public T call() throws RuntimeException {
return t;
}
}
public static Test suite() throws Exception {
return buildSuite(SimpleTest.class);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册