У меня есть класс агента, он просто печатает две строки до и после метода 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()");
}
Затем я упаковываю агент в виде jar-файла с именем agent.jar и добавляю «-javaagent: xxx / yyy / agent.jar» в vmoptions в IDEA вот так
После этого, когда я запускаю hello-world, я получаю то, что хочу
<-----------before------->
Hi, i am in main()
<-----------end------->
Однако, когда я пытаюсь запустить hello-world как jar, например «hello-world.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.
Может кто-нибудь сказать мне, почему и как решить эту проблему?
Спасибо!