// 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());
    }
  }
Ejemplo n.º 2
0
 public static void main(String[] args)
     throws NotFoundException, CannotCompileException, IOException {
   ClassPool classPool = ClassPool.getDefault();
   classPool.appendClassPath(new ClassClassPath(JavassistLengthBug.class));
   CtClass dummyClass = classPool.get("net.fwbrasil.activate.entity.Dummy");
   dummyClass.instrument(
       new ExprEditor() {
         public void edit(FieldAccess fa) {
           if (fa.isReader() && fa.getFieldName().equals("length"))
             try {
               fa.replace("$_ = ($r) this.length.substring(1);");
             } catch (CannotCompileException e) {
               e.printStackTrace();
             }
         }
       });
   dummyClass.toClass();
   new Dummy().print();
 }
  /**
   * Transforms the call side pointcuts.
   *
   * @param context the transformation context
   * @param klass the class set.
   */
  public void transform(final Context context, final Klass klass)
      throws NotFoundException, CannotCompileException {
    List definitions = SystemDefinitionContainer.getDefinitionsContext();

    m_joinPointIndex =
        TransformationUtil.getJoinPointIndex(klass.getCtClass()); // TODO thread safe reentrant

    for (Iterator it = definitions.iterator(); it.hasNext(); ) {
      final SystemDefinition definition = (SystemDefinition) it.next();

      final CtClass ctClass = klass.getCtClass();
      final ClassMetaData classMetaData = context.getMetaDataMaker().createClassMetaData(ctClass);

      // filter caller classes
      if (classFilter(definition, classMetaData, ctClass)) {
        continue;
      }

      ctClass.instrument(
          new ExprEditor() {
            public void edit(MethodCall methodCall) throws CannotCompileException {
              try {
                CtBehavior where = null;

                try {
                  where = methodCall.where();
                } catch (RuntimeException e) {
                  // <clinit> access leads to a bug in Javassist
                  where = ctClass.getClassInitializer();
                }

                // filter caller methods
                if (methodFilterCaller(where)) {
                  return;
                }

                // get the callee method name, signature and class name
                CtMethod calleeMethod = methodCall.getMethod();
                String calleeClassName = methodCall.getClassName();

                // filter callee classes
                if (!definition.inIncludePackage(calleeClassName)) {
                  return;
                }

                // filter callee methods
                if (methodFilterCallee(calleeMethod)) {
                  return;
                }

                // create the class meta-data
                ClassMetaData calleeSideClassMetaData;

                try {
                  calleeSideClassMetaData =
                      context
                          .getMetaDataMaker()
                          .createClassMetaData(context.getClassPool().get(calleeClassName));
                } catch (NotFoundException e) {
                  // TODO - AV - 20040507 small fix for test.aopc. that use on the fly generated
                  // classes
                  if (calleeClassName.equals(ctClass.getName())) {
                    calleeSideClassMetaData = classMetaData;
                  } else {
                    throw new WrappedRuntimeException(e);
                  }
                }

                // create the method meta-data
                MethodMetaData calleeSideMethodMetaData =
                    JavassistMetaDataMaker.createMethodMetaData(methodCall.getMethod());

                // is this a caller side method pointcut?
                if (definition.isPickedOutByCallPointcut(
                    calleeSideClassMetaData, calleeSideMethodMetaData)) {
                  //                            // TODO: should this caller data be passed to the
                  // join point? It is possible.
                  //                            String callerMethodName = callerBehaviour.getName();
                  //                            String callerMethodSignature =
                  // callerBehaviour.getSignature();
                  //                            CtClass[] callerMethodParameterTypes =
                  // callerBehaviour.getParameterTypes();
                  //                            int callerMethodModifiers =
                  // callerBehaviour.getModifiers();
                  // check the callee class is not the same as target class, if that is the case
                  // then we have have class loaded and set in the ___AW_clazz already
                  String declaringClassMethodName = TransformationUtil.STATIC_CLASS_FIELD;
                  CtMethod method = methodCall.getMethod();
                  CtClass declaringClass = method.getDeclaringClass();

                  if (!declaringClass
                      .getName()
                      .replace('/', '.')
                      .equals(where.getDeclaringClass().getName().replace('/', '.'))) {
                    declaringClassMethodName = addCalleeMethodDeclaringClassField(ctClass, method);
                  }

                  // call the wrapper method instead of the callee method
                  StringBuffer body = new StringBuffer();
                  StringBuffer callBody = new StringBuffer();

                  callBody.append(TransformationUtil.JOIN_POINT_MANAGER_FIELD);
                  callBody.append('.');
                  callBody.append(TransformationUtil.PROCEED_WITH_CALL_JOIN_POINT_METHOD);
                  callBody.append('(');
                  callBody.append(TransformationUtil.calculateHash(method));
                  callBody.append(',');
                  callBody.append(m_joinPointIndex);
                  callBody.append(", args");
                  callBody.append(", $0, declaringClassMethodName, ");
                  callBody.append(TransformationUtil.JOIN_POINT_TYPE_METHOD_CALL);
                  callBody.append(");");

                  body.append('{');

                  if (method.getParameterTypes().length > 0) {
                    body.append("Object[] args = $args; ");
                  } else {
                    body.append("Object[] args = null; ");
                  }

                  body.append("Class declaringClassMethodName = ");
                  body.append(declaringClassMethodName);
                  body.append("; ");

                  if (methodCall.getMethod().getReturnType() == CtClass.voidType) {
                    body.append("$_ = ").append(callBody.toString()).append("}");
                  } else if (!methodCall.getMethod().getReturnType().isPrimitive()) {
                    body.append("$_ = ($r)");
                    body.append(callBody.toString());
                    body.append("}");
                  } else {
                    String localResult = TransformationUtil.ASPECTWERKZ_PREFIX + "res";

                    body.append("Object ").append(localResult).append(" = ");
                    body.append(callBody.toString());
                    body.append("if (").append(localResult).append(" != null)");
                    body.append("$_ = ($r) ").append(localResult).append("; else ");
                    body.append("$_ = ");
                    body.append(
                        JavassistHelper.getDefaultPrimitiveValue(
                            methodCall.getMethod().getReturnType()));
                    body.append("; }");
                  }

                  methodCall.replace(body.toString());
                  context.markAsAdvised();

                  m_joinPointIndex++;
                }
              } catch (NotFoundException nfe) {
                nfe.printStackTrace();

                // TODO: should we swallow this exception?
              }
            }
          });
    }

    TransformationUtil.setJoinPointIndex(klass.getCtClass(), m_joinPointIndex);
  }
Ejemplo n.º 4
0
 public void onLoad(ClassPool pool, String cname)
     throws NotFoundException, CannotCompileException {
   System.out.println("Dissecting class " + cname);
   CtClass clas = pool.get(cname);
   clas.instrument(new VerboseEditor());
 }