1 package hudson.remoting; 2 3 import java.io.ByteArrayOutputStream ; 4 import java.io.File ; 5 import java.io.FileOutputStream ; 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.net.URL ; 9 import java.util.Enumeration ; 10 import java.util.HashMap ; 11 import java.util.Map ; 12 import java.util.Vector ; 13 import java.util.List ; 14 import java.util.ArrayList ; 15 16 21 final class RemoteClassLoader extends ClassLoader { 22 private final IClassLoader proxy; 23 24 private final Map <String ,URL > resourceMap = new HashMap <String ,URL >(); 25 private final Map <String ,Vector <URL >> resourcesMap = new HashMap <String ,Vector <URL >>(); 26 27 public RemoteClassLoader(ClassLoader parent, IClassLoader proxy) { 28 super(parent); 29 this.proxy = proxy; 30 } 31 32 protected Class <?> findClass(String name) throws ClassNotFoundException { 33 byte[] bytes = proxy.fetch(name); 34 return defineClass(name, bytes, 0, bytes.length); 35 } 36 37 protected URL findResource(String name) { 38 if(resourceMap.containsKey(name)) 39 return resourceMap.get(name); 40 41 try { 42 byte[] image = proxy.getResource(name); 43 if(image==null) { 44 resourceMap.put(name,null); 45 return null; 46 } 47 48 URL url = makeResource(name, image); 49 resourceMap.put(name,url); 50 return url; 51 } catch (IOException e) { 52 throw new Error ("Unable to load resource "+name,e); 53 } 54 } 55 56 protected Enumeration <URL > findResources(String name) throws IOException { 57 Vector <URL > urls = resourcesMap.get(name); 58 if(urls!=null) 59 return urls.elements(); 60 61 byte[][] images = proxy.getResources(name); 62 63 urls = new Vector <URL >(); 64 for( byte[] image: images ) 65 urls.add(makeResource(name,image)); 66 resourcesMap.put(name,urls); 67 68 return urls.elements(); 69 } 70 71 private URL makeResource(String name, byte[] image) throws IOException { 72 int idx = name.lastIndexOf('/'); 73 File f = File.createTempFile("hudson-remoting","."+name.substring(idx+1)); 74 FileOutputStream fos = new FileOutputStream (f); 75 fos.write(image); 76 fos.close(); 77 f.deleteOnExit(); 78 79 return f.toURL(); 80 } 81 82 85 static interface IClassLoader { 86 byte[] fetch(String className) throws ClassNotFoundException ; 87 byte[] getResource(String name) throws IOException ; 88 byte[][] getResources(String name) throws IOException ; 89 } 90 91 public static IClassLoader export(ClassLoader cl, Channel local) { 92 return local.export(IClassLoader.class, new ClassLoaderProxy(cl), false); 93 } 94 95 98 static int exportId(ClassLoader cl, Channel local) { 99 return local.export(new ClassLoaderProxy(cl)); 100 } 101 102 static final class ClassLoaderProxy implements IClassLoader { 103 private final ClassLoader cl; 104 105 public ClassLoaderProxy(ClassLoader cl) { 106 this.cl = cl; 107 } 108 109 public byte[] fetch(String className) throws ClassNotFoundException { 110 InputStream in = cl.getResourceAsStream(className.replace('.', '/') + ".class"); 111 if(in==null) 112 throw new ClassNotFoundException (className); 113 114 try { 115 return readFully(in); 116 } catch (IOException e) { 117 throw new ClassNotFoundException (); 118 } 119 } 120 121 122 public byte[] getResource(String name) throws IOException { 123 InputStream in = cl.getResourceAsStream(name); 124 if(in==null) return null; 125 126 return readFully(in); 127 } 128 129 public byte[][] getResources(String name) throws IOException { 130 List <byte[]> images = new ArrayList <byte[]>(); 131 132 Enumeration <URL > e = cl.getResources(name); 133 while(e.hasMoreElements()) { 134 images.add(readFully(e.nextElement().openStream())); 135 } 136 137 return images.toArray(new byte[images.size()][]); 138 } 139 140 private byte[] readFully(InputStream in) throws IOException { 141 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 142 143 byte[] buf = new byte[8192]; 144 int len; 145 while((len=in.read(buf))>0) 146 baos.write(buf,0,len); 147 in.close(); 148 149 return baos.toByteArray(); 150 } 151 152 public boolean equals(Object that) { 153 if (this == that) return true; 154 if (that == null || getClass() != that.getClass()) return false; 155 156 return cl.equals(((ClassLoaderProxy) that).cl); 157 } 158 159 public int hashCode() { 160 return cl.hashCode(); 161 } 162 } 163 } 164 | Popular Tags |