The Java Virtual Machine (JVM) gave up on loading a class that was present at compile time because it couldn’t find the definition of that class at runtime.
This usually happens because the class is missing from your application’s classpath, or there’s a version mismatch between libraries.
1. Missing JAR in Classpath
- Diagnosis: Check your application’s startup script or manifest file for the
java.class.pathproperty or theClass-Pathentry. - Fix: Add the missing JAR file to the classpath. For example, if your app is run with
java -jar myapp.jar, andmyapp.jardepends onlib/dependency.jar, ensurelib/dependency.jaris in the same directory or explicitly added:
This works because the JVM explicitly searches the colon-separated list of directories and JARs for class files.java -cp "myapp.jar:lib/dependency.jar" com.example.Main - Why it happens: The JVM needs to know where to find the compiled
.classfiles at runtime. If the JAR containing the missing class isn’t in the locations it’s told to look, it can’t load it.
2. Incorrect JAR Version
- Diagnosis: If you have multiple versions of the same library on your classpath, the JVM might pick up an older one that doesn’t contain the class you need, or a newer one that has a different API.
- Fix: Ensure only one version of a library is present, or that the correct version is prioritized. If using Maven, resolve conflicts:
Then, exclude the unwanted version or explicitly declare the desired one in yourmvn dependency:treepom.xml:
This forces the build tool to use the specified version, ensuring the correct class definition is available.<dependency> <groupId>com.example</groupId> <artifactId>mylib</artifactId> <version>1.5.0</version> <exclusions> <exclusion> <groupId>com.example</groupId> <artifactId>mylib</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>mylib</artifactId> <version>2.0.0</version> </dependency> - Why it happens: The JVM loads classes based on the first match it finds on the classpath. If an older, incompatible version is found first, the class might exist but not have the expected methods or structure, leading to
NoClassDefFoundErrorif a method signature changed or the class was removed.
3. Corrupted JAR File
- Diagnosis: Verify the integrity of the JAR file by checking its size against a known good version or by listing its contents.
jar tf /path/to/your.jar | grep MissingClass - Fix: Re-download or rebuild the JAR file. If using a dependency manager like Maven or Gradle, clean and rebuild:
This ensures the JAR is rebuilt from source and is not truncated or corrupted.mvn clean install # or gradle clean build - Why it happens: A corrupted JAR file might be missing the
.classfile entirely or have a damaged entry, preventing the JVM from extracting and loading it.
4. Class Not Included in the Executable JAR (Fat JAR)
- Diagnosis: If you’re building a "fat JAR" (an executable JAR that includes all dependencies), check the build configuration to ensure all necessary dependencies are being packaged.
- Fix: Configure your build tool (e.g., Maven Shade Plugin, Gradle Shadow Jar plugin) to include all required dependencies. For Maven Shade Plugin:
This ensures that when<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>java -jar myapp.jaris run, all necessary classes are within the JAR itself. - Why it happens: When running a fat JAR, the JVM only looks inside that single JAR file. If dependencies weren’t correctly included during the build, the classes they provide won’t be found.
5. Class Loading Delegation Issues (Less Common)
- Diagnosis: In complex environments with multiple classloaders (e.g., application servers like Tomcat, OSGi), a custom classloader might be preventing the standard classloader from finding the class.
- Fix: Adjust the classloader hierarchy or explicitly load the class using the correct classloader. For example, in Tomcat, ensure your WAR file’s
WEB-INF/libhas the correct JAR, or that shared libraries incommon/libare not conflicting. If a custom classloader is involved, itsloadClassmethod might need adjustment:
This forces the specific classloader responsible for your application’s dependencies to attempt the load.// Example of explicit loading if a custom classloader 'myLoader' is involved try { Class<?> loadedClass = myLoader.loadClass("com.example.MissingClass"); // ... use loadedClass } catch (ClassNotFoundException e) { // handle error } - Why it happens: Each classloader has a parent. By default, a classloader asks its parent to load a class first. If the parent can’t find it, the child then tries. If this delegation is misconfigured or a custom loader intercepts the request incorrectly, the class might be missed.
6. Package Name Mismatch in Source vs. Compiled Class
- Diagnosis: Double-check the
packagedeclaration in your.javasource file against the directory structure within the JAR file or on the classpath. - Fix: Ensure the package name in your source code exactly matches the directory structure. If your source has
package com.example.util;, the.classfile should be found undercom/example/util/. Recompile if necessary:
Then ensurejavac -d bin src/com/example/MyClass.javabinis on the classpath. - Why it happens: The JVM uses the fully qualified class name (package + class name) to locate the
.classfile. A mismatch means the expected path doesn’t exist, even if the class file itself is present elsewhere.
The next error you’ll likely encounter, after resolving this, is a LinkageError if the class was found but its methods or fields are incompatible with the calling code, or potentially a NoSuchMethodError or NoSuchFieldError.