Question about ClassNotFoundException
See original GitHub issueHi, everyone!
I found a java.lang.ClassNotFoundException
when i use ElasticApm and my own agent.
I prepared a demo to reproduce it:
Elastic Apm version: 1.34.1 bytebuddy version: 1.12.10 (same with elastic apm)
- i generate a springboot web demo in start.spring.io and new a
DemoController
DemoController:
@RestController
public class DemoController {
@GetMapping("/hello")
public String hello(String message) {
System.out.println("i am hello");
return message;
}
}
pom.xml:
......
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
- write a simple agent with bytebuddy, enhance
DemoController#hello
and print : “i am agent”, i load my agent with bootstrap classloader:
premain:
public static void premain(String args, Instrumentation inst) {
File jar = new File("my agent path");
try {
inst.appendToBootstrapClassLoaderSearch(new JarFile(jar));
// use bootstrap classloader
Class.forName("Myagent", true, null)
.getMethod("main", Instrumentation.class)
.invoke(null, inst);
}
Myagent:
public static void main(Instrumentation inst) {
new AgentBuilder.Default()
.with(AgentBuilder.LocationStrategy.ForClassLoader.WEAK)
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.LocationStrategy.ForClassLoader.WEAK)
.ignore(ElementMatchers.<TypeDescription>nameStartsWith("net.bytebuddy.")
.or(ElementMatchers.<TypeDescription>nameStartsWith(".asm."))
.or(nameStartsWith("java."))//rt.jar bootstrap classloader
.or(nameStartsWith("com.sun.")))
.type(ElementMatchers.<TypeDescription>named("com.example.demo.DemoController"))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
return builder
.method(ElementMatchers.named("hello"))
.intercept(MethodDelegation.to(new Interceptor()));
}
})
.installOn(inst);
}
Interceptor:
@RuntimeType
public String interceptor(@SuperCall Callable<?> zuper) throws Exception {
System.out.println("i am interceptor");
zuper.call();
return "";
}
Here are some experiments I did:
- jdk version: 17.05,
jvm options: -javaagent:Myagent.jar -javaagent:elastic-apm-agent-1.34.1.jar
curl localhost:8080/hello
will thrown exception:
java.lang.ClassNotFoundException: com.example.demo.DemoController$auxiliary$0QZj0xRL
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
at com.example.demo.DemoController.hello(DemoController.java) ~[classes/:na]
- if
premain
use AppClassloader load Myagent, it works great:
public static void premain(String args, Instrumentation inst) {
File jar = new File("my agent path");
try {
inst.appendToBootstrapClassLoaderSearch(new JarFile(jar));
// use bootstrap classloader
Class.forName("Myagent", true, ClassLoader.getSystemClassLoader())
.getMethod("main", Instrumentation.class)
.invoke(null, inst);
}
-
if i use elastic-apm-agent-1.26.0.jar, it work great: jdk version: 17.05,
jvm options: -javaagent:Myagent.jar -javaagent:elastic-apm-agent-1.26.0.jar
-
if i use jdk8 and elastic-apm-agent-1.34.1.jar, it work great: jdk version: 1.8.0_211,
jvm options: -javaagent:Myagent.jar -javaagent:elastic-apm-agent-1.34.1.jar
i think when i use elastic-apm-agent-1.34.1 in jdk17 with Myagent,bytebuddy can’t inject auxiliary class to app classloader? Can you help me? thank
Issue Analytics
- State:
- Created 10 months ago
- Comments:11 (1 by maintainers)
Top Results From Across the Web
ClassNotFoundException Vs NoClassDefFoundError in Java
Both of the exceptions that are ClassNotFoundException and NoClassDefFoundError occur when the class is not found at runtime.
Read more >How do I resolve ClassNotFoundException? - Stack Overflow
When you get a ClassNotFoundException, it means the JVM has traversed the entire classpath and not found the class you've attempted to reference....
Read more >How to Fix ClassNotFoundException in Java - Rollbar
The Java ClassNotFoundException occurs when the JVM tries to load a class but does not find it in the classpath. Learn the three...
Read more >Interview Questions and Answers for 'Classnotfoundexception'
What things should be kept in mind while creating your own exceptions in Java? Difference between Checked and Unchecked exceptions ? Explain throw,...
Read more >java.lang.ClassNotFoundException - DigitalOcean
Java ClassNotFoundException occurs when the application tries to load a class but Classloader is not able to find it in the classpath.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The problem will be that this injects the
Nexus
class into the boot loader. However, theNexusAccessor
is explicitly aiming for the system class loader, so this should not be a problem?Thank you very much!I think I have probably understood the general logic. Thank you for your guidance. If necessary later, I will provide a reproduction