java.lang.ClassNotFoundException: com.example.MyClass
This exception means the JVM tried to load a class at runtime and couldn’t find it on the classpath. The class existed at compile time (otherwise you’d get a compiler error), but it’s missing when the application runs.
What causes this
The JVM’s classloader searches the classpath for .class files. If the class isn’t there — because a JAR is missing, the classpath is wrong, or the package structure doesn’t match — you get ClassNotFoundException.
Common triggers:
- A dependency JAR isn’t included in the classpath at runtime
- The
packagedeclaration doesn’t match the directory structure - You’re using
Class.forName()with a wrong or misspelled class name - A transitive dependency was excluded or has a version conflict
- The fat JAR / uber JAR wasn’t built correctly
Fix 1: Check your classpath
When running from the command line, make sure all required JARs are on the classpath:
# Include all JARs in the lib directory
java -cp .:lib/* com.example.Main
# On Windows, use semicolons
java -cp ".;lib\*" com.example.Main
The . includes the current directory (for your own classes). The lib/* glob includes all JARs in the lib/ folder.
Fix 2: Add the missing dependency
If you’re using a build tool, the class likely comes from a dependency you haven’t declared:
<!-- Maven — add to pom.xml -->
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
</dependency>
// Gradle — add to build.gradle
implementation 'com.example:library:1.0.0'
After adding the dependency, rebuild:
mvn clean install # Maven
gradle build # Gradle
Fix 3: Fix the package/directory mismatch
Java requires the package declaration to match the directory structure exactly:
// ❌ File is at src/main/java/com/other/MyClass.java
package com.example; // Mismatch!
// ✅ File must be at src/main/java/com/example/MyClass.java
package com.example;
If you rename a package, make sure you move the file to the matching directory. Most IDEs handle this automatically, but manual moves can break it.
Fix 4: Check for dependency scope issues
In Maven, dependencies with <scope>provided</scope> or <scope>test</scope> aren’t included in the runtime classpath:
<!-- ❌ This JAR won't be in the runtime classpath -->
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
<!-- ✅ Default scope (compile) — available at runtime -->
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
</dependency>
Use provided only for libraries that the runtime environment supplies (like a servlet container providing the Servlet API).
Fix 5: Fix Class.forName() calls
If you’re loading classes dynamically, double-check the fully qualified name:
// ❌ Typo or wrong package
Class.forName("com.example.MyClss");
// ✅ Exact fully qualified class name
Class.forName("com.example.MyClass");
Also check that the class’s JAR is on the classpath of the classloader doing the loading — in web applications, the webapp classloader and the server classloader have different classpaths.
How to prevent it
- Use
mvn dependency:treeorgradle dependenciesto inspect your full dependency tree and catch missing transitive dependencies. - Build fat/uber JARs with
maven-shade-pluginorshadowJarin Gradle to bundle all dependencies into a single JAR. - In your IDE, use “Find Class” (Ctrl+N in IntelliJ) to verify the class exists and which JAR it comes from.