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; } }
public static CtClass makeInvocationClassNoCtors( AOPClassPool pool, boolean makeInnerClass, CtClass outerClass, String className, CtClass superInvocation) throws CannotCompileException, NotFoundException { CtClass untransformable = pool.get("org.jboss.aop.instrument.Untransformable"); CtClass invocation; if (makeInnerClass) { // Strip away the package from classname String innerClassName = className.substring(className.lastIndexOf('.') + 1); defrostClassIfExists(pool, outerClass.getName() + "$" + innerClassName); // Only static nested classes are supported boolean classStatic = true; invocation = TransformerCommon.makeNestedClass(outerClass, innerClassName, classStatic); invocation.setSuperclass(superInvocation); } else { defrostClassIfExists(pool, className); invocation = TransformerCommon.makeClass(pool, className, superInvocation); } invocation.addInterface(untransformable); return invocation; }
public static void defrostClassIfExists(AOPClassPool pool, String className) { // In some cases we get a class frozen exception. I guess if the invocation class // existed, method was unwrapped and the wrapped again CtClass existing = pool.getCached(className); if (existing != null) { existing.defrost(); } }
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(); } }
@Override public void lockInCache(CtClass clazz) { super.lockInCache(clazz); localResources.put(getResourceName(clazz.getName()), Boolean.TRUE); }
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 { } }