Java classnotfoundexception

Hello,
I’m trying to follow along with the self paced training (https://training.docker.com/self-paced-training), but in the third one where a java application is built and run, on the “compose run…” command I always get a ClassNotFoundException for the redis.redis.jedis.Jedis class. I can build fine with no exceptions, and the java class file (JavaHelloWorld.class) is created as expected, as well as the image. But when I go to run it with:

docker run --link redis:redis jeff/javahelloworld java JavaHelloWorld

I get a ClassNotFoundException for the Jedis library. If I take all references to Jedis out of the code, then it all runs fine, so it’s something to do with how I’m specifying the Jedis library.

Environment: Windows with VirtualBox

Dockerfile:

FROM java:7
COPY . .
RUN javac -cp lib/jedis-2.4.2.jar -d . ./JavaHelloWorld.java

As the link –link redis:redis indicates is a Docker container called “redis” running?

Yes, a container with the name “redis” is running.

ClassNotFoundException for the redis.redis.jedis.Jedis class
The error is probably because no such class as redis.redis.jedis.Jedis is defined.
The class name should be redis.clients.jedis.Jedis. Fix the class name and the error should get fixed.

http://javadox.com/redis.clients/jedis/2.2.1/redis/clients/jedis/Jedis.html

Sorry, error message is actually:

$ docker run --link redis:redis jeff/javahelloworld java JavaHelloWorld
Exception in thread “main” java.lang.NoClassDefFoundError: redis/clients/jedis/J
edis
at JavaHelloWorld.main(JavaHelloWorld.java:8)
Caused by: java.lang.ClassNotFoundException: redis.clients.jedis.Jedis
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:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
… 1 more

The Jedis library jar is in the classpath of the linked container “jedis”, but not the container of the JavaHelloWorld application. Copy the Jedis library jar to the container running the HelloWorld application.

I bash’ed into the container and the jar file is being copied to the container at:

lib/jedis-2.4.2.jar

The lib is directly below the main directory containing the JavaHelloWorld.class file. I assume the copy is being done by the following COPY command in the Dockerfile:

COPY . .

The COPY command did not get listed in the post. Copy the jar file to the same directory as the JavaHelloWorld.class file.

That was the copy command. Here’s the whole dockerfile:

FROM java:7
COPY . .
RUN javac -cp lib/jedis-2.4.2.jar -d . ./JavaHelloWorld.java

I did try moving the jedis-2.4.2.jar file up into the main directory but I’m still seeing the same thing. The command I use to run is:

docker run jeff/javahelloworld java -cp . JavaHelloWorld

It seems to be finding the main class, but not the jar file. I also tried:

docker run jeff/javahelloworld java -cp .;lib/jedis-2.4.2.jar JavaHelloWorld

But then I get a java Usage error.

Set the classpath in the Dockerfile with ENV CLASSPATH
Refer

Yeah, I had already tried that as well. I added this to my Dockerfile:

ENV CLASSPATH .;./lib/jedis-2.4.2.jar

And I bashed into the container and did:

echo $CLASSPATH

and it was set correctly, but the java command still couldn’t find the jedis jar file. Even running my program from the container bash shell didn’t work, it gets the same error.

Verify if the jar has the class indicating to be not found. Is the class name qualified, both for the hello class and the jedis class. All class names should be referred in qualified form , which is including the package name.

Wouldn’t it get a build error if it didn’t? Also when I have the code in my Eclipse IDE, after adding that jar to my build path there are no compile errors.

Also I just tried adding the fully qualified names instead of relying on import but still see the same behavior

The problem ended up being simple, if not time consuming. I had a semi-colon in the classpath definition instead of a colon. Changing it to:

ENV CLASSPATH .:./lib/jedis-2.4.2.jar

and everything works. That’s what I get for using Windows (which uses semi-colons as the separator) :blush:

After upgrading to Oracle JDK 11, i am seeing similar error - java.lang.NoClassDefFoundError: Could not initialize class …

Have validated the class name in the deployed application.jar.
few entry from env -
JAVA_HOME=/usr/lib/jvm/jdk-11.0.2
JAVA_VERSION=11.0.2+7
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Any idea what i should look at ?