Пример #1
0
 public static void premain(Instrumentation instrumentation, @Nullable File glowrootJarFile) {
   boolean jbossModules = AppServerDetection.isJBossModules();
   if (jbossModules) {
     String jbossModulesSystemPkgs = System.getProperty("jboss.modules.system.pkgs");
     if (Strings.isNullOrEmpty(jbossModulesSystemPkgs)) {
       jbossModulesSystemPkgs = "org.glowroot.agent";
     } else {
       jbossModulesSystemPkgs += ",org.glowroot.agent";
     }
     System.setProperty("jboss.modules.system.pkgs", jbossModulesSystemPkgs);
   }
   String baseDirPath = System.getProperty("glowroot.base.dir");
   File baseDir = BaseDir.getBaseDir(baseDirPath, glowrootJarFile);
   // init logger as early as possible
   instrumentation.addTransformer(new LogbackPatch());
   initLogging(baseDir);
   try {
     ImmutableMap<String, String> properties = getGlowrootProperties(baseDir);
     start(baseDir, properties, instrumentation, glowrootJarFile);
   } catch (BaseDirLockedException e) {
     logBaseDirLockedException(baseDir);
   } catch (Throwable t) {
     // log error but don't re-throw which would prevent monitored app from starting
     startupLogger.error("Glowroot not started: {}", t.getMessage(), t);
   }
 }
Пример #2
0
  public static void premain(String agentArgs, Instrumentation inst) throws FileNotFoundException {
    Config config = Config.readFromFile(Config.DEFAULT_FILE_CONFIG_LOCATION);
    globalInst = inst;

    inst.addTransformer(new BasicClassFileTransformer(config));

    ResourceMonitor rm = config.getResourceMonitor();
    if (rm.isActive() && hardwareThread == null) {
      //            installGCMonitoring();
      List<HardwareDaemonWriter> writers = new ArrayList<HardwareDaemonWriter>();

      if (rm.isDebug()) {
        System.out.println("use debug");
        writers.add(new HardwareDaemonWriterMockImpl());
      } else {
        System.out.println("not using debug");
      }
      if (rm.isSendToCollector())
        try {
          writers.add(new HardwareDaemonWriterCollectorImpl(config));
        } catch (IOException e) {
          e.printStackTrace();
        }
      hardwareThread = new HardwareDaemon(config, writers);
      hardwareThread.start();
    }
  }
Пример #3
0
  @SuppressWarnings("unused")
  public static void premain(String args, Instrumentation inst) {
    boolean verbose = false;
    if (args != null) {
      if (args.contains("verbose")) {
        verbose = true;
      }
    }
    inst.addTransformer(new FileStreamInstrumentationTransformer(verbose), true);
    System.out.println("OrcAgent is registered.");

    if (!inst.isRetransformClassesSupported()) {
      System.err.println("WARNING: JVM does not support class retransformation.");
    } else {
      try {
        inst.retransformClasses(FileInputStream.class, FileOutputStream.class);
      } catch (UnmodifiableClassException e) {
        System.err.println("Unable to modify FileStream classes.");
        e.printStackTrace();
      }
    }

    Runtime.getRuntime()
        .addShutdownHook(
            new Thread(
                new Runnable() {
                  public void run() {
                    System.err.println();
                    System.err.println(FileStreamStatistics.asString());
                  }
                }));
  }
Пример #4
0
  private void instrumentApplication() throws FileNotFoundException, UnmodifiableClassException {
    if (!instrumentation.isRetransformClassesSupported()) {
      throw new UnmodifiableClassException();
    }

    instrumentation.addTransformer(this, true);

    for (Class<?> c : instrumentation.getAllLoadedClasses()) {
      if (isInstrumentClass(c)) {
        if (configuration.isAsyncTransformation()) {
          try {
            blockingQueue.put(c);
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            break;
          }
        } else {
          try {
            instrumentation.retransformClasses(new Class[] {c});
          } catch (Throwable e) {
            LOG.error("Could not transform " + c.getName(), e);
          }
        }
      }
    }
    if (configuration.isAsyncTransformation() && !blockingQueue.isEmpty()) {
      startTransformThread();
    }
  }
Пример #5
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();
    }
  }
Пример #6
0
  public static void premain(String args, Instrumentation inst) {
    ClassFileTransformer transformer = new ContractClassFileTransformer();

    String dumpDir = System.getProperty("com.google.java.contract.dump");
    if (dumpDir != null) {
      transformer = new DumpClassFileTransformer(transformer, dumpDir);
    }

    inst.addTransformer(transformer);

    configure();
  }
Пример #7
0
 public static void agentmain(@SuppressWarnings("unused") String args, Instrumentation inst)
     throws Exception {
   if (inst.isRedefineClassesSupported() && inst.isRetransformClassesSupported()) {
     inst.addTransformer(new FooTransformer(), true);
     Class<?>[] allClasses = inst.getAllLoadedClasses();
     for (int i = 0; i < allClasses.length; i++) {
       Class<?> c = allClasses[i];
       if (c == Foo.class) {
         inst.retransformClasses(new Class<?>[] {c});
       }
     }
   }
 }
Пример #8
0
 private void transform(Pattern pattern, List<Class<?>> classes, File dir) {
   ClassDumpTransformer transformer = new ClassDumpTransformer(pattern, dir);
   instrumentation.addTransformer(transformer, true);
   try {
     for (Class<?> clazz : classes) {
       try {
         instrumentation.retransformClasses(clazz);
       } catch (UnmodifiableClassException e) {
         log.log(Level.WARNING, "Unexpected error", e);
       }
     }
   } finally {
     instrumentation.removeTransformer(transformer);
   }
 }
Пример #9
0
  public static void premain(final String agentArgument, final Instrumentation instrumentation)
      throws IOException, SAXException, ParserConfigurationException {

    if (null == agentArgument) {
      System.err.println("Missing javaagent argument!");
      System.exit(1);
    }

    Log.setFile(agentArgument.replace(".xml", "." + System.currentTimeMillis()));

    final Document document = XmlUtil.loadDocument(agentArgument);

    final AbstractMonkeyPatcher parse = parseTransformer(document);
    instrumentation.addTransformer(parse);
  }
Пример #10
0
  public static void premain(final String agentArgs, Instrumentation instrumentation)
      throws InstantiationException {
    counter++;
    final String callbackId = String.valueOf(counter);
    try {
      if (agentArgs == null) {
        throw new IllegalArgumentException(
            "Agent argument is required of the form 'interceptor-class-name[;interceptor-custom-args]'");
      }
      String[] tokens = agentArgs.split(";", 2);
      Class<?> clazz = Agent.class.getClassLoader().loadClass(tokens[0]);
      final Interceptor interceptor = (Interceptor) clazz.newInstance();
      if (tokens.length == 2) {
        interceptor.init(tokens[1]);
      } else {
        interceptor.init(null);
      }
      Callback.registerCallback(callbackId, interceptor);
      instrumentation.addTransformer(
          new ClassFileTransformer() {
            public byte[] transform(
                final ClassLoader loader,
                final String className,
                final Class<?> classBeingRedefined,
                final ProtectionDomain protectionDomain,
                final byte[] classfileBuffer)
                throws IllegalClassFormatException {

              if (!isAncestor(Agent.class.getClassLoader(), loader)) {
                return classfileBuffer;
              }
              return AccessController.doPrivileged(
                  new PrivilegedAction<byte[]>() {
                    public byte[] run() {
                      Instrumentator instrumentator =
                          new Instrumentator(className, classfileBuffer, interceptor, callbackId);
                      return instrumentator.modifyClass();
                    }
                  });
            }
          });
    } catch (Throwable th) {
      th.printStackTrace(System.err);
    }
  }
Пример #11
0
  /**
   * Allows the installation of the agent via the -javaagent command line argument
   *
   * @param agentArgs the agent arguments
   * @param inst the instrumentation
   */
  public static void premain(String agentArgs, final Instrumentation inst) {
    System.setProperty(INITIALIZED_VIA_JAVAAGENT, Boolean.TRUE.toString());
    inst.addTransformer(
        new ClassFileTransformer() {

          @Override
          public byte[] transform(
              ClassLoader loader,
              String className,
              Class<?> classBeingRedefined,
              ProtectionDomain protectionDomain,
              byte[] classfileBuffer)
              throws IllegalClassFormatException {
            if (loader == null) {
              return classfileBuffer;
            }
            if (!initialized) {
              initClassFileTransformer(loader);
            }
            return classfileBuffer;
          }

          @SuppressWarnings("unchecked")
          private void initClassFileTransformer(ClassLoader loader) {
            try {
              final ClassFileTransformer mainStagemonitorClassFileTransformer =
                  getMainStagemonitorClassFileTransformer(loader, inst);
              inst.addTransformer(mainStagemonitorClassFileTransformer, true);
              initialized = true;
              // loader could load MainStagemonitorClassFileTransformer - this is the application
              // class loader
            } catch (Exception e) {
              // ignore; this is probably not the application class loader
            }
          }
        });
  }
Пример #12
0
 public static void premain(String options, Instrumentation ins) {
   ins.addTransformer(new LJApp("init"));
   ins.addTransformer(new LJApp("work"));
   ins.addTransformer(new LJApp("clearup"));
 }
  /**
   * INTERNAL predeploy (with deploy) is one of the two steps required in deployment of entities
   * This method will prepare to call predeploy, call it and finally register the transformer
   * returned to be used for weaving.
   */
  protected boolean callPredeploy(
      SEPersistenceUnitInfo persistenceUnitInfo,
      Map m,
      PersistenceInitializationActivator persistenceActivator) {
    ClassLoader tempLoader = null;
    // we will only attempt to deploy when TopLink is specified as the provider or the provider is
    // unspecified
    String providerClassName = persistenceUnitInfo.getPersistenceProviderClassName();
    if (persistenceActivator.isPersistenceProviderSupported(providerClassName)) {
      EntityManagerSetupImpl emSetupImpl =
          EntityManagerFactoryProvider.getEntityManagerSetupImpl(
              persistenceUnitInfo.getPersistenceUnitRootUrl()
                  + persistenceUnitInfo.getPersistenceUnitName());

      // if we already have an EntityManagerSetupImpl this PU has already been processed.  Use the
      // existing one
      if (emSetupImpl != null && !emSetupImpl.isUndeployed()) {
        return false;
      }
      Set tempLoaderSet =
          PersistenceUnitProcessor.buildClassSet(
              persistenceUnitInfo, Thread.currentThread().getContextClassLoader());

      Map mergedProperties =
          EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties());

      String weaving =
          EntityManagerFactoryProvider.getConfigPropertyAsString(
              TopLinkProperties.WEAVING, mergedProperties, null);
      // Bug#4452468  When globalInstrumentation is null, there is no weaving
      if (globalInstrumentation == null) {
        if (weaving == null) {
          mergedProperties.put(TopLinkProperties.WEAVING, "false");
          weaving = "false";
        } else if (weaving.equalsIgnoreCase("true")) {
          throw new PersistenceException(EntityManagerSetupException.wrongWeavingPropertyValue());
        }
      }

      // Bug#2741: If weaving disabled then use regular loader, not a temp one
      if (weaving != null
          && (weaving.equalsIgnoreCase("false") || weaving.equalsIgnoreCase("static"))) {
        shouldCreateInternalLoader = false;
      }
      // Create the temp loader that will not cache classes for entities in our persistence unit
      tempLoader = createTempLoader(tempLoaderSet);
      persistenceUnitInfo.setNewTempClassLoader(tempLoader);
      persistenceUnitInfo.setClassLoader(getMainLoader());
      if (emSetupImpl == null) {
        emSetupImpl = new EntityManagerSetupImpl();
        EntityManagerFactoryProvider.addEntityManagerSetupImpl(
            persistenceUnitInfo.getPersistenceUnitRootUrl()
                + persistenceUnitInfo.getPersistenceUnitName(),
            emSetupImpl);
      }
      // Make the callback
      AbstractSessionLog.getLog()
          .log(
              SessionLog.FINER,
              "cmp_init_invoke_predeploy",
              persistenceUnitInfo.getPersistenceUnitName());

      // A call to predeploy will partially build the session we will use
      final ClassTransformer transformer =
          emSetupImpl.predeploy(persistenceUnitInfo, mergedProperties);

      // If we got a transformer then register it
      if ((transformer != null) && (globalInstrumentation != null)) {
        AbstractSessionLog.getLog()
            .log(
                SessionLog.FINER,
                "cmp_init_register_transformer",
                persistenceUnitInfo.getPersistenceUnitName());
        globalInstrumentation.addTransformer(
            new ClassFileTransformer() {
              // adapt ClassTransformer to ClassFileTransformer interface
              public byte[] transform(
                  ClassLoader loader,
                  String className,
                  Class<?> classBeingRedefined,
                  ProtectionDomain protectionDomain,
                  byte[] classfileBuffer)
                  throws IllegalClassFormatException {
                return transformer.transform(
                    loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
              }
            });
      } else if (transformer == null) {
        AbstractSessionLog.getLog().log(SessionLog.FINER, "cmp_init_transformer_is_null");
      } else if (globalInstrumentation == null) {
        AbstractSessionLog.getLog().log(SessionLog.FINER, "cmp_init_globalInstrumentation_is_null");
      }
      return true;
    }
    return false;
  }
Пример #14
0
  public static void premain(String agentArgs, Instrumentation inst) {

    // registers the transformer
    inst.addTransformer(new Transformer());
  }
Пример #15
0
  public DefaultAgent(
      String agentPath,
      String agentArgs,
      Instrumentation instrumentation,
      ProfilerConfig profilerConfig) {
    if (agentPath == null) {
      throw new NullPointerException("agentPath must not be null");
    }
    if (instrumentation == null) {
      throw new NullPointerException("instrumentation must not be null");
    }
    if (profilerConfig == null) {
      throw new NullPointerException("profilerConfig must not be null");
    }

    this.binder = new Slf4jLoggerBinder();
    bindPLoggerFactory(this.binder);

    dumpSystemProperties();
    dumpConfig(profilerConfig);

    changeStatus(AgentStatus.INITIALIZING);

    this.agentPath = agentPath;
    this.profilerConfig = profilerConfig;

    final ApplicationServerTypeResolver typeResolver =
        new ApplicationServerTypeResolver(profilerConfig.getApplicationServerType());
    if (!typeResolver.resolve()) {
      throw new PinpointException("ApplicationServerType not found.");
    }
    this.byteCodeInstrumentor = new JavaAssistByteCodeInstrumentor(this);
    if (logger.isInfoEnabled()) {
      logger.info("DefaultAgent classLoader:{}", this.getClass().getClassLoader());
    }

    final AgentInformationFactory agentInformationFactory = new AgentInformationFactory();
    this.agentInformation =
        agentInformationFactory.createAgentInformation(typeResolver.getServerType());
    logger.info("agentInformation:{}", agentInformation);

    CommandDispatcher commandDispatcher = new CommandDispatcher();
    commandDispatcher.registerCommandService(new ThreadDumpService());
    commandDispatcher.registerCommandService(new EchoService());

    this.factory = createPinpointSocketFactory(commandDispatcher);
    this.socket =
        createPinpointSocket(
            this.profilerConfig.getCollectorTcpServerIp(),
            this.profilerConfig.getCollectorTcpServerPort(),
            factory);

    this.serverMetaDataHolder = createServerMetaDataHolder();

    this.tcpDataSender = createTcpDataSender(socket);

    this.spanDataSender =
        createUdpSpanDataSender(
            this.profilerConfig.getCollectorSpanServerPort(),
            "Pinpoint-UdpSpanDataExecutor",
            this.profilerConfig.getSpanDataSenderWriteQueueSize(),
            this.profilerConfig.getSpanDataSenderSocketTimeout(),
            this.profilerConfig.getSpanDataSenderSocketSendBufferSize());
    this.statDataSender =
        createUdpStatDataSender(
            this.profilerConfig.getCollectorStatServerPort(),
            "Pinpoint-UdpStatDataExecutor",
            this.profilerConfig.getStatDataSenderWriteQueueSize(),
            this.profilerConfig.getStatDataSenderSocketTimeout(),
            this.profilerConfig.getStatDataSenderSocketSendBufferSize());

    this.traceContext = createTraceContext(agentInformation.getServerType());

    this.agentInfoSender =
        new AgentInfoSender(
            tcpDataSender,
            profilerConfig.getAgentInfoSendRetryInterval(),
            this.agentInformation,
            this.serverMetaDataHolder);

    this.agentStatMonitor =
        new AgentStatMonitor(
            this.statDataSender,
            this.agentInformation.getAgentId(),
            this.agentInformation.getStartTime());

    ClassFileRetransformer retransformer = new ClassFileRetransformer(instrumentation);
    instrumentation.addTransformer(retransformer, true);
    this.classFileTransformer =
        new ClassFileTransformerDispatcher(this, byteCodeInstrumentor, retransformer);
    instrumentation.addTransformer(this.classFileTransformer);

    preLoadClass();

    /**
     * FIXME In case of Tomcat,
     * com.baidu.oped.apm.profiler.modifier.tomcat.interceptor.CatalinaAwaitInterceptor invokes
     * start() method before entering await() method of org.apache.catalina.startup.Catalina. But
     * for other applications, it must be invoked directly.
     */
    if (typeResolver.isManuallyStartupRequired()) {
      start();
    }
  }
Пример #16
0
 /**
  * Premain method that registers this class as ClassFileTransformer
  *
  * @param args arguments passed to javaagent, ignored
  * @param instrumentation Instrumentation object
  */
 public static void premain(String args, Instrumentation instrumentation) {
   instrumentation.addTransformer(new ObjectCallbackEnhancer(), true);
   instrumentation.addTransformer(new GlobalCallbackEnhancer(), true);
 }
Пример #17
0
 public static void premain(String agentArgs, Instrumentation inst)
     throws IllegalArgumentException, IOException, InvalidClassFileException {
   inst.addTransformer(new OnlineDynamicCallGraph());
 }
Пример #18
0
  public DefaultAgent(
      AgentOption agentOption, final InterceptorRegistryBinder interceptorRegistryBinder) {
    if (agentOption == null) {
      throw new NullPointerException("agentOption must not be null");
    }
    if (agentOption.getInstrumentation() == null) {
      throw new NullPointerException("instrumentation must not be null");
    }
    if (agentOption.getProfilerConfig() == null) {
      throw new NullPointerException("profilerConfig must not be null");
    }
    if (agentOption.getServiceTypeRegistryService() == null) {
      throw new NullPointerException("serviceTypeRegistryService must not be null");
    }

    if (interceptorRegistryBinder == null) {
      throw new NullPointerException("interceptorRegistryBinder must not be null");
    }
    logger.info("AgentOption:{}", agentOption);

    this.binder = new Slf4jLoggerBinder();
    bindPLoggerFactory(this.binder);

    this.interceptorRegistryBinder = interceptorRegistryBinder;
    interceptorRegistryBinder.bind();
    this.serviceTypeRegistryService = agentOption.getServiceTypeRegistryService();

    dumpSystemProperties();
    dumpConfig(agentOption.getProfilerConfig());

    changeStatus(AgentStatus.INITIALIZING);

    this.profilerConfig = agentOption.getProfilerConfig();
    this.instrumentation = agentOption.getInstrumentation();
    this.agentOption = agentOption;
    this.classPool =
        new JavassistClassPool(interceptorRegistryBinder, agentOption.getBootStrapCoreJarPath());

    if (logger.isInfoEnabled()) {
      logger.info("DefaultAgent classLoader:{}", this.getClass().getClassLoader());
    }

    pluginContexts = loadPlugins(agentOption);

    this.classFileTransformer = new ClassFileTransformerDispatcher(this, pluginContexts);
    this.dynamicTransformService =
        new DynamicTransformService(instrumentation, classFileTransformer);

    instrumentation.addTransformer(this.classFileTransformer, true);

    String applicationServerTypeString = profilerConfig.getApplicationServerType();
    ServiceType applicationServerType =
        this.serviceTypeRegistryService.findServiceTypeByName(applicationServerTypeString);

    final ApplicationServerTypeResolver typeResolver =
        new ApplicationServerTypeResolver(
            pluginContexts, applicationServerType, profilerConfig.getApplicationTypeDetectOrder());

    final AgentInformationFactory agentInformationFactory = new AgentInformationFactory();
    this.agentInformation = agentInformationFactory.createAgentInformation(typeResolver.resolve());
    logger.info("agentInformation:{}", agentInformation);

    CommandDispatcher commandDispatcher = new CommandDispatcher();

    this.tcpDataSender = createTcpDataSender(commandDispatcher);

    this.serverMetaDataHolder = createServerMetaDataHolder();

    this.spanDataSender =
        createUdpSpanDataSender(
            this.profilerConfig.getCollectorSpanServerPort(),
            "Pinpoint-UdpSpanDataExecutor",
            this.profilerConfig.getSpanDataSenderWriteQueueSize(),
            this.profilerConfig.getSpanDataSenderSocketTimeout(),
            this.profilerConfig.getSpanDataSenderSocketSendBufferSize());
    this.statDataSender =
        createUdpStatDataSender(
            this.profilerConfig.getCollectorStatServerPort(),
            "Pinpoint-UdpStatDataExecutor",
            this.profilerConfig.getStatDataSenderWriteQueueSize(),
            this.profilerConfig.getStatDataSenderSocketTimeout(),
            this.profilerConfig.getStatDataSenderSocketSendBufferSize());

    this.traceContext = createTraceContext();

    addCommandService(commandDispatcher, traceContext);

    this.agentInfoSender =
        new AgentInfoSender.Builder(tcpDataSender, this.agentInformation)
            .sendInterval(profilerConfig.getAgentInfoSendRetryInterval())
            .build();
    this.serverMetaDataHolder.addListener(this.agentInfoSender);

    AgentStatCollectorFactory agentStatCollectorFactory =
        new AgentStatCollectorFactory(
            this.getTransactionCounter(this.traceContext), this.profilerConfig);
    this.agentStatMonitor =
        new AgentStatMonitor(
            this.statDataSender,
            this.agentInformation.getAgentId(),
            this.agentInformation.getStartTime(),
            agentStatCollectorFactory);

    InterceptorInvokerHelper.setPropagateException(
        profilerConfig.isPropagateInterceptorException());
  }
Пример #19
0
 /**
  * @param args
  * @param inst
  */
 public static void premain(String args, Instrumentation inst) {
   inst.addTransformer(new ProfTransformer());
   Manager.instance().startupThread();
 }
Пример #20
0
 public static void premain(String args, Instrumentation inst) {
   inst.addTransformer(new TraceTransformer());
 }
Пример #21
0
 private static void forceCorrectNewRelicApi(
     final Instrumentation instrProxy, final JarFile bridgeJarFile) throws IOException {
   final JarEntry jarEntry = bridgeJarFile.getJarEntry("com/newrelic/api/agent/NewRelic.class");
   final byte[] bytes = read(bridgeJarFile.getInputStream(jarEntry), true);
   instrProxy.addTransformer(new ApiClassTransformer(bytes), true);
 }
  public static synchronized void premain(String agentArguments, Instrumentation instrumentation) {

    String[] arguments = agentArguments.split(";");

    String[] includes = arguments[0].split(",");
    String[] excludes = arguments[1].split(",");

    if (Boolean.getBoolean("junit.code.coverage")) {
      final CoberturaClassFileTransformer coberturaClassFileTransformer =
          new CoberturaClassFileTransformer(includes, excludes);

      instrumentation.addTransformer(coberturaClassFileTransformer);

      Runtime runtime = Runtime.getRuntime();

      runtime.addShutdownHook(
          new Thread() {

            @Override
            public void run() {
              ProjectDataUtil.runMergeHooks();
            }
          });
    } else if (instrumentation.isRedefineClassesSupported()
        && instrumentation.isRetransformClassesSupported()) {

      _instrumentation = instrumentation;
      _includes = includes;
      _excludes = excludes;

      // Forcibly clear the data file to make sure that the coverage
      // assert is based on the current test

      File dataFile = CoverageDataFileHandler.getDefaultDataFile();

      dataFile.delete();
    } else {
      StringBuilder sb = new StringBuilder();

      sb.append("Current JVM is not capable for dynamic ");
      sb.append("instrumententation. Instrumentation ");

      if (instrumentation.isRetransformClassesSupported()) {
        sb.append("supports ");
      } else {
        sb.append("does not support ");
      }

      sb.append("restranforming classes. Instrumentation ");

      if (instrumentation.isRedefineClassesSupported()) {
        sb.append("supports ");
      } else {
        sb.append("does not support ");
      }

      sb.append("redefining classes. Dynamic instrumententation is ");
      sb.append("disabled.");

      System.out.println(sb.toString());
    }
  }