【发布时间】:2020-04-16 07:58:08
【问题描述】:
我有一个代理类,它只是在另一个项目的 main() 方法之前和之后打印两行。代理类如下
public class Agent {
static String packageName = "xxx.hello.world";
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer((classLoader, s, aClass, protectionDomain, bytes) -> {
byte[] transformed = null;
CtClass cl = null;
try {
ClassPool pool = new ClassPool();
pool.insertClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
pool.importPackage(packageName);
cl = pool.makeClass(new ByteArrayInputStream(bytes));
CtMethod[] methods = cl.getDeclaredMethods();
for (CtMethod method : methods) {
if ("main".equals(method.getName())) {
method.insertBefore("System.out.println(\"<-----------before------->\");");
method.insertAfter("System.out.println(\"<-----------end------->\");");
}
}
transformed = cl.toBytecode();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cl != null) {
cl.detach();
}
}
return transformed;
});
}}
我还有另一个名为“HelloWorld”的项目,它只是在它的主方法中打印“嗨,我在 main()”。 HelloWorld.class如下
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hi, i am in main()");
}
然后我把agent打包成一个jar,命名为“agent.jar”,在IDEA的vmoptions中添加“-javaagent:xxx/yyy/agent.jar”,像这样
之后,当我运行 hello-world 时,我得到了我想要的样子
<-----------before------->
Hi, i am in main()
<-----------end------->
但是,当我尝试在命令行中将 hello-world 作为类似“hello-world.jar”的 jar 运行时
java -javaagent:xxx/yyy/agent.jar -jar hello-world.jar
我收到一个奇怪的错误,例如
Exception in thread "main" java.lang.NoClassDefFoundError: javassist/ClassPath
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getDeclaredMethod(Unknown Source)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(Unknown Source)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javassist.ClassPath
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 5 more
这很奇怪,因为我认为这两种方式(在 IDEA 和命令行中)是相同的。当我检查 hello-world.jar 时,我可以看到 javassist/ClassPath.class。
谁能告诉我为什么以及如何解决这个问题?
谢谢!
【问题讨论】:
-
"Caused by: java.lang.ClassNotFoundException: javassist.ClassPath" - 修复你的类路径
标签: java maven javaagents