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());
    }
  }
예제 #4
0
 /**
  * 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);
  }
예제 #6
0
 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();
   }
 }
예제 #7
0
  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;
  }