/**
   * Recursively registers all return types to be accessible, down to the java.lang.Class. By
   * calling this function you ensure a) that all returned objects are accessible from JavaScript,
   * no matter how nested they are and b) memory leaks.
   *
   * @param brdge
   * @param reg
   * @param start
   */
  private static void registerCallableRecursively(
      JSONRPCBridge brdge, Collection<Class<?>> reg, Class<?> start, int levelOfRecursion) {

    if (levelOfRecursion == 0) return;

    try {

      Collection<Class<?>> allRelatedClasses = getAllRelatedClasses(start);
      // = start.getDeclaredClasses();
      // Method[] methods = start.getMethods();
      // for (Method method : methods) {
      for (Class<?> returnType : allRelatedClasses) {
        // Class<?> returnType = method.getReturnType();

        if (reg.contains(returnType)) continue;

        // I think these classes are already serialized by JSON, so don't make them accessible.
        if (returnType.equals(String.class)) continue;
        if (returnType.equals(Void.class)) continue;
        if (returnType.equals(Float.class)) continue;
        if (returnType.equals(Double.class)) continue;
        if (returnType.equals(Integer.class)) continue;
        if (returnType.equals(ArrayList.class)) continue;
        if (returnType.equals(Array.class)) continue;

        reg.add(returnType);
        brdge.registerCallableReference(returnType);

        registerCallableRecursively(brdge, reg, returnType, levelOfRecursion - 1);
      }
    } catch (Exception e1) {
      e1.printStackTrace();
    }
  }
 /** Convert a collection of ConstantSets to the format expected by GenTest.addClassLiterals. */
 public static MultiMap<Class<?>, PrimitiveOrStringOrNullDecl> toMap(
     Collection<ConstantSet> constantSets) {
   final MultiMap<Class<?>, PrimitiveOrStringOrNullDecl> map =
       new MultiMap<Class<?>, PrimitiveOrStringOrNullDecl>();
   for (ConstantSet cs : constantSets) {
     Class<?> clazz;
     try {
       clazz = Class.forName(cs.classname);
     } catch (ClassNotFoundException e) {
       throw new Error("Class " + cs.classname + " not found on the classpath.");
     }
     for (Integer x : cs.ints) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(int.class, x.intValue()));
     }
     for (Long x : cs.longs) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(long.class, x.longValue()));
     }
     for (Float x : cs.floats) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(float.class, x.floatValue()));
     }
     for (Double x : cs.doubles) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(double.class, x.doubleValue()));
     }
     for (String x : cs.strings) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(String.class, x));
     }
     for (Class<?> x : cs.classes) {
       map.add(clazz, new PrimitiveOrStringOrNullDecl(Class.class, x));
     }
   }
   return map;
 }
Beispiel #3
0
  public static void premain(String args, Instrumentation inst) throws Exception {
    try {
      String[] agentArgs;
      if (args == null) agentArgs = new String[] {""};
      else agentArgs = args.split(",");
      if (!agentArgs[0].equals("instrumenting")) jarFileName = agentArgs[0];
      BaseClassTransformer rct = null;
      rct = new BaseClassTransformer();
      if (agentArgs[0].equals("instrumenting")) {
        initVMClasses = new HashSet<String>();
        for (Class<?> c : inst.getAllLoadedClasses()) {
          ((Set<String>) initVMClasses).add(c.getName());
        }
      }
      if (!agentArgs[0].equals("instrumenting")) {

        inst.addTransformer(rct);
        Tracer.setLocals(new CounterThreadLocal());
        Tracer.overrideAll(true);
        for (Class<?> c : inst.getAllLoadedClasses()) {
          try {
            if (c.isInterface()) continue;
            if (c.isArray()) continue;
            byte[] bytes = rct.getBytes(c.getName());
            if (bytes == null) {
              continue;
            }
            inst.redefineClasses(new ClassDefinition[] {new ClassDefinition(c, bytes)});
          } catch (Throwable e) {
            synchronized (System.err) {
              System.err.println("" + c + " failed...");
              e.printStackTrace();
            }
          }
        }
        Runtime.getRuntime()
            .addShutdownHook(
                new Thread() {
                  public void run() {
                    Tracer.mark();
                    try {
                      PrintStream ps = new PrintStream("bailout.txt");
                      ps.println("Bailouts: " + Tracer.getBailoutCount());
                      ps.close();
                    } catch (Exception e) {
                    }
                    Tracer.unmark();
                  }
                });
        if ("true".equals(System.getProperty("bci.observerOn"))) Tracer.overrideAll(false);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * Returns all related classes
   *
   * @param start
   * @return
   */
  private static Collection<Class<?>> getAllRelatedClasses(Class<?> start) {

    List<Class<?>> rval = new ArrayList<Class<?>>();
    JavaClass lookupClass;

    // In case the class fails, return empty.
    try {
      lookupClass = Repository.lookupClass(start);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
      return rval;
    }

    ConstantPool constantPool = lookupClass.getConstantPool();

    int length = constantPool.getLength();
    for (int i = 0; i < length; i++) {
      Constant constant = constantPool.getConstant(i);
      if (constant instanceof ConstantClass) {
        ConstantClass cc = (ConstantClass) constant;
        ConstantUtf8 constant2 = (ConstantUtf8) constantPool.getConstant(cc.getNameIndex());

        // In case a subclass fails, skip, but print warning.
        try {
          String toLoad = constant2.getBytes().replace('/', '.');
          if (toLoad.contains("[")) continue;
          Class<?> forName = Class.forName(toLoad);
          rval.add(forName);
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
      }
    }

    return rval;
  }