🔧 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.