Ian Finlayson
Ian Finlayson

Reputation: 311

Why is Java not finding classes that are in the CLASSPATH?

I am trying to install Mooshak which is distributed as a .jar installer. When I run the file, it gives me the following error about a missing class:

ifinlay@mooshak:~$ sudo java -jar MooshakInstaller.jar -cui
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/ArchiveException
    at pt.up.fc.dcc.mooshak.installer.Installer.<init>(Installer.java:26)
    at pt.up.fc.dcc.mooshak.installer.Installer.main(Installer.java:52)
    ... 5 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.compress.archivers.ArchiveException
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:436)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 7 more

So it can't find the org/apache/commons/compress/archivers/ArchiveException class. But I have installed this library and have the following in my CLASSPATH:

ifinlay@mooshak:~$ echo $CLASSPATH
.:/usr/share/maven-repo/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar

And this .jar file in the CLASSPATH does seem to contain the class in question:

ifinlay@mooshak:~$ jar tvf /usr/share/maven-repo/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar

# ... other classes edited out
   722 Fri Mar 01 16:57:28 UTC 2019 org/apache/commons/compress/archivers/ArchiveException.class
# ... other classes edit out

So why can Java not find this class when it does seem to be in the path? Any help would be so awesome, I'm really scratching my head at this.

Thanks for reading!

EDIT: The Manifest file for the .jar looks like this:

Manifest-Version: 1.0
Rsrc-Class-Path: ./ junit.jar org.hamcrest.core_1.3.0.v201303031735.ja
 r commons-compress-1.12.jar BrowserLauncher2-all-1_3.jar
Class-Path: .
Rsrc-Main-Class: pt.up.fc.dcc.mooshak.installer.Installer
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

So this seems to imply that the commons-compress-1.12.jar file should just be placed in the same directory as the installer. This doesn't seem to work though...

Upvotes: 1

Views: 3368

Answers (2)

Stephen C
Stephen C

Reputation: 719189

This answer is based on the new information you provided. It changes things.

First of all, what I said about CLASSPATH and -jar remains true.

However, it turns out that the Mooshak 2 installer is an executable JAR that uses a "jar in jar" loader.

  • The main class is org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.
  • The manifest specifies that the classpath for the installer should include these nested JARs which are part of the installer JAR:

     junit.jar 
     org.hamcrest.core_1.3.0.v201303031735.jar 
     commons-compress-1.12.jar 
     BrowserLauncher2-all-1_3.jar
    
  • The JarRsrcLoader entrypoint classes should then set up classloaders for the above JARs, and then start the installer.

And it should all just work.

I do see one strange thing though. The manifest has commons-compress-1.12.jar, but you seem to be trying to use commons-compress-1.18.jar.

You said:

So this seems to imply that the commons-compress-1.12.jar file should just be placed in the same directory as the installer.

I don't read it that way, but I will see if I can find the documentation.

UPDATE: nope. I couldn't find the documentation, but it seems from the JarRsrcLoader source code, that it doesn't work that way.

But I did find a clue. In the current version of JarRsrcLoader there is separate code for Java 8 and Java 9+. So, if the Mooshak 2.0 installer uses an older version of JarRsrcLoader, AND you are trying to install with Java 9 or later, then it is possible that it won't work.

So, make sure that you use Java 8 ... like the requirements say.


However, what you are apparently trying to do here is to use a different version of the compress library. The better way to do this is to set up your own build tree for Mooshak:

... checkout the full source code with svn checkout https://svn.dcc.fc.up.pt/projects/Mooshak/Mooshak/

Then modify the dependencies and build / install as per the instructions that I presume are in the tree.

Upvotes: 2

Stephen C
Stephen C

Reputation: 719189

Why is Java not finding classes that are in the CLASSPATH?

Short answer: because they are NOT on the actual classpath.

Long answer:

There is either something wrong with the installer, or you are not running it correctly / as it is designed to be run.

When you run a java like this with a -jar option:

java -jar MooshakInstaller.jar -cui

it will ignore the CLASSPATH variable, and any -cp arguments that you add. That explains why Java is not finding classes in the commons-compress-1.18.jar JAR file on your (assumed) classpath.

This means one of the following:

  1. The MooshakInstaller.jar installer is missing a dependency; i.e. it is broken. (I doubt this is the case. They would have spotted this.)
  2. The MooshakInstaller.jar installer is not designed to be run as an executable JAR.

  3. The MooshakInstaller.jar installer is expecting to find the dependency in some location relative to the location of the JAR file. (See if there is a "Class Path" attribute in the JAR's manifest file.)

I would also note that when you run this:

sudo java -jar MooshakInstaller.jar -cui

the value of the CLASSPATH environment variable will probably not be passed through to the root process. Check the manual entry for sudo. This is not the actual problem here ... because the CLASSPATH variable is being ignored anyway, due to the -jar option.


UPDATE

It looks like you simply didn't follow the installation instructions:

To install Mooshak you must execute the following commands. Make sure your system has all requirements. Note that you must have root privileges

% tar xzf mooshak-version.tgz     
% cd mooshak-version
% su      
# ./install

That's not what you did, and I strongly suspect that what you actually did is not equivalent to the above.

(I'm not going to investigate this further, because the download procedure requires me to give them all sorts of personal details. No way Jose!)

Upvotes: 3

Related Questions