使用byte buddy的Advice时,抛出Exception of java.lang.NoClassDefFoundError
When using Advice of byte buddy, Exception of java.lang.NoClassDefFoundError is throwed
出于某种原因,我一直在分析我自己的旧 jar 文件(不幸的是源代码丢失了)。
我知道我要找到哪个部分,但不记得它在哪里。
所以决定使用byte buddy来获取jar文件的所有运行流。记录所有 classes 中所有方法的参数值和 return 值就足够了(库 class 除外,例如 java.lang.*)。
我尝试了稍作修改的示例代码,但只出现了一个例外:
public static void premain(final String agentArgs,
final Instrumentation inst) {
System.out.println(
"+++Hey, look: I'm instrumenting a freshly started JVM!");
new AgentBuilder.Default()
.type(ElementMatchers.any())
.transform(new MetricsTransformer())
.with(AgentBuilder.Listener.StreamWriting.toSystemOut())
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.installOn(inst);
}
private static class MetricsTransformer implements AgentBuilder.Transformer {
@Override
public DynamicType.Builder<?> transform(
final DynamicType.Builder<?> builder,
final TypeDescription typeDescription,
final ClassLoader classLoader,
final JavaModule module) {
final AsmVisitorWrapper methodsVisitor =
Advice.to(EnterAdvice.class, ExitAdviceMethods.class)
.on(ElementMatchers.isAnnotatedWith(CollectMetrics.class)
.and(ElementMatchers.isMethod()));
final AsmVisitorWrapper constructorsVisitor =
Advice.to(EnterAdvice.class, ExitAdviceConstructors.class)
.on(ElementMatchers.isAnnotatedWith(CollectMetrics.class)
.and(ElementMatchers.isConstructor()));
return builder.visit(methodsVisitor).visit(constructorsVisitor);
}
private static class EnterAdvice {
@Advice.OnMethodEnter
static long enter() {
return System.nanoTime();
}
}
private static class ExitAdviceMethods {
@Advice.OnMethodExit(onThrowable = Throwable.class)
static void exit(@Advice.Origin final Executable executable,
@Advice.Enter final long startTime,
@Advice.Thrown final Throwable throwable) {
final long duration = System.nanoTime() - startTime;
System.out.println(duration);;
}
}
}
字节哥的版本是1.9.5,1.7.11
jdk版本:1.8.0.191
和 cmd 中的异常:
E:\>cd E:\workshop\_android_studio\BounAgent\out\artifacts\BounAgent_jar
E:\BounAgent_jar>java -javaagent:BounAgent.jar -jar untitled.jar
Exception in thread "main" java.lang.NoClassDefFoundError: net/bytebuddy/matcher
/ElementMatcher
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 Sou
rce)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown So
urce)
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.matcher.ElementMatche
r
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
本机方法中的致命错误:-javaagent 处理失败
提前致谢。
根据an article我发现:
To launch your agent you must bundle the agent classes and resources in a jar, and in the jar manifest set the Agent-Class property to the name of your agent class containing the premain method. (An agent must always be bundled as a jar file, it cannot be specified in an exploded format.)
您的代理 JAR 文件 ("BounAgent.jar") 似乎未包含正确形式的所有依赖项。具体来说,bytebuddy 类 不在 JAR 文件中。这导致代理 类 无法加载。
出于某种原因,我一直在分析我自己的旧 jar 文件(不幸的是源代码丢失了)。 我知道我要找到哪个部分,但不记得它在哪里。 所以决定使用byte buddy来获取jar文件的所有运行流。记录所有 classes 中所有方法的参数值和 return 值就足够了(库 class 除外,例如 java.lang.*)。 我尝试了稍作修改的示例代码,但只出现了一个例外:
public static void premain(final String agentArgs,
final Instrumentation inst) {
System.out.println(
"+++Hey, look: I'm instrumenting a freshly started JVM!");
new AgentBuilder.Default()
.type(ElementMatchers.any())
.transform(new MetricsTransformer())
.with(AgentBuilder.Listener.StreamWriting.toSystemOut())
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.installOn(inst);
}
private static class MetricsTransformer implements AgentBuilder.Transformer {
@Override
public DynamicType.Builder<?> transform(
final DynamicType.Builder<?> builder,
final TypeDescription typeDescription,
final ClassLoader classLoader,
final JavaModule module) {
final AsmVisitorWrapper methodsVisitor =
Advice.to(EnterAdvice.class, ExitAdviceMethods.class)
.on(ElementMatchers.isAnnotatedWith(CollectMetrics.class)
.and(ElementMatchers.isMethod()));
final AsmVisitorWrapper constructorsVisitor =
Advice.to(EnterAdvice.class, ExitAdviceConstructors.class)
.on(ElementMatchers.isAnnotatedWith(CollectMetrics.class)
.and(ElementMatchers.isConstructor()));
return builder.visit(methodsVisitor).visit(constructorsVisitor);
}
private static class EnterAdvice {
@Advice.OnMethodEnter
static long enter() {
return System.nanoTime();
}
}
private static class ExitAdviceMethods {
@Advice.OnMethodExit(onThrowable = Throwable.class)
static void exit(@Advice.Origin final Executable executable,
@Advice.Enter final long startTime,
@Advice.Thrown final Throwable throwable) {
final long duration = System.nanoTime() - startTime;
System.out.println(duration);;
}
}
}
字节哥的版本是1.9.5,1.7.11 jdk版本:1.8.0.191
和 cmd 中的异常:
E:\>cd E:\workshop\_android_studio\BounAgent\out\artifacts\BounAgent_jar
E:\BounAgent_jar>java -javaagent:BounAgent.jar -jar untitled.jar
Exception in thread "main" java.lang.NoClassDefFoundError: net/bytebuddy/matcher
/ElementMatcher
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 Sou
rce)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown So
urce)
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.matcher.ElementMatche
r
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
本机方法中的致命错误:-javaagent 处理失败
提前致谢。
根据an article我发现:
To launch your agent you must bundle the agent classes and resources in a jar, and in the jar manifest set the Agent-Class property to the name of your agent class containing the premain method. (An agent must always be bundled as a jar file, it cannot be specified in an exploded format.)
您的代理 JAR 文件 ("BounAgent.jar") 似乎未包含正确形式的所有依赖项。具体来说,bytebuddy 类 不在 JAR 文件中。这导致代理 类 无法加载。