Skip to content
Advertisement

How to fix “NoClassDefFoundError” for a package inside a package

Java Program

File Location : ..new1packageEGB.java

package packageEG ;
public class B
{
    public void display()
    {
        System.out.println("B") ;
    }
}

File Location : ..new1C.java

package new1 ;
import packageEG.B ;
public class C 
{
    public void display()
    {
        B b = new B() ;
        b.display() ;
    }
}

File Location : ..A.java

import new1.C ;
public class A 
{
    public static void main(String[] args)
    {
        C c = new C() ;
        c.display() ;
    }
} 

Folder View

../
   A.java
   new1/
      C.java
      packageEG/
            B.java 

It has nested package, one package inside another package.

When I compile main class i.e, “A” it compiles successfully but when I run this program it shows following error :

Exception in thread "main" java.lang.NoClassDefFoundError: packageEG/B
        at new1.C.display(C.java:7)
        at A.main(A.java:7)
Caused by: java.lang.ClassNotFoundException: packageEG.B
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 2 more

Please help me how to fix this error.

Advertisement

Answer

A simple solution to your problem will be to restructure your directories. It is a good practice to store source files and classes in separate directories, typically “src” and “classes”. Then compile using --class-path option.

For your case as an example we can consider the structure of your project as (we may also put A.java in src directory but to maintain some similarity with your code structure let us consider this):

tree
.
├── A.java
└── src
    └── com
        └── xyz
            ├── B.java
            └── C.java

To compile the source using JDK, we need to use the -d option to specify the base directory of the compiled classes, i.e. classes, as follows:

javac -d classes src/com/xyz/B.java src/com/xyz/C.java

Now compile A.java using -cp or --class-path option to specify the base directory of the package com.xyz in order to locate com.xyz.C.

javac -cp ./classes/ A.java

Now the directory structure will be like:

tree
.
├── A.class
├── A.java
├── classes
│   └── com
│       └── xyz
│           ├── B.class
│           └── C.class
└── src
    └── com
        └── xyz
            ├── B.java
            └── C.java

To run, explicitly set CLASSPATH variable to include current directory (denoted using ‘.’) in the CLASSPATH together with base directory of the package com.xyz separated by ‘:’ on linux or ‘;’ on windows. Linux:

java -cp .:./classes A

Windows:

java -cp .;d:pathtodirectoryclasses A
Advertisement