public byte[] translate( AspectManager manager, String className, ClassLoader loader, byte[] classfileBuffer) throws Exception { if (isReEntry()) { return null; } setReEntry(); super.setTransformationStarted(); try { if (manager.isNonAdvisableClassName(className)) { return null; } AOPClassPool pool = (AOPClassPool) manager.registerClassLoader(loader); CtClass clazz = obtainCtClassInfo(pool, className, classfileBuffer); CtClass woven = instrumentClass(manager, pool, clazz, true); if (woven != null) { pool.lockInCache(woven); if (AspectManager.debugClasses) { SecurityActions.debugWriteFile(clazz); } byte[] rtn = woven.toBytecode(); if (AspectManager.getPrune()) woven.prune(); return rtn; } else { pool.soften(clazz); } return null; } catch (Exception ex) { if (!(ex instanceof NotFoundException)) { if (verbose) logger.error(ex); else logger.error(ex.getMessage() + ".. Do verbose mode if you want full stack trace."); } throw ex; } finally { clearReEntry(); } }
/** * Generated advisors need to load all the superclasses before we load the actual class. * * @author <a href="*****@*****.**">Stale W. Pedersen</a> * @author <a href="mailto:[email protected]">Kabir Khan</a> * @version $Revision: */ public class SuperClassesFirstWeavingStrategy extends WeavingStrategySupport { private static final AOPLogger logger = AOPLogger.getLogger(SuperClassesFirstWeavingStrategy.class); private boolean verbose = AspectManager.verbose; public static final String AOP_PACKAGE = Advised.class.getPackage().getName(); public byte[] translate( AspectManager manager, String className, ClassLoader loader, byte[] classfileBuffer) throws Exception { if (isReEntry()) { return null; } setReEntry(); super.setTransformationStarted(); try { if (manager.isNonAdvisableClassName(className)) { return null; } AOPClassPool pool = (AOPClassPool) manager.registerClassLoader(loader); CtClass clazz = obtainCtClassInfo(pool, className, classfileBuffer); CtClass woven = instrumentClass(manager, pool, clazz, true); if (woven != null) { pool.lockInCache(woven); if (AspectManager.debugClasses) { SecurityActions.debugWriteFile(clazz); } byte[] rtn = woven.toBytecode(); if (AspectManager.getPrune()) woven.prune(); return rtn; } else { pool.soften(clazz); } return null; } catch (Exception ex) { if (!(ex instanceof NotFoundException)) { if (verbose) logger.error(ex); else logger.error(ex.getMessage() + ".. Do verbose mode if you want full stack trace."); } throw ex; } finally { clearReEntry(); } } private CtClass obtainCtClassInfo(AOPClassPool pool, String className, byte[] classfileBuffer) throws NotFoundException { try { return pool.getLocally(className); } catch (NotFoundException e) { // todo Bill Burke: this scares the shit out of me, but it must be done // I think it will screw up hotdeployment at some time. Then again, maybe not ;) ByteArrayClassPath cp = new ByteArrayClassPath(className, classfileBuffer); pool.insertClassPath(cp); return pool.getLocally(className); } catch (Error e) { return null; } } private CtClass instrumentClass( AspectManager manager, AOPClassPool pool, CtClass clazz, boolean isLoadedClass) throws NotFoundException, Exception { if (pool.isClassLoadedButNotWoven(clazz.getName())) { return null; } try { CtClass superClass = clazz.getSuperclass(); if (superClass != null && !Instrumentor.implementsAdvised(clazz)) { ClassPool superPool = superClass.getClassPool(); if (superPool instanceof AOPClassPool) { AspectManager aspectManager = manager; if (manager instanceof Domain && superPool != pool) { // We are in a scoped classloader and the superclass is not aspectManager = AspectManager.instance(superPool.getClassLoader()); } instrumentClass(aspectManager, (AOPClassPool) superPool, superClass, false); } } if (manager.isNonAdvisableClassName(clazz.getName())) { return null; } if (clazz.isArray()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isArray: " + clazz.getName()); pool.flushClass(clazz.getName()); return null; } if (clazz.isInterface()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isInterface: " + clazz.getName()); // pool.flushClass(info.getClassName()); clazz.prune(); return null; } if (clazz.isFrozen()) { if (isAdvised(pool, clazz)) return null; if (verbose && logger.isDebugEnabled()) logger.debug("warning, isFrozen: " + clazz.getName() + " " + clazz.getClassPool()); if (!isLoadedClass) { // What's the point of this? clazz = obtainCtClassInfo(pool, clazz.getName(), null); } else return null; // info.getClazz().defrost(); } boolean transformed = clazz.isModified(); if (!transformed) { ClassAdvisor advisor = AdvisorFactory.getClassAdvisor(clazz, manager); Instrumentor instrumentor = InstrumentorFactory.getInstrumentor( pool, manager, manager.dynamicStrategy.getJoinpointClassifier(), manager.dynamicStrategy.getDynamicTransformationObserver(clazz)); if (!Instrumentor.isTransformable(clazz)) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, implements Untransformable: " + clazz.getName()); // Flushing the generated invocation classes breaks things further down the line // pool.flushClass(info.getClassName()); return null; } manager.attachMetaData(advisor, clazz, true); manager.applyInterfaceIntroductions(advisor, clazz); transformed = instrumentor.transform(clazz, advisor); } if (transformed) { return clazz; } if (isLoadedClass) { pool.setClassLoadedButNotWoven(clazz.getName()); } return null; } catch (Exception e) { throw new RuntimeException("Error converting class ", e); } finally { } } public boolean isAdvised(ClassPool pool, CtClass clazz) throws NotFoundException { CtClass[] interfaces = clazz.getInterfaces(); CtClass advised = pool.get(AOP_PACKAGE + ".Advised"); for (int i = 0; i < interfaces.length; i++) { if (interfaces[i].equals(advised)) return true; if (interfaces[i].getName().equals(AOP_PACKAGE + ".Advised")) return true; } return false; } }
private CtClass instrumentClass( AspectManager manager, AOPClassPool pool, CtClass clazz, boolean isLoadedClass) throws NotFoundException, Exception { if (pool.isClassLoadedButNotWoven(clazz.getName())) { return null; } try { CtClass superClass = clazz.getSuperclass(); if (superClass != null && !Instrumentor.implementsAdvised(clazz)) { ClassPool superPool = superClass.getClassPool(); if (superPool instanceof AOPClassPool) { AspectManager aspectManager = manager; if (manager instanceof Domain && superPool != pool) { // We are in a scoped classloader and the superclass is not aspectManager = AspectManager.instance(superPool.getClassLoader()); } instrumentClass(aspectManager, (AOPClassPool) superPool, superClass, false); } } if (manager.isNonAdvisableClassName(clazz.getName())) { return null; } if (clazz.isArray()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isArray: " + clazz.getName()); pool.flushClass(clazz.getName()); return null; } if (clazz.isInterface()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isInterface: " + clazz.getName()); // pool.flushClass(info.getClassName()); clazz.prune(); return null; } if (clazz.isFrozen()) { if (isAdvised(pool, clazz)) return null; if (verbose && logger.isDebugEnabled()) logger.debug("warning, isFrozen: " + clazz.getName() + " " + clazz.getClassPool()); if (!isLoadedClass) { // What's the point of this? clazz = obtainCtClassInfo(pool, clazz.getName(), null); } else return null; // info.getClazz().defrost(); } boolean transformed = clazz.isModified(); if (!transformed) { ClassAdvisor advisor = AdvisorFactory.getClassAdvisor(clazz, manager); Instrumentor instrumentor = InstrumentorFactory.getInstrumentor( pool, manager, manager.dynamicStrategy.getJoinpointClassifier(), manager.dynamicStrategy.getDynamicTransformationObserver(clazz)); if (!Instrumentor.isTransformable(clazz)) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, implements Untransformable: " + clazz.getName()); // Flushing the generated invocation classes breaks things further down the line // pool.flushClass(info.getClassName()); return null; } manager.attachMetaData(advisor, clazz, true); manager.applyInterfaceIntroductions(advisor, clazz); transformed = instrumentor.transform(clazz, advisor); } if (transformed) { return clazz; } if (isLoadedClass) { pool.setClassLoadedButNotWoven(clazz.getName()); } return null; } catch (Exception e) { throw new RuntimeException("Error converting class ", e); } finally { } }