Search code examples
javaclassloaderclassnotfoundexception

ClassNotFoundException but class is on classpath and in same jar


Question

what is causing the ClassNotFoundException?

Details

I'm getting a ClassNotFoundException when trying to load a class that I believe to be on the classpath - the class is com.ldbc.driver.db.BasicDb, an implementation of com.ldbc.driver.db.Db

When I try to run this command:

java -cp core/target/core-0.1.jar:distribution/target/ldbc-driver-0.1.tar.gz com.ldbc.driver.Client -db com.ldbc.driver.db.BasicDb

I get the error:

java.lang.ClassNotFoundException: com.ldbc.driver.db.BasicDb
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at com.ldbc.driver.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:163)
    at com.ldbc.driver.util.ClassLoaderHelper.loadDb(ClassLoaderHelper.java:29)
    at com.ldbc.driver.Client.start(Client.java:167)
    at com.ldbc.driver.Client.main(Client.java:80)

It occurs on this line:

Class<?> loadedClass = classLoader.loadClass( className );

To check if the class is on the classpath (in one of my jars) I did the following:

grep "BasicDb" distribution/target/ldbc-driver-0.1.tar.gz

-> returned 0 matches

grep "BasicDb" core/target/core-0.1.jar

-> returned 1 match: Binary file core/target/core-0.1.jar matches

If I import the class at compile time it works fine, i.e. the following works:

import com.ldbc.driver.db.basic.BasicDb;

Though my grep tests seem to indicate the class is on the classpath and is there only once, I wanted to test if for some reason different classes were attached to a different root classloader.

But when printing them out it seems that the same classloader is used everywhere:

ClassLoaderHelper classloader = sun.misc.Launcher$AppClassLoader@489a44f1
Client classloader = sun.misc.Launcher$AppClassLoader@489a44f1

Solution

  • com.ldbc.driver.db.BasicDb versus what you have in your import com.ldbc.driver.db.basic.BasicDb

    You launched your app with the wrong package name for BasicDb, as an application argument.

    java -cp core/target/core-0.1.jar:distribution/target/ldbc-driver-0.1.tar.gz com.ldbc.driver.Client -db com.ldbc.driver.db.BasicDb