1 22 package org.jboss.aop.standalone; 23 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.lang.reflect.Method ; 30 import java.net.URL ; 31 import java.security.AccessController ; 32 import java.security.CodeSource ; 33 import java.security.PrivilegedAction ; 34 import java.security.PrivilegedActionException ; 35 import java.security.PrivilegedExceptionAction ; 36 import java.security.ProtectionDomain ; 37 import java.security.cert.Certificate ; 38 import java.util.Enumeration ; 39 40 68 public class SystemClassLoader 69 extends ClassLoader 70 { 71 74 private static final int NOT_INSTALLED = 0; 75 76 79 private static final int INSTALLED = 1; 80 81 84 private static final int INITIALIZING = 2; 85 86 89 private static final int INITIALIZED = 3; 90 91 94 private int state = NOT_INSTALLED; 95 96 99 ClassLoader parent = null; 100 101 102 105 Method deployXML; 106 107 111 Method transform; 112 113 116 Method instance; 117 118 121 Object aspectManager; 122 123 130 public SystemClassLoader(ClassLoader parent) 131 { 132 super(parent); 133 install(); 134 } 135 136 145 public synchronized Class loadClass(String name, boolean resolve) 146 throws ClassNotFoundException 147 { 148 Class clazz = findLoadedClass(name); 150 if (clazz != null) 151 { 152 if (resolve) resolveClass(clazz); 153 return clazz; 154 } 155 156 clazz = loadClassByDelegation(name); 158 if (clazz != null) 159 { 160 if (resolve) resolveClass(clazz); 161 return clazz; 162 } 163 164 initialize(); 166 167 try 169 { 170 ClassBytes origBytes = loadClassBytes(name); 171 ClassBytes classBytes = new ClassBytes(); 172 173 if (state == INITIALIZED) 175 { 176 final Object [] args = {this, name, null, null, origBytes.bytes}; 177 if (!name.startsWith("org.jboss.aop")) 178 { 179 classBytes.bytes = (byte[]) transform.invoke(aspectManager, args); 180 classBytes.protectionDomain = origBytes.protectionDomain; 181 } 182 } 183 if (classBytes.bytes == null) 184 classBytes = origBytes; 185 186 return defineClassFromBytes(name, classBytes, resolve); 188 } 189 catch (IOException ioe) 190 { 191 throw new ClassNotFoundException ("Unable to load " + name, ioe); 192 } 193 catch (IllegalAccessException iae) 194 { 195 throw new Error (iae); 196 } 197 catch (InvocationTargetException ite) 198 { 199 throw new Error ("Error transforming the class " + name, ite.getCause()); 200 } 201 } 202 203 206 protected ClassBytes loadClassBytes(String name) 207 throws ClassNotFoundException , IOException 208 { 209 final String classFileName = name.replace('.', '/') + ".class"; 210 final URL url = (URL ) AccessController.doPrivileged(new PrivilegedAction () 211 { 212 public Object run() 213 { 214 return getParent().getResource(classFileName); 215 } 216 }); 217 ProtectionDomain protectionDomain = null; 218 InputStream in = null; 219 if (url != null) 220 { 221 try 222 { 223 in = (InputStream ) AccessController.doPrivileged(new PrivilegedExceptionAction () 224 { 225 public Object run() throws Exception 226 { 227 return url.openStream(); 228 } 229 }); 230 } 231 catch (PrivilegedActionException e) 232 { 233 throw new ClassNotFoundException (name, e); 234 } 235 String urlstring = url.toExternalForm(); 236 URL urlCS = url; 237 if (urlstring.startsWith("jar:")) 238 { 239 int i = urlstring.indexOf('!'); 240 String cs = urlstring.substring(4, i); 241 urlCS = new URL (cs); 242 } 243 else 244 { 245 int i = urlstring.indexOf(classFileName); 246 if (i != -1) 247 { 248 String cs = urlstring.substring(0, i); 249 urlCS = new URL (cs); 250 } 251 } 252 CodeSource codeSource = new CodeSource (urlCS, (Certificate []) null); 253 protectionDomain = new ProtectionDomain (codeSource, null, this, null); 254 } 255 else 256 { 257 260 try 261 { 262 in = (InputStream ) AccessController.doPrivileged(new PrivilegedExceptionAction () 263 { 264 public Object run() throws Exception 265 { 266 String tmpdir = System.getProperty("java.io.tmpdir"); 267 File aopdynclasses = new File (tmpdir, "aopdynclasses"); 268 File classFile = new File (aopdynclasses, classFileName); 269 return new FileInputStream (classFile); 270 } 271 }); 272 } 273 catch (PrivilegedActionException e) 274 { 275 throw new ClassNotFoundException (name, e); 276 } 277 } 278 279 byte[][] bufs = new byte[8][]; 280 int bufsize = 4096; 281 282 for (int i = 0; i < 8; ++i) 283 { 284 bufs[i] = new byte[bufsize]; 285 int size = 0; 286 int len = 0; 287 do 288 { 289 len = in.read(bufs[i], size, bufsize - size); 290 if (len >= 0) 291 size += len; 292 else 293 { 294 byte[] result = new byte[bufsize - 4096 + size]; 295 int s = 0; 296 for (int j = 0; j < i; ++j) 297 { 298 System.arraycopy(bufs[j], 0, result, s, s + 4096); 299 s = s + s + 4096; 300 } 301 302 System.arraycopy(bufs[i], 0, result, s, size); 303 ClassBytes classBytes = new ClassBytes(); 304 classBytes.bytes = result; 305 classBytes.protectionDomain = protectionDomain; 306 return classBytes; 307 } 308 } 309 while (size < bufsize); 310 bufsize *= 2; 311 } 312 313 throw new IOException ("too much data loading class " + name); 314 } 315 316 324 protected Class defineClassFromBytes(String name, ClassBytes bytes, boolean resolve) 325 { 326 definePackage(name); 327 byte[] b = bytes.bytes; 328 Class clazz = defineClass(name, b, 0, b.length, bytes.protectionDomain); 329 if (resolve) resolveClass(clazz); 330 return clazz; 331 } 332 333 339 protected void definePackage(String className) 340 { 341 int i = className.lastIndexOf('.'); 342 if (i == -1) 343 return; 344 345 try 346 { 347 definePackage(className.substring(0, i), null, null, null, null, null, null, null); 348 } 349 catch (IllegalArgumentException alreadyDone) 350 { 351 } 352 } 353 354 361 protected Class loadClassLocally(String name) 362 throws ClassNotFoundException 363 { 364 try 365 { 366 ClassBytes bytes = loadClassBytes(name); 367 return defineClassFromBytes(name, bytes, true); 368 } 369 catch (Throwable ex) 370 { 371 throw new ClassNotFoundException (name, ex); 372 } 373 } 374 375 382 protected Class loadClassByDelegation(String name) 383 throws ClassNotFoundException 384 { 385 if (name.startsWith("java.") || name.startsWith("javax.") 387 || name.startsWith("sun.") || name.startsWith("com.sun.") 388 || name.startsWith("org.apache.xerces.") || name.startsWith("org.xml.sax.") 389 || name.startsWith("org.w3c.dom.")) 390 return getParent().loadClass(name); 391 392 return null; 393 } 394 395 399 protected synchronized void install() 400 { 401 try 402 { 403 Class clazz = loadClassLocally("org.jboss.aop.AspectManager"); 405 Class [] transformSig = {ClassLoader .class, String .class, 406 Class .class, ProtectionDomain .class, byte[].class}; 407 transform = clazz.getMethod("transform", transformSig); 408 instance = clazz.getMethod("instance", new Class [0]); 409 410 clazz = loadClassLocally("org.jboss.aop.AspectXmlLoader"); 412 deployXML = clazz.getMethod("deployXML", new Class []{URL .class}); 413 414 483 484 state = INSTALLED; 485 } 486 catch (Throwable t) 487 { 488 t.printStackTrace(); 489 throw new Error ("Error initializing system classloader", t); 490 } 491 } 492 493 496 protected synchronized void initialize() 497 { 498 if (state != INSTALLED) 500 return; 501 state = INITIALIZING; 502 503 Thread.currentThread().setContextClassLoader(this); 505 506 try 509 { 510 try 511 { 512 System.setProperty("jboss.aop.optimized", "false"); 513 aspectManager = instance.invoke(null, new Object [0]); 514 } 515 catch (InvocationTargetException ite) 516 { 517 throw ite.getCause(); 518 } 519 state = INITIALIZED; 520 } 521 catch (Throwable t) 522 { 523 t.printStackTrace(); 524 throw new Error ("Error installing aspect manager", t); 525 } 526 527 try 529 { 530 Enumeration enumeration = getParent().getResources("META-INF/jboss-aop.xml"); 531 while (enumeration.hasMoreElements()) 532 { 533 URL url = (URL ) enumeration.nextElement(); 534 deployXML.invoke(null, new Object []{url}); 535 } 536 } 537 catch (Throwable t) 538 { 539 t.printStackTrace(); 540 throw new Error ("Error deploying aop configrations", t); 541 } 542 } 543 544 547 private static class ClassBytes 548 { 549 public ProtectionDomain protectionDomain; 550 public byte[] bytes; 551 } 552 } 553 | Popular Tags |