您的位置:首页 > 其它

HotSpot SA #4:输出类加载路径

2015-03-29 13:02 155 查看
参考R大的文章,也写了一个SA的小工具,可以输出指定类(使用
-Dme.kisimple.just4fun.ClassPathDump=类名
指定)是从什么地方加载进来的,

[code]package me.kisimple.just4fun;

import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;

public class ClassPathDump extends Tool {

    private String className;

    public ClassPathDump(String className) {
        super();
        this.className = className;
    }

    public static void main(String[] args) {
        String className = System.getProperty("me.kisimple.just4fun.ClassPathDump");
        if(className != null) {
            ClassPathDump dump = new ClassPathDump(className.replace(".", "/"));
            dump.start(args);
            dump.stop();
        }
    }

    @Override
    public void run() {
        VM vm = VM.getVM();
        final ObjectHeap objectHeap = vm.getObjectHeap();
        objectHeap.iteratePerm(new HeapVisitor() {
            @Override
            public void prologue(long l) {
            }

            @Override
            public boolean doObj(Oop oop) {
                if(oop instanceof InstanceKlass) {
                    InstanceKlass klass = (InstanceKlass)oop;
                    if(klass.getName() != null &&
                            className.equals(klass.getName().asString())) {
                        Oop protectionDomain = klass.getProtectionDomain();
                        if(protectionDomain == null)
                            return true;

                        Oop codesource = getOopFieldValue(protectionDomain,
                                "codesource", "Ljava/security/CodeSource;");
                        if(codesource == null)
                            return true;

                        Oop location = getOopFieldValue(codesource,
                                "location", "Ljava/net/URL;");
                        if(location == null)
                            return true;

                        Oop path = getOopFieldValue(location,
                                "path", "Ljava/lang/String;");
                        if (path == null)
                            return true;

                        System.out.println("////////////////////////////////////////");
                        System.out.println("[LOADED]" + className);
                        System.out.println("[FORM]"+ OopUtilities.stringOopToString(path));
                        return true;
                    }
                }
                return false;
            }

            @Override
            public void epilogue() {
            }
        });
    }

    private Oop getOopFieldValue(Oop oop, String name, String sig) {
        InstanceKlass klass = (InstanceKlass) oop.getKlass();
        OopField field = (OopField) klass.findField(name, sig);
        return field.getValue(oop);
    }

}


执行以下命令(
sa-jdi.jar
需要放在classpath上),

[code]> java -Dme.kisimple.just4fun.ClassPathDump=groovy.lang.GroovyClassLoader me.kisimple.just4fun.ClassPathDump 6376


6376
是目标进程pid,示例输出如下,

[code]Attaching to process ID 6376, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
////////////////////////////////////////
[LOADED]groovy/lang/GroovyClassLoader
[FORM]/C:/Java/jdk1.7.0_51/jre/lib/ext/groovy-2.4.0.jar


参考资料

http://rednaxelafx.iteye.com/blog/1295944
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: