1 8 9 package mx4j.remote.rmi; 10 11 import java.io.BufferedInputStream ; 12 import java.io.BufferedOutputStream ; 13 import java.io.ByteArrayOutputStream ; 14 import java.io.IOException ; 15 import java.io.InputStream ; 16 import java.lang.reflect.InvocationTargetException ; 17 import java.lang.reflect.Method ; 18 import java.net.URL ; 19 import java.rmi.MarshalledObject ; 20 import java.security.AccessController ; 21 import java.security.PrivilegedAction ; 22 import java.security.SecureClassLoader ; 23 24 62 class RMIMarshaller 63 { 64 private static final Method unmarshal = getUnmarshalMethod(); 65 66 private static Method getUnmarshalMethod() 67 { 68 return (Method )AccessController.doPrivileged(new PrivilegedAction () 69 { 70 public Object run() 71 { 72 String marshallerName = Marshaller.class.getName(); 73 InputStream stream = Marshaller.class.getResourceAsStream(marshallerName.substring(marshallerName.lastIndexOf('.') + 1) + ".class"); 74 if (stream == null) throw new Error ("Could not load implementation class " + marshallerName); 75 BufferedInputStream bis = new BufferedInputStream (stream); 76 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 77 BufferedOutputStream bos = new BufferedOutputStream (baos); 78 try 79 { 80 byte[] buffer = new byte[256]; 81 int read = -1; 82 while ((read = bis.read(buffer)) >= 0) bos.write(buffer, 0, read); 83 bis.close(); 84 bos.close(); 85 } 86 catch (IOException x) 87 { 88 throw new Error (x.toString()); 89 } 90 91 byte[] classBytes = baos.toByteArray(); 92 93 MarshallerClassLoader loader = new MarshallerClassLoader(classBytes); 94 95 try 96 { 97 Class cls = loader.loadClass(marshallerName); 98 return cls.getMethod("unmarshal", new Class []{MarshalledObject .class}); 99 } 100 catch (ClassNotFoundException x) 101 { 102 throw new Error (x.toString()); 103 } 104 catch (NoSuchMethodException x) 105 { 106 throw new Error (x.toString()); 107 } 108 } 109 }); 110 } 111 112 115 public static MarshalledObject marshal(Object object) throws IOException 116 { 117 if (object == null) return null; 118 return new MarshalledObject (object); 119 } 120 121 125 public static Object unmarshal(MarshalledObject object, final ClassLoader mbeanLoader, final ClassLoader defaultLoader) throws IOException 126 { 127 if (object == null) return null; 128 if (mbeanLoader == null) return unmarshal(object, defaultLoader); 129 130 ClassLoader loader = (ClassLoader )AccessController.doPrivileged(new PrivilegedAction () 131 { 132 public Object run() 133 { 134 return new ExtendedClassLoader(mbeanLoader, defaultLoader); 135 } 136 }); 137 return unmarshal(object, loader); 138 } 139 140 private static Object unmarshal(MarshalledObject object, ClassLoader loader) throws IOException 141 { 142 if (loader != null) 143 { 144 ClassLoader old = Thread.currentThread().getContextClassLoader(); 145 try 146 { 147 setContextClassLoader(loader); 148 return unmarshal(object); 149 } 150 catch (IOException x) 151 { 152 throw x; 153 } 154 catch (ClassNotFoundException ignored) 155 { 156 } 157 finally 158 { 159 setContextClassLoader(old); 160 } 161 } 162 throw new IOException ("Cannot unmarshal " + object); 163 } 164 165 private static Object unmarshal(MarshalledObject marshalled) throws IOException , ClassNotFoundException 166 { 167 try 168 { 169 return unmarshal.invoke(null, new Object []{marshalled}); 170 } 171 catch (InvocationTargetException x) 172 { 173 Throwable t = x.getTargetException(); 174 if (t instanceof IOException ) throw (IOException )t; 175 if (t instanceof ClassNotFoundException ) throw (ClassNotFoundException )t; 176 throw new IOException (t.toString()); 177 } 178 catch (Exception x) 179 { 180 throw new IOException (x.toString()); 181 } 182 } 183 184 private static void setContextClassLoader(final ClassLoader loader) 185 { 186 AccessController.doPrivileged(new PrivilegedAction () 187 { 188 public Object run() 189 { 190 Thread.currentThread().setContextClassLoader(loader); 191 return null; 192 } 193 }); 194 } 195 196 private static class MarshallerClassLoader extends SecureClassLoader 197 { 198 private byte[] bytes; 199 200 209 private MarshallerClassLoader(byte[] classBytes) 210 { 211 super(null); 212 this.bytes = classBytes; 213 } 214 215 223 public Class loadClass(final String name) throws ClassNotFoundException 224 { 225 if (name.startsWith(Marshaller.class.getName())) 226 { 227 try 228 { 229 return defineClass(name, bytes, 0, bytes.length, MarshallerClassLoader.this.getClass().getProtectionDomain()); 230 } 231 catch (ClassFormatError x) 232 { 233 throw new ClassNotFoundException ("Class Format Error", x); 234 } 235 } 236 else 237 { 238 return super.loadClass(name); 239 } 240 } 241 } 242 243 247 private static class ExtendedClassLoader extends SecureClassLoader 248 { 249 private final ClassLoader defaultLoader; 250 251 private ExtendedClassLoader(ClassLoader mbeanLoader, ClassLoader defaultLoader) 252 { 253 super(mbeanLoader); 254 this.defaultLoader = defaultLoader; 255 } 256 257 protected Class findClass(String name) throws ClassNotFoundException 258 { 259 return defaultLoader.loadClass(name); 260 } 261 262 protected URL findResource(String name) 263 { 264 return defaultLoader.getResource(name); 265 } 266 } 267 } 268 | Popular Tags |