๐Ÿ”ง Error Fixes
ยท 2 min read
Last updated on

Java ClassNotFoundException โ€” How to Fix It


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 package declaration 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:tree or gradle dependencies to inspect your full dependency tree and catch missing transitive dependencies.
  • Build fat/uber JARs with maven-shade-plugin or shadowJar in 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