@Override public void configurationChanged() { if (started.get()) { if (configuration.isFilterChanged()) { List<ClassInfo> deltas = context.buildDeltaList(); if (deltas != null && !deltas.isEmpty()) { for (ClassInfo classInfo : deltas) { if (configuration.isAsyncTransformation()) { try { blockingQueue.put(classInfo.getOriginalClass()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } else { try { instrumentation.retransformClasses(new Class[] {classInfo.getOriginalClass()}); } catch (Throwable e) { LOG.error("Could not transform " + classInfo.getClassName(), e); } } } if (configuration.isAsyncTransformation() && !blockingQueue.isEmpty()) { startTransformThread(); } } } } }
@Override public byte[] transform( ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { byte[] buffer = null; ClassInfo classInfo = context.getClassInfo(className); classInfo.setOriginalClass(classBeingRedefined); if (classInfo.getTransformed() == null) { // we haven't been transformed before classInfo.setOriginal(classfileBuffer); } if (!cleanUp.get()) { byte[] classBufferToRedefine = classInfo.getOriginal(); if (configuration.isAudit(className)) { if (classInfo.isTransformed()) { // remove metrics from methods no longer defined context.resetMethods(classInfo); } ClassReader cr = new ClassReader(classBufferToRedefine); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); ApmClassVisitor visitor = new ApmClassVisitor(this, cw, classInfo); cr.accept(visitor, ClassReader.SKIP_FRAMES); buffer = cw.toByteArray(); if (!verifyClass(className, buffer)) { classInfo.setCanTransform(false); buffer = null; } classInfo.setTransformed(buffer); } } else { if (classInfo.getOriginal() != null) { buffer = classInfo.getOriginal(); context.resetAll(classInfo); } } return buffer; }