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.
Related: Android: NetworkOnMainThreadException โ How to Fix It