1 package hudson.remoting; 2 3 import hudson.remoting.RemoteClassLoader.IClassLoader; 4 5 import java.io.ByteArrayInputStream ; 6 import java.io.ByteArrayOutputStream ; 7 import java.io.IOException ; 8 import java.io.ObjectOutputStream ; 9 import java.io.Serializable ; 10 import java.io.NotSerializableException ; 11 12 22 final class UserRequest<RSP,EXC extends Throwable > extends Request<UserResponse<RSP,EXC>,EXC> { 23 24 private final byte[] request; 25 private final IClassLoader classLoaderProxy; 26 private final String toString; 27 28 public UserRequest(Channel local, Callable<?,EXC> c) throws IOException { 29 request = serialize(c,local); 30 this.toString = c.toString(); 31 ClassLoader cl = getClassLoader(c); 32 classLoaderProxy = RemoteClassLoader.export(cl,local); 33 } 34 35 static ClassLoader getClassLoader(Callable<?,?> c) { 36 ClassLoader cl = c.getClass().getClassLoader(); 37 if(c instanceof DelegatingCallable) 38 cl = ((DelegatingCallable)c).getClassLoader(); 39 return cl; 40 } 41 42 protected UserResponse<RSP,EXC> perform(Channel channel) throws EXC { 43 try { 44 ClassLoader cl = channel.importedClassLoaders.get(classLoaderProxy); 45 46 RSP r = null; 47 Channel oldc = Channel.setCurrent(channel); 48 try { 49 Object o = new ObjectInputStreamEx(new ByteArrayInputStream (request), cl).readObject(); 50 51 Callable<RSP,EXC> callable = (Callable<RSP,EXC>)o; 52 53 ClassLoader old = Thread.currentThread().getContextClassLoader(); 54 Thread.currentThread().setContextClassLoader(cl); 55 try { 57 r = callable.call(); 58 } finally { 59 Thread.currentThread().setContextClassLoader(old); 60 } 61 } finally { 62 Channel.setCurrent(oldc); 63 } 64 65 return new UserResponse<RSP,EXC>(serialize(r,channel),false); 66 } catch (Throwable e) { 67 try { 69 return new UserResponse<RSP,EXC>(serialize(e,channel),true); 70 } catch (IOException x) { 71 throw (EXC)x; 73 } 74 } 75 } 76 77 private byte[] serialize(Object o, Channel localChannel) throws IOException { 78 Channel old = Channel.setCurrent(localChannel); 79 try { 80 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 81 new ObjectOutputStream (baos).writeObject(o); 82 return baos.toByteArray(); 83 } catch( NotSerializableException e ) { 84 IOException x = new IOException ("Unable to serialize " + o); 85 x.initCause(e); 86 throw x; 87 } finally { 88 Channel.setCurrent(old); 89 } 90 } 91 92 public String toString() { 93 return "UserRequest:"+toString; 94 } 95 } 96 97 final class UserResponse<RSP,EXC extends Throwable > implements Serializable { 98 private final byte[] response; 99 private final boolean isException; 100 101 public UserResponse(byte[] response, boolean isException) { 102 this.response = response; 103 this.isException = isException; 104 } 105 106 public RSP retrieve(Channel channel, ClassLoader cl) throws IOException , ClassNotFoundException , EXC { 107 Channel old = Channel.setCurrent(channel); 108 try { 109 Object o = new ObjectInputStreamEx(new ByteArrayInputStream (response), cl).readObject(); 110 111 if(isException) 112 throw (EXC)o; 113 else 114 return (RSP) o; 115 } finally { 116 Channel.setCurrent(old); 117 } 118 } 119 120 private static final long serialVersionUID = 1L; 121 } 122 | Popular Tags |