public static DialogFieldConfig getDialogFieldFromSuperClasses(CtMethod method) throws NotFoundException, ClassNotFoundException, InvalidComponentClassException { DialogFieldConfig dialogFieldConfig = null; List<CtClass> classes = new ArrayList<CtClass>(); CtClass clazz = method.getDeclaringClass(); classes.add(clazz); while (clazz.getSuperclass() != null) { classes.add(clazz.getSuperclass()); clazz = clazz.getSuperclass(); } Collections.reverse(classes); CtMember interfaceMember = getMemberForAnnotatedInterfaceMethod(method); if (interfaceMember != null) { dialogFieldConfig = new DialogFieldConfig( (DialogField) interfaceMember.getAnnotation(DialogField.class), interfaceMember); } for (CtClass ctclass : classes) { try { CtMethod superClassMethod = ctclass.getDeclaredMethod(method.getName(), method.getParameterTypes()); if (superClassMethod.hasAnnotation(DialogField.class)) { dialogFieldConfig = new DialogFieldConfig( (DialogField) superClassMethod.getAnnotation(DialogField.class), superClassMethod); } else if (superClassMethod.hasAnnotation(DialogFieldOverride.class)) { mergeDialogFields(dialogFieldConfig, superClassMethod); } } catch (NotFoundException e) { } } return dialogFieldConfig; }
private static CtMember getMemberForAnnotatedInterfaceMethod(CtMethod member) throws InvalidComponentClassException, ClassNotFoundException, NotFoundException { CtMethod newMember = null; List<CtClass> interfaces = new ArrayList<CtClass>(); CtClass clazz = member.getDeclaringClass(); while (clazz != null) { interfaces.addAll(Arrays.asList(clazz.getInterfaces())); clazz = clazz.getSuperclass(); } for (CtClass ctclass : interfaces) { try { CtMethod newMethodMember = ctclass.getDeclaredMethod(member.getName(), member.getParameterTypes()); DialogField tempDialogProperty = (DialogField) newMethodMember.getAnnotation(DialogField.class); if (tempDialogProperty != null) { if (newMember == null) { newMember = newMethodMember; } else { throw new InvalidComponentClassException( "Class has multiple interfaces that have the same method signature annotated"); } } } catch (NotFoundException e) { } } if (newMember != null) { member = newMember; } return newMember; }
// TODO: Implement byte code instrumentation to replace calls to methods that do not exist in // proxy by invoke(callee,methodHash/methodName,args) protected void instrument( CtClass toManipulate, String extRef, ClassPool externalPool, String proxyName, ProxyLoader loader) throws NotFoundException, CannotCompileException { ClassPool proxyPool = getPool(externalPool, loader); // javassist bytecode manipulation // LOG.info(" onWrite: getting proxy "+proxyName+" from pool "+loader.getClassPath()); CtClass proxyCtClass = proxyPool.get(proxyName); // LOG.info(" onWrite: getting external class "+extRef+" from pool "+extCop.getClassPath()); CtClass extRefCtClass = externalPool.get(extRef); if (proxyCtClass.getSuperclass() == extRefCtClass) { CodeConverter conv = new CodeConverter(); conv.replaceNew(extRefCtClass, proxyCtClass, TransparentProxyFactory.factoryMethod); // replace any occurence of "new $extRefClass ()" by "$proxyClass.$factoryMathod" in code of // $className toManipulate.instrument(conv); // e.g. "new TestComponentMain()" is replaced by // "Proxy4_TestComponentMain.newExternalInstance()" in bytecode of class // "ComponentUsingAnotherOne" // LOG.info(" Finished bytecode instrumentation of "+toManipulate.getName()); } }
/** * Return whether or not the class has a method with the given name * * @param theClass the class to inspect * @param theName the name of the method to look for * @return true if the class contains the method, false otherwise */ private static boolean hasMethod(CtClass theClass, String theName) { try { return theClass.getDeclaredMethod(theName) != null && !Modifier.isAbstract(theClass.getDeclaredMethod(theName).getModifiers()); } catch (NotFoundException e) { try { if (theClass.getSuperclass() != null) { return hasMethod(theClass.getSuperclass(), theName); } else { return false; } } catch (NotFoundException e1) { return false; } } }
private Class<?> injectToPlainClassLoader( ClassPool pool, ClassLoader classLoader, String className) throws NotFoundException, IOException, CannotCompileException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { Class<?> c = null; try { c = classLoader.loadClass(className); } catch (ClassNotFoundException ignore) { } if (c != null) { return c; } CtClass ct = pool.get(className); if (ct == null) { throw new NotFoundException(className); } CtClass superClass = ct.getSuperclass(); if (superClass != null) { injectToPlainClassLoader(pool, classLoader, superClass.getName()); } CtClass[] interfaces = ct.getInterfaces(); for (CtClass i : interfaces) { injectToPlainClassLoader(pool, classLoader, i.getName()); } Collection<String> refs = ct.getRefClasses(); for (String ref : refs) { try { injectToPlainClassLoader(pool, classLoader, ref); } catch (NotFoundException e) { logger.warn("Skip a referenced class because of NotFoundException : ", e); } } byte[] bytes = ct.toBytecode(); return (Class<?>) DEFINE_CLASS.invoke(classLoader, ct.getName(), bytes, 0, bytes.length); }
public void onWrite(ClassPool pool, String className) throws NotFoundException, CannotCompileException { CtClass cc = pool.get(className); try { if (isPersistent(className)) { CtClass base = cc.getSuperclass(); CtConstructor cons = new CtConstructor(constructorParams, cc); if (base.subclassOf(persistent) || base == object) { cons.setBody(null); cc.addConstructor(cons); if (base == object) { cc.setSuperclass(persistent); } } else { if (!isPersistent(base.getName())) { throw new NotFoundException( "Base class " + base.getName() + " was not declared as persistent"); } cons.setBody("super($0);"); cc.addConstructor(cons); } preprocessMethods(cc, true, true); if (base == persistent || base == object) { CtMethod m = new CtMethod(isRecursive, cc, null); m.setBody("return false;"); cc.addMethod(m); addSerializeMethods(cc, false); } else if (base.subtypeOf(serializable)) { addSerializeMethods(cc, true); } if ((cc.getModifiers() & Modifier.PRIVATE) == 0) { CtClass f = pool.makeClass(className + "LoadFactory"); f.addInterface(factory); CtMethod c = new CtMethod(create, f, null); c.setBody("return new " + className + "($1);"); f.addMethod(c); CtNewConstructor.defaultConstructor(f); } } else { preprocessMethods( cc, cc.subtypeOf(persistent) && cc != persistent, !className.startsWith("org.nachodb")); } } catch (Exception x) { x.printStackTrace(); } }
private static void findConstructors( CtClass ctClass, Set<CtConstructor> set, Class<?>... argsClasses) { try { if (ctClass == null) { return; } CtConstructor[] constructors = ctClass.getDeclaredConstructors(); if (constructors.length == 0) { findConstructors(ctClass.getSuperclass(), set, argsClasses); } else if (constructors.length == 1 && argsClasses.length == 0) { set.add(constructors[0]); } else { for (CtConstructor c : constructors) { if (c.getParameterTypes().length != argsClasses.length) { continue; } boolean sameArgs = true; for (int i = 0; i < argsClasses.length; i++) { String requestedClassName = argsClasses[i].getName(); String currentClassName = c.getParameterTypes()[i].getName(); if (!requestedClassName.equals(currentClassName)) { sameArgs = false; } } if (sameArgs) { set.add(c); } } } } catch (NotFoundException e) { // should never happen throw new GwtTestPatchException( "Error while trying find a constructor in class '" + ctClass.getName() + "'", e); } }
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 { } }
/** * looks for classes that are referenced within the code of the class named <code>classname</code> * that do neither belong to system classes nor to the same component as the class searched. Any * external reference found must belong to a dependency component of the component of the class * being searched. For each occurrence of such an external reference, <code>foundExternalReference * </code> is invoked. * * @param classname * @param pool * @param loadingCop * @return */ protected int searchExternalReferences( String classname, ClassPool pool, IComponentResource loadingCop) { // LOG.info(logCounter+" found it ... in pool // "+loadingCop.getExtResLocation() + loadingCop.getCodeBase()); // search for external references in code of class "className" using CtClass.getRefClasses() and // create an externalPool for each cop in dependencies CtClass toSearch = null; try { // LOG.info(cp+" "+v+": searching for external references in "+classname); toSearch = pool.get(classname); CtClass[] ifcs = toSearch.getInterfaces(); CtClass superClass = toSearch.getSuperclass(); } catch (IllegalStateException e) { LOG.error("Zipfile is not open", e); } catch (NotFoundException e) { LOG.error( "javassist.NotFoundException: class " + classname + " not found in " + cp + " " + v); throw new RuntimeException(); // loadClassBytes fails -> loadFromDep } Vector externalClasses = new Vector(); Iterator referencedClasses = toSearch.getRefClasses().iterator(); int extRefCount = 0; while (referencedClasses.hasNext()) { String toWrap = (String) referencedClasses.next(); IComponentResource dependencyCop; Object cached = class2cop.get(toSearch.getName()); if (cached instanceof UpgradeableComponentResource) { dependencyCop = (UpgradeableComponentResource) cached; } else { dependencyCop = UpgradeableComponentResourceFactory.getComponentResourceByContent(toWrap); } if ((dependencyCop instanceof UpgradeableComponentResource) && (!loadingCop .getCodeBase() .equals( dependencyCop .getCodeBase()))) { // compare jar names (different versions are considered // equal: java.** and internal Classes seems to be // external of new cop version (found inside old cop // version)) // a dependency that may be uncoupled has been found // dependency is ignored if the dependency class is already hidden behind a proxy // or the dependency class may be in use already or the dependency class lies in a previous // version of the loading cop // LOG.info("Found dependency to external class "+toWrap+" in cop "+dependencyCop+" while // loading class "+toSearch.getName()+" in cop "+loadingCop); foundExternalReference(loadingCop, toWrap, (UpgradeableComponentResource) dependencyCop); extRefCount++; } else { // if (dependencyCop == null) LOG.error("Nullpointer, dependencyCop is null (system // class?)"); // else if (dependencyCop != loadingCop) LOG.info("dependency is NOT evolvable // "+dependencyCop.getCodeBase()+" : "+dependencyCop.getClass().getName()); } } // LOG.info(logCounter+" onWrite: Found "+extRefCount+" external reference(s) in // "+loadingCop.getCodeBase()+"."+classname); return extRefCount; }