简体   繁体   English

用javassist加载另一个类

[英]loading another class with javassist

I have two projects: a profiler and a basic application (with JUnit tests) 我有两个项目:探查器和基本应用程序(带有JUnit测试)

The profiler uses Javassist to instrument the basic application. 探查器使用Javassist来检测基本应用程序。

When the profiler is inside the basic application, it works fine. 当探查器在基本应用程序内部时,它可以正常工作。 When the profiler is outside the basic application, I have to import the basic application jar file into the build path on Eclipse to be abble to instrument my application. 当探查器不在基本应用程序之外时,我必须将基本应用程序jar文件导入Eclipse上的构建路径,才能对我的应用程序进行检测。

I want to run my profiler on my basic application in command line as EMMA does: 我想像EMMA一样在命令行上的基本应用程序上运行探查器:

java -jar profiler.jar run application.jar java -jar profiler.jar运行application.jar

But I don't know how to tell my profiler, ok, instrument this jar. 但是我不知道该如何告诉我的分析器,好吧,把这个罐子装进去。

Here is my profiler main code: 这是我的分析器主要代码:

    public static void main(String[] args) throws Exception {   
    Loader loader = new Loader();
    loader.addTranslator(ClassPool.getDefault(), new Profiler());
    try {
        loader.run("com.application.bookstore.test.Test", null);
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

I tried to do that: 我试图这样做:

final String arg = args[0];
final String[] commandArgs = new String[args.length - 1];
System.arraycopy(args, 1, commandArgs, 0, commandArgs.length-1);

loader.run(arg, commandArgs);

But when I run it, I get: 但是当我运行它时,我得到:

[kdelemme@pdkdelemme build]$ java -jar profiler.jar bookstore.jar
java.lang.ClassNotFoundException: bookstore.jar
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at javassist.Loader.delegateToParent(Loader.java:429)
    at javassist.Loader.loadClass(Loader.java:315)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at javassist.Loader.run(Loader.java:289)
    at com.modeln.Profiler.main(Profiler.java:93)

So I tried to run directly into my Main class directory: 因此,我尝试直接运行到我的Main class目录中:

[kdelemme@pdkdelemme test]$ ls
profiler.jar  Test.class
[kdelemme@pdkdelemme test]$ java -jar profiler.jar Test 
java.lang.NoClassDefFoundError: Test (wrong name: com/application/bookstore/test/Test)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:480)
    at javassist.Loader.findClass(Loader.java:380)
    at javassist.Loader.loadClass(Loader.java:312)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at javassist.Loader.run(Loader.java:289)
    at com.modeln.Profiler.main(Profiler.java:93)

So Have you any ideas to how run my profiler on an outside jar project? 那么,您对如何在外部jar项目上运行我的探查器有任何想法吗? Thanks a lot! 非常感谢!

Ok, here's the solution: Just pool.insertClassPath() 好的,这是解决方案:只是pool.insertClassPath()

public static void main(String[] args) throws Exception {   
    Loader loader = new Loader();
    loader.addTranslator(ClassPool.getDefault(), new Profiler());
    try {
        if (args.length < 1) {
            System.out.println(TOOL_USAGE);
        } else {

            //Initialize profiler with config/config.properties file
            initializeProfiler();

            final String[] commandArgs = new String[args.length - 1];
            System.arraycopy(args, 1, commandArgs, 0, commandArgs.length);

            //Open a jar file, unJar it into /tmp/ then add the /tmp/ classpath to the javassist laoder
            File file = new File(args[0]);
            JarFile jarFile = new JarFile(args[0]);
            Manifest manifest = jarFile.getManifest();
            String mainClassName = null;

            if (manifest != null) {
                mainClassName = manifest.getMainAttributes().getValue("Main-Class");
            }

            jarFile.close();

            mainClassName = mainClassName.replaceAll("/", ".");
            //Default temp directory is Jarfilename without .jar
            final File workDir = File.createTempFile(args[0].substring(0, args[0].indexOf('.')), "");
            workDir.delete();
            workDir.mkdirs();

            //Unjar all files into WorkDir temp directory
            unJar(file, workDir);

            //Add all directories into classPath
            createClassPath(workDir, file);

            //Add the classPath with unJar files into the Javassist ClassPool
            ClassPool pool = ClassPool.getDefault();
            pool.insertClassPath(workDir + "/");
            loader.run(mainClassName, null);

          }

    } catch (Throwable e) {
        e.printStackTrace();
    }

    System.out.println("Instrumentation of " + args[0] + " finished.");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM