Java Intstrumentation-从ClassFileTransformer中的类路径加载类

时间:2018-11-24 17:36:00

标签: java instrumentation

我正在尝试从类路径中加载类,然后在访问ClassVisitor时打印有关类的信息。挑战在于,我所要学习的类不是由检测应用程序加载的,因此我必须自己加载它。首先,我在类路径上寻找它,然后调用loader.loadClass,但是没有什么特别的事情发生。你们能告诉我怎么做吗?如果我在检测应用中实例化此类(然后将其加载),则一切正常,我还确定findConfigurationClassName正常,返回正确的类名,并且loadClass不会引发任何异常

public class Agent {

    private static boolean scanned;

    public static void premain(String arentArgs, Instrumentation inst) {
        inst.addTransformer( new ClassFileTransformer() {
            @Override
            public byte[] transform ( ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer )
                    throws IllegalClassFormatException {
                if(!scanned) {
                    ClassInfoList configrationClassName = findConfigrationClassName();
                    for(ClassInfo cl : configrationClassName) {
                        try {
                            loader.loadClass( cl.getName().replaceAll( "\\.", "\\" ) );
                        } catch ( ClassNotFoundException e ) {
                            e.printStackTrace();
                        }
                    }
                }
            ClassReader reader = new ClassReader(classfileBuffer);
            ClassWriter writer = new ClassWriter(reader, 0);
            ClassPrinter visitor = new ClassPrinter(writer);
            reader.accept(visitor, 0);
            return writer.toByteArray();

            }
        });

    }

    public static ClassInfoList findConfigrationClassName() {
        scanned = true;
        String routeAnnotation = "my.package";
        try (ScanResult scanResult =
                     new ClassGraph()
                             .enableAllInfo()
                             .whitelistPackages("my")
                             .scan()) {
            for (ClassInfo routeClassInfo : scanResult.getClassesWithAnnotation(routeAnnotation)) {
                AnnotationInfo routeAnnotationInfo = routeClassInfo.getAnnotationInfo(routeAnnotation);
                List<AnnotationParameterValue> routeParamVals = routeAnnotationInfo.getParameterValues();
                String route = (String) routeParamVals.get(0).getValue();
                System.out.println(routeClassInfo.getName() + " is annotated with route " + route);
            }

            return scanResult.getClassesWithAnnotation(routeAnnotation);
        }
    }
}

0 个答案:

没有答案