We have a very small Web service (less than 1K lines of code) which is run by Jetty. The service worked always fine even during our stress testing phase. However, after 13 days of uptime we experienced a ClassNotFoundException in two nodes the same day.
The strange thing is that the class that wasn't found was already there (it is part of the startup routine and it was used constantly servicing previous requests). In fact, simply restarting the process solved the issue. Both nodes are in separate machines and are independent of each other. They don't depend on external resources, except on one JMS connection.
I couldn't find relevant information while Googling this, as most of the reported issues are related to missing classes in the class path while starting up the Java process, which is not our case. We suspect there could be a memory leak that in a way corrupted the JVM memory, however this can't explain why the same problem happened in two nodes around the same time. We've been running intensive stress testing during the last five days attaching a JVM monitor and a memory leak analyzer, and everything seems fine. For this tests we decreased the process memory from 2GB to 512MB.
Details:
Can you please contribute with ideas regarding what could make the JVM to suddenly "forget" about the existence of a previously loaded class, not being able to load it again?
Caused by: java.lang.ClassNotFoundException: com.a.b.c.SomeClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:202) ~[na:1.6.0_37]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.6.0_37]
at java.net.URLClassLoader.findClass(URLClassLoader.java:190) ~[na:1.6.0_37]
at java.lang.ClassLoader.loadClass(ClassLoader.java:306) ~[na:1.6.0_37]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) ~[na:1.6.0_37]
at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ~[na:1.6.0_37]
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:424) ~[na:na]
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377) ~[na:na]
at java.lang.Class.forName0(Native Method) ~[na:1.6.0_37]
at java.lang.Class.forName(Class.java:247) ~[na:1.6.0_37]
at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:95) ~[na:1.6.0_37]
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:107) ~[na:1.6.0_37]
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:31) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:370) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:351) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:280) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:222) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:69) ~[na:1.6.0_37]
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:52) ~[na:1.6.0_37]
at java.lang.reflect.Field.declaredAnnotations(Field.java:1014) ~[na:1.6.0_37]
at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:1007) ~[na:1.6.0_37]
Edit:
Someone mentioned me that while using NFS mounts under Win, it could happen that the JVM decides to unload a class, and then re-loads it when it's needed. If in the middle of this process the NFS connection was broken, the file handle will be invalid and the re-loading will fail with a similar stacktrace. In our case, we are using Linux and all the involved files are in the same mount, which is a local hard disk. Just for the sake of more testing, I've CD'd into the Jetty temporary directory and manually deleted one well known for one specific service class. If the JVM unloads it and then attempts to re-load it from the classes directory, it will fail. While this does not explain the original problem, it might put more information on the table...
java. lang. NoClassDefFoundError is runtime error thrown when a required class is not found in the classpath and hence JVM is unable to load it into memory.
click on project->properties->Java build path->Source and check each src folder is still valid exist or recently removed. Correct any missing path or incorrect path and rebuild and run the test. It will fix the problem.
When you get a ClassNotFoundException, it means the JVM has traversed the entire classpath and not found the class you've attempted to reference. The solution, as so often in the Java world, is to check your classpath. You define a classpath on the command line by saying java -cp and then your classpath.
This is what is happening:
A good hint we had is that some people reported a similar issue while loading resources in JARs over NFS on Windows (if network connectivity is lost for a brief moment, NFS handles become invalid and the JVM fails with a similar error). This is not our case (/tmp is local storage), but quite similar.
Thanks everyone for their help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With