我有两个项目:一个探查器和一个基本应用程序(带有 JUnit 测试)
分析器使用 Javassist 来检测基本应用程序。
当探查器位于基本应用程序内部时,它可以正常工作。 当探查器位于基本应用程序之外时,我必须将基本应用程序 jar 文件导入到 Eclipse 上的构建路径中,以便能够检测我的应用程序。
我想像 EMMA 一样在命令行中的基本应用程序上运行我的探查器:
block 引用>java -jar profiler.jar run application.jar
但我不知道如何告诉我的探查器,好吧,检测这个 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 项目上运行我的探查器有什么想法吗?非常感谢!
最佳答案
好的,这是解决方案:只需 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.");
}
关于java - 使用 javassist 加载另一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10953373/