package com.alibaba.ttl.threadpool.agent; import com.alibaba.ttl.threadpool.agent.internal.logging.Logger; import com.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; import java.lang.instrument.ClassFileTransformer; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; /** * TTL {@link ClassFileTransformer} of Java Agent * * @author Jerry Lee (oldratlee at gmail dot com) * @see ClassFileTransformer * @see The mechanism for instrumentation * @since 0.9.0 */ public class TtlTransformer implements ClassFileTransformer { private static final Logger logger = Logger.getLogger(TtlTransformer.class); private static final byte[] EMPTY_BYTE_ARRAY = {}; private final List transformletList = new ArrayList(); TtlTransformer(List> transformletClasses) throws Exception { for (Class transformletClass : transformletClasses) { final JavassistTransformlet transformlet = transformletClass.getConstructor().newInstance(); transformletList.add(transformlet); logger.info("[TtlTransformer] add Transformlet " + transformletClass + " success"); } } @Override public final byte[] transform(final ClassLoader loader, final String classFile, final Class classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classFileBuffer) { try { // Lambda has no class file, no need to transform, just return. if (classFile == null) { return EMPTY_BYTE_ARRAY; } final String className = toClassName(classFile); for (JavassistTransformlet transformlet : transformletList) { final byte[] bytes = transformlet.doTransform(className, classFileBuffer, loader); if (bytes != null) return bytes; } } catch (Throwable t) { String msg = "Fail to transform class " + classFile + ", cause: " + t.toString(); logger.log(Level.SEVERE, msg, t); throw new IllegalStateException(msg, t); } return EMPTY_BYTE_ARRAY; } private static String toClassName(final String classFile) { return classFile.replace('/', '.'); } }