package org.skywalking.apm.agent.core.plugin; import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.TypeResolutionStrategy; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.pool.TypePool; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; /** * A test entrance for enhancing class. * This should be used only in bytecode-manipulate test. * And make sure, all classes which need to be enhanced, must not be loaded. * * @author wusheng */ public class TracingBootstrap { private static final ILog logger = LogManager.getLogger(TracingBootstrap.class); private TracingBootstrap() { } /** * Main entrance for testing. * * @param args includes target classname ( which exists "public static void main(String[] args)" ) and arguments * list. * @throws PluginException * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException */ public static void main(String[] args) throws PluginException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { if (args.length == 0) { throw new RuntimeException("bootstrap failure. need args[0] to be main class."); } List<AbstractClassEnhancePluginDefine> plugins = null; try { PluginBootstrap bootstrap = new PluginBootstrap(); plugins = bootstrap.loadPlugins(); } catch (Throwable t) { logger.error("PluginBootstrap start failure.", t); } for (AbstractClassEnhancePluginDefine plugin : plugins) { String enhanceClassName = plugin.enhanceClassName(); TypePool.Resolution resolution = TypePool.Default.ofClassPath().describe(enhanceClassName); if (!resolution.isResolved()) { logger.error("Failed to resolve the class " + enhanceClassName, null); continue; } DynamicType.Builder<?> newClassBuilder = new ByteBuddy().rebase(resolution.resolve(), ClassFileLocator.ForClassLoader.ofClassPath()); newClassBuilder = ((AbstractClassEnhancePluginDefine) plugin).define(enhanceClassName, newClassBuilder); newClassBuilder.make(new TypeResolutionStrategy.Active()).load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION) .getLoaded(); } String[] newArgs = Arrays.copyOfRange(args, 1, args.length); Class.forName(args[0]).getMethod("main", String[].class).invoke(null, new Object[] {newArgs}); } }