예제 #1
0
  private static void inheritAnnotations(final CtClass theClass, final CtMethod theMethod)
      throws NotFoundException {
    if (hasMethod(theClass, theMethod)) {
      CtMethod aOtherMethod = theClass.getMethod(theMethod.getName(), theMethod.getSignature());
      // method we're probably overriding or implementing in the case of an abstract method.

      AnnotationsAttribute annotationsAttribute =
          (AnnotationsAttribute)
              aOtherMethod.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag);

      if (annotationsAttribute != null) {
        ConstPool cp = theClass.getClassFile().getConstPool();
        AnnotationsAttribute attr = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);

        for (Object obj : annotationsAttribute.getAnnotations()) {

          Annotation a = (Annotation) obj;

          Annotation theAnnotation = new Annotation(a.getTypeName(), cp);

          if (a.getMemberNames() != null) {
            for (Object aName : a.getMemberNames()) {
              theAnnotation.addMemberValue(aName.toString(), a.getMemberValue(aName.toString()));
            }
          }

          attr.setAnnotation(theAnnotation);
        }
        theMethod.getMethodInfo().addAttribute(attr);
      }
    }
  }
예제 #2
0
  /**
   * Similar to main method but is not static
   *
   * @param args command line parameters
   * @throws Exception if something fails during the execution
   */
  public void doIt2(String[] args) throws Exception {

    // Se carga la clase para la que se quiere modificar sus bytecodes
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.jzb.ja.Clase1");

    // Se puede iterar imprimiendo los metodos, y su signatura, contenidos en la clase
    for (CtMethod mm : cc.getMethods()) {
      System.out.println(mm.getName() + " " + mm.getMethodInfo().getDescriptor());
    }

    // Se puede buscar un metodo en concreto...
    CtMethod mr = cc.getMethod("diHola", "(Ljava/lang/String;)Ljava/lang/String;");
    // ... Borrarlo...
    cc.removeMethod(mr);
    // .. Y volver a escribir su .class moficado en una carpeta raiz
    cc.writeFile("c:\\tmp");

    // Posteriormente, tanto por este codigo de creación dinamica, o porque se usa
    // el fichero .class generado antes, se obtiene un error de "Metodo No Existe"
    Class c1 = cc.toClass();
    Clase1 o1 = (Clase1) c1.newInstance();
    System.out.println(o1.sumaUno(2));
    System.out.println(o1.diHola("Pepe"));
  }
예제 #3
0
 /*  66:    */
 /*  67:    */ private boolean matchClass(String name, ClassPool pool) /*  68:    */ {
   /*  69: 84 */ if (this.classname.equals(name)) {
     /*  70: 85 */ return true;
     /*  71:    */ }
   /*  72:    */ try
   /*  73:    */ {
     /*  74: 88 */ CtClass clazz = pool.get(name);
     /*  75: 89 */ CtClass declClazz = pool.get(this.classname);
     /*  76: 90 */ if (clazz.subtypeOf(declClazz)) {
       /*  77:    */ try
       /*  78:    */ {
         /*  79: 92 */ CtMethod m = clazz.getMethod(this.methodname, this.methodDescriptor);
         /*  80: 93 */ return m.getDeclaringClass().getName().equals(this.classname);
         /*  81:    */ }
       /*  82:    */ catch (NotFoundException e)
       /*  83:    */ {
         /*  84: 97 */ return true;
         /*  85:    */ }
       /*  86:    */ }
     /*  87:    */ }
   /*  88:    */ catch (NotFoundException e)
   /*  89:    */ {
     /*  90:101 */ return false;
     /*  91:    */ }
   /*  92:104 */ return false;
   /*  93:    */ }
예제 #4
0
 private static boolean hasMethod(final CtClass theClass, final CtMethod theMethod) {
   try {
     return theClass.getMethod(theMethod.getName(), theMethod.getSignature()) != null;
   } catch (NotFoundException e) {
     return false;
   }
 }
 @Test
 public void testSetter() throws Exception {
   CtClass mock = new WicketMockClassFactory(Date.class).getMock();
   assertNotNull(
       mock.getMethod(
           "setSeconds",
           Descriptor.ofMethod(
               voidType, new CtClass[] {ClassPool.getDefault().get(Object.class.getName())})));
 }
예제 #6
0
  private void initExtraHarvest() {
    try {
      CtClass terraForming =
          HookManager.getInstance()
              .getClassPool()
              .get("com.wurmonline.server.behaviours.Terraforming");

      CtClass[] paramTypes = {
        HookManager.getInstance().getClassPool().get("com.wurmonline.server.creatures.Creature"),
        CtPrimitiveType.intType,
        CtPrimitiveType.intType,
        CtPrimitiveType.booleanType,
        CtPrimitiveType.intType,
        CtPrimitiveType.floatType,
        HookManager.getInstance().getClassPool().get("com.wurmonline.server.items.Item")
      };

      CtMethod method =
          terraForming.getMethod(
              "harvest", Descriptor.ofMethod(CtPrimitiveType.booleanType, paramTypes));
      MethodInfo methodInfo = method.getMethodInfo();
      CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
      CodeIterator codeIterator = codeAttribute.iterator();

      LocalVariableAttribute attr =
          (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
      int quantityIndex = -1;
      for (int i = 0; i < attr.tableLength(); i++) {
        if ("quantity".equals(attr.variableName(i))) {
          quantityIndex = attr.index(i);
        }
      }

      if (quantityIndex == -1) {
        throw new HookException("Quantity variable can not be resolved");
      }

      while (codeIterator.hasNext()) {
        int pos = codeIterator.next();
        int op = codeIterator.byteAt(pos);
        if (op == CodeIterator.ISTORE) {
          int fieldRefIdx = codeIterator.byteAt(pos + 1);
          if (quantityIndex == fieldRefIdx) {
            Bytecode bytecode = new Bytecode(codeIterator.get().getConstPool());
            bytecode.addIconst(extraHarvest);
            bytecode.add(Bytecode.IADD);
            codeIterator.insertAt(pos, bytecode.get());
            break;
          }
        }
      }
    } catch (NotFoundException | BadBytecode e) {
      throw new HookException(e);
    }
  }
예제 #7
0
  @Override
  public void compile(HookCompiler compiler, CtClass c, Side side)
      throws NotFoundException, CannotCompileException {

    compiler.replaceDouble(
        c.getMethod("tick", "()V"),
        -64,
        EntryFactory.getClassEntry(getClass()),
        "getOutOfWorldDepth",
        "this");
  }
 @Test(expected = NotFoundException.class)
 public void testFinalField() throws Exception {
   CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock();
   mock.getMethod("setField", Descriptor.ofMethod(voidType, new CtClass[] {intType}));
 }
 @Test(expected = Test.None.class)
 public void testField() throws Exception {
   CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock();
   mock.getMethod("getNonFinalField", Descriptor.ofMethod(OBJECT_CLASS, new CtClass[] {}));
   mock.getMethod("setNonFinalField", Descriptor.ofMethod(voidType, new CtClass[] {intType}));
 }
      private URL computeResourceURL(Method method) throws NotFoundException, URISyntaxException {
        List<ResourceFileEntry> filesSimpleNames = new ArrayList<ResourceFileEntry>();
        boolean computeExtensions = false;
        CtMethod m = ctClass.getMethod(method.getName(), getDescriptor(method));
        MethodInfo minfo = m.getMethodInfo2();
        AnnotationsAttribute attr =
            (AnnotationsAttribute) minfo.getAttribute(AnnotationsAttribute.invisibleTag);
        if (attr != null) {
          Annotation an = attr.getAnnotation(Source.class.getName());
          if (an != null) {
            MemberValue[] mvArray = ((ArrayMemberValue) an.getMemberValue("value")).getValue();
            if (mvArray != null) {
              for (MemberValue mv : mvArray) {
                StringMemberValue smv = (StringMemberValue) mv;
                filesSimpleNames.add(new ResourceFileEntry(smv.getValue(), m));
              }
            }
          }
        }

        if (filesSimpleNames.isEmpty()) {
          // no @Source annotation detected
          filesSimpleNames.add(new ResourceFileEntry(method.getName(), m));
          computeExtensions = true;
        }

        List<URL> existingFiles = new ArrayList<URL>();

        for (ResourceFileEntry resourceEntry : filesSimpleNames) {
          String resourceName = resourceEntry.resourceName;
          CtClass declaringClass = resourceEntry.resourceMethod.getDeclaringClass();
          String baseDir = declaringClass.getPackageName().replaceAll("\\.", "/") + "/";
          String fileName =
              (resourceName.startsWith(baseDir)) ? resourceName : baseDir + resourceName;

          if (computeExtensions) {
            String[] extensions = getResourceDefaultExtensions(method);

            for (String extension : extensions) {
              String possibleFile = fileName + extension;
              URL url = GwtPatcher.class.getClassLoader().getResource(possibleFile);
              if (url != null) {
                existingFiles.add(url);
              }
            }
          } else {
            URL url = GwtPatcher.class.getClassLoader().getResource(fileName);
            if (url != null) {
              existingFiles.add(url);
            }
          }
        }

        if (existingFiles.isEmpty()) {
          throw new RuntimeException(
              "No resource file found for method "
                  + ctClass.getSimpleName()
                  + "."
                  + method.getName()
                  + "()");
        } else if (existingFiles.size() > 1) {
          throw new RuntimeException(
              "Too many resource files found for method "
                  + ctClass.getSimpleName()
                  + "."
                  + method.getName()
                  + "()");
        }

        return existingFiles.get(0);
      }
예제 #11
0
  //    @Deprecated
  //    @Test
  public void interceptor()
      throws NotFoundException, CannotCompileException, IllegalAccessException,
          InstantiationException, IOException, ClassNotFoundException, NoSuchMethodException {
    AroundInterceptor aroundInterceptor =
        new AroundInterceptor() {

          @Override
          public void before(Object target, Object[] args) {
            logger.info("BEFORE target:" + target + " args:" + Arrays.toString(args));
          }

          @Override
          public void after(Object target, Object[] args, Object result, Throwable throwable) {
            logger.info(
                "AFTER target: "
                    + target
                    + " args:"
                    + Arrays.toString(args)
                    + " result:"
                    + result
                    + " throwable:"
                    + throwable);
          }
        };
    int interceptorId = INTERCEPTOR_REGISTRY_ADAPTOR.addInterceptor(aroundInterceptor);

    final ClassPool classPool = new ClassPool(true);
    CtClass throwable = classPool.get(Throwable.class.getName());

    CtClass ctClass = classPool.get("com.baidu.oped.apm.profiler.interceptor.JavaAssistTestObject");

    final CtMethod hello = ctClass.getMethod("hello", "(Ljava/lang/String;)Ljava/lang/String;");
    logger.debug("longName:{}", hello.getLongName());
    logger.debug("name:{}", hello.getName());

    String interceptorClassName = AroundInterceptor.class.getName();
    CtClass interceptor = classPool.get(interceptorClassName);
    hello.addLocalVariable("interceptor", interceptor);

    CtClass object = classPool.get(Object.class.getName());
    hello.addLocalVariable("result", object);

    //        hello.insertBefore("{ System.out.println(\"BEFORE\"); }");
    hello.insertBefore(
        "{"
            + "interceptor = ("
            + interceptorClassName
            + ") "
            + InterceptorRegistry.class.getName()
            + ".getSimpleInterceptor("
            + interceptorId
            + ");"
            + "interceptor.before(this, $args);"
            + "}");
    //        hello.addCatch("{" +
    ////            " interceptor.after(ctx);"+
    ////           " AroundInterceptor a = (AroundInterceptor) " +
    // InterceptorRegistry.class.getName() + ".getStaticInterceptor(\"a\");"+
    //                " throw $e;" +
    //                "}", throwable);
    //        hello.insertAfter("{" +
    //                "interceptor.after(this,  $args, ($w)$_, null); " +
    //                "}");

    //       hello.setBody(generatedAroundInterceptor("TestObject", "hello"));
    //       hello.setBody("{ System.out.println(\"ddd\");  }", ClassMap map );
    //       hello.insertBefore(" System.out.println(\" BEFORE +  \");");
    //       hello.insertAfter(" System.out.println($_);");
    //       hello.insertAfter(" System.out.println($r);");
    //       hello.insertAfter(" System.out.println($w);");
    //       hello.insertAfter(" System.out.println($sig);");
    //       hello.insertAfter(" System.out.println($type);");
    //       hello.insertAfter(" System.out.println($class);");
    //       hello.instrument(new ExprEditor() {
    //         public void edit(MethodCall m)
    //         throws CannotCompileException
    //         {
    //             try {
    //                 System.out.println("method call" + m.getMethod().getName());
    //             } catch (NotFoundException e) {
    //                 e.printStackTrace();  //To change body of catch statement use File | Settings
    // | File Templates.
    //             }
    //             String code = generatedAroundInterceptor("TestObject", "hello");
    //             m.replace(code);
    //         }

    //         });
    //        hello.addCatch("System.out.println(\"catch\"); throw $e;", throwable);

    //       hello.setName("__hello");
    //       CtMethod method = CtNewMethod.make("public void hello() { try {__hello(); }
    // catch(Throwable th){throw th;}}", ctClass);

    //         CtMethod method = CtNewMethod.make("public void hello() {
    // System.out.println(\"ddd\"); } catch(Throwable th){throw th;}}", ctClass);
    //       ctClass.addMethod(method);

    //        ctClass.freeze();
    //       ctClass.writeFile("./debug");
    //       ctClass.debugWriteFile("./debug");
    Loader loader = LoaderUtils.createLoader(classPool);
    loader.delegateLoadingOf("com.baidu.oped.apm.bootstrap.");

    Class aClass = loader.loadClass(ctClass.getName());
    Object testObject = aClass.newInstance();

    Method helloMethod = testObject.getClass().getDeclaredMethod("hello", String.class);

    try {
      helloMethod.invoke(testObject, "hello~~");
    } catch (Exception e) {
      Assert.fail(e.getMessage());
    }

    //       o.hello();
  }
  /** Generate Javassist Proxy Classes */
  private static <T> void generateProxyClass(
      Class<T> primaryInterface, String superClassName, String methodBody) throws Exception {
    String newClassName = superClassName.replaceAll("(.+)\\.(\\w+)", "$1.Hikari$2");

    CtClass superCt = classPool.getCtClass(superClassName);
    CtClass targetCt = classPool.makeClass(newClassName, superCt);
    targetCt.setModifiers(Modifier.FINAL);

    System.out.println("Generating " + newClassName);

    targetCt.setModifiers(Modifier.PUBLIC);

    // Make a set of method signatures we inherit implementation for, so we don't generate delegates
    // for these
    Set<String> superSigs = new HashSet<>();
    for (CtMethod method : superCt.getMethods()) {
      if ((method.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
        superSigs.add(method.getName() + method.getSignature());
      }
    }

    Set<String> methods = new HashSet<>();
    Set<Class<?>> interfaces = getAllInterfaces(primaryInterface);
    for (Class<?> intf : interfaces) {
      CtClass intfCt = classPool.getCtClass(intf.getName());
      targetCt.addInterface(intfCt);
      for (CtMethod intfMethod : intfCt.getDeclaredMethods()) {
        final String signature = intfMethod.getName() + intfMethod.getSignature();

        // don't generate delegates for methods we override
        if (superSigs.contains(signature)) {
          continue;
        }

        // Ignore already added methods that come from other interfaces
        if (methods.contains(signature)) {
          continue;
        }

        // Ignore default methods (only for Jre8 or later)
        if (isDefaultMethod(intf, intfCt, intfMethod)) {
          continue;
        }

        // Track what methods we've added
        methods.add(signature);

        // Clone the method we want to inject into
        CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null);

        String modifiedBody = methodBody;

        // If the super-Proxy has concrete methods (non-abstract), transform the call into a simple
        // super.method() call
        CtMethod superMethod = superCt.getMethod(intfMethod.getName(), intfMethod.getSignature());
        if ((superMethod.getModifiers() & Modifier.ABSTRACT) != Modifier.ABSTRACT) {
          modifiedBody = modifiedBody.replace("((cast) ", "");
          modifiedBody = modifiedBody.replace("delegate", "super");
          modifiedBody = modifiedBody.replace("super)", "super");
        }

        modifiedBody = modifiedBody.replace("cast", primaryInterface.getName());

        // Generate a method that simply invokes the same method on the delegate
        if (isThrowsSqlException(intfMethod)) {
          modifiedBody = modifiedBody.replace("method", method.getName());
        } else {
          modifiedBody =
              "{ return ((cast) delegate).method($$); }"
                  .replace("method", method.getName())
                  .replace("cast", primaryInterface.getName());
        }

        if (method.getReturnType() == CtClass.voidType) {
          modifiedBody = modifiedBody.replace("return", "");
        }

        method.setBody(modifiedBody);
        targetCt.addMethod(method);
      }
    }

    targetCt.writeFile("target/classes");
  }