【问题标题】:loading another class with javassist用 javassist 加载另一个类
【发布时间】:2012-06-08 17:25:01
【问题描述】:

我有两个项目:一个分析器和一个基本应用程序(带有 JUnit 测试)

分析器使用 Javassist 来检测基本应用程序。

当分析器在基本应用程序中时,它可以正常工作。 当分析器在基本应用程序之外时,我必须将基本应用程序 jar 文件导入 Eclipse 上的构建路径才能检测我的应用程序。

我想像 EMMA 一样在命令行中的基本应用程序上运行我的分析器:

java -jar profiler.jar 运行 application.jar

但我不知道如何告诉我的分析器,好的,检测这个罐子。

这是我的分析器主要代码:

    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();
    }
}

我尝试过这样做:

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);

但是当我运行它时,我得到:

[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)

所以我尝试直接运行到我的主类目录:

[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)

那么您对如何在外部 jar 项目上运行我的分析器有任何想法吗?非常感谢!

【问题讨论】:

    标签: java classloader emma javassist


    【解决方案1】:

    好的,解决方案如下:只需 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.");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2019-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多