gradle run executes; compiled JAR crashes with ClassNotFoundException

Why does the client JAR crash, java.lang.NoClassDefFoundError, caused by ClassNotFoundException, yet run from gradle works fine? There's a problem with how the client uses the library JAR?

thufir@mordor:~/NetBeansProjects/hello_client$ 
thufir@mordor:~/NetBeansProjects/hello_client$ gradle clean build
Starting a new Gradle Daemon for this build (subsequent builds will be faster).
Download https://jitpack.io/com/github/THUFIR/hello_api/dev/hello_api-dev.pom
Download https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.4.1/groovy-all-2.4.1.pom
Download https://jitpack.io/com/github/THUFIR/hello_api/dev/hello_api-dev.jar
Download https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.4.1/groovy-all-2.4.1.jar
Changed strategy of configuration ':compile' after it has been resolved. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:startScripts
:distTar
:distZip
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 1 mins 11.959 secs
thufir@mordor:~/NetBeansProjects/hello_client$ 
thufir@mordor:~/NetBeansProjects/hello_client$ java -jar build/libs/hello_client.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: net/bounceme/mordor/hello/library/HelloLibrary
    at net.bounceme.mordor.hello.client.Client.runLibrary(Client.java:13)
    at net.bounceme.mordor.hello.client.Client.main(Client.java:9)
Caused by: java.lang.ClassNotFoundException: net.bounceme.mordor.hello.library.HelloLibrary
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 2 more
thufir@mordor:~/NetBeansProjects/hello_client$ 
thufir@mordor:~/NetBeansProjects/hello_client$ gradle clean run
Changed strategy of configuration ':compile' after it has been resolved. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
hello [fred]

BUILD SUCCESSFUL

Total time: 4.66 secs
thufir@mordor:~/NetBeansProjects/hello_client$ 

As it should, above output is "hello [fred]", which is fine. The hello world client code:

package net.bounceme.mordor.hello.client;

import static java.lang.System.out;
import net.bounceme.mordor.hello.library.HelloLibrary;

public class Client {

    public static void main(String[] args) {
        new Client().runLibrary();
    }

    private void runLibrary() {
        HelloLibrary library = new HelloLibrary();
        out.println(library.hello("fred"));
    }

}

Netbeans complains about the import statement for net.bounceme.mordor.hello.library.HelloLibrary, which would seem to be correct:

thufir@mordor:~$ 
thufir@mordor:~$ cp .gradle/caches/modules-2/files-2.1/com.github.THUFIR/hello_api/dev/fa670823cfe9548b87c75f224a48a1089eab0b35/hello_api-dev.jar jar
thufir@mordor:~$ 
thufir@mordor:~$ cd jar
thufir@mordor:~/jar$ 
thufir@mordor:~/jar$ jar -xf hello_api-dev.jar 
thufir@mordor:~/jar$ 
thufir@mordor:~/jar$ cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0

thufir@mordor:~/jar$           
thufir@mordor:~/jar$ ll net/bounceme/mordor/hello/library/HelloLibrary.class 
-rw-rw-r-- 1 thufir thufir 728 Mar 11  2016 net/bounceme/mordor/hello/library/HelloLibrary.class
thufir@mordor:~/jar$ 

Here is the client JAR:

thufir@mordor:~/NetBeansProjects/hello_client$              
thufir@mordor:~/NetBeansProjects/hello_client$ cd build/libs/
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ jar -xf hello_client.jar 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Main-Class: net.bounceme.mordor.hello.client.Client
Class-Path: hello_api-dev.jar groovy-all-2.4.1.jar

thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ ll net/bounceme/mordor/hello/client/Client.class 
-rw-rw-r-- 1 thufir thufir 912 Mar 11 02:28 net/bounceme/mordor/hello/client/Client.class
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 

and it seems, to me, that the classpath includes hello_api-dev.jar correctly.

This seems notable:

Where possible, avoid using dependencies in the manner of compile fileTree(dir: 'lib', include: ['*.jar']). Managed dependencies based on a repository such as Maven or JCenter are much easier to work with consistently than dependencies in a random directory. If these are internal libraries that you don't want to publish to an open-source artifact repository, then it may be worth setting up a local Nexus instance or similar.

https://stackoverflow.com/a/35304025/262852

However, I'm not quite sure whether that's the problem, as I seem to be using the correct JAR, with the correct packaging, from jitpack.

I even added the libary to a libs folder for the client:

thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ jar -vft hello_client.jar 
     0 Fri Mar 11 02:50:28 PST 2016 META-INF/
   135 Fri Mar 11 02:50:28 PST 2016 META-INF/MANIFEST.MF
     0 Fri Mar 11 02:50:28 PST 2016 net/
     0 Fri Mar 11 02:50:28 PST 2016 net/bounceme/
     0 Fri Mar 11 02:50:28 PST 2016 net/bounceme/mordor/
     0 Fri Mar 11 02:50:28 PST 2016 net/bounceme/mordor/hello/
     0 Fri Mar 11 02:50:28 PST 2016 net/bounceme/mordor/hello/client/
   927 Fri Mar 11 02:50:28 PST 2016 net/bounceme/mordor/hello/client/HelloClient.class
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ jar -vft libs/hello_api-dev.jar 
     0 Fri Mar 11 01:59:38 PST 2016 META-INF/
    25 Fri Mar 11 01:59:38 PST 2016 META-INF/MANIFEST.MF
     0 Fri Mar 11 01:59:38 PST 2016 net/
     0 Fri Mar 11 01:59:38 PST 2016 net/bounceme/
     0 Fri Mar 11 01:59:38 PST 2016 net/bounceme/mordor/
     0 Fri Mar 11 01:59:38 PST 2016 net/bounceme/mordor/hello/
     0 Fri Mar 11 01:59:38 PST 2016 net/bounceme/mordor/hello/library/
   728 Fri Mar 11 01:59:38 PST 2016 net/bounceme/mordor/hello/library/HelloLibrary.class
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ java -jar hello_client.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: net/bounceme/mordor/hello/library/HelloLibrary
    at net.bounceme.mordor.hello.client.HelloClient.runLibrary(HelloClient.java:13)
    at net.bounceme.mordor.hello.client.HelloClient.main(HelloClient.java:9)
Caused by: java.lang.ClassNotFoundException: net.bounceme.mordor.hello.library.HelloLibrary
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 2 more
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 

which begs the question: why doesn't gradle copy the library over for the client?

Answers


kludge:

thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ cp /home/thufir/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy-all/2.4.1/a9ca9c9de09361ec2a18d2c058d2524fbd8eae0c/groovy-all-2.4.1.jar hello_api-dev.jar hello_client.jar .
cp: ‘hello_api-dev.jar’ and ‘./hello_api-dev.jar’ are the same file
cp: ‘hello_client.jar’ and ‘./hello_client.jar’ are the same file
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ jar -i hello_client.jar 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ ll
total 6816
drwxrwxr-x 2 thufir thufir    4096 Mar 11 03:41 ./
drwxrwxr-x 6 thufir thufir    4096 Mar 11 03:30 ../
-rw-rw-r-- 1 thufir thufir 6937913 Mar 11 03:41 groovy-all-2.4.1.jar
-rw-rw-r-- 1 thufir thufir    1422 Mar 11 03:39 hello_api-dev.jar
-rw-rw-r-- 1 thufir thufir    2722 Mar 11 03:41 hello_client.jar
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ java -jar hello_client.jar 
hello [fred]
thufir@mordor:~/NetBeansProjects/hello_client/build/libs$ 

1.) why does this work?

2.) what's the correct way to build these JAR's?

This has to be one of the few, if not only, case where Reading the Fine Manual actually was useful. I saw the "i" switch, and it showed:

thufir@mordor:~/NetBeansProjects/hello_client$ 
thufir@mordor:~/NetBeansProjects/hello_client$ jar -i build/libs/hello_client.jar 
java.io.FileNotFoundException: build/libs/hello_api-dev.jar (No such file or directory)
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.tools.jar.Main.getJarPath(Main.java:1163)
    at sun.tools.jar.Main.getJarPath(Main.java:1179)
    at sun.tools.jar.Main.genIndex(Main.java:1195)
    at sun.tools.jar.Main.run(Main.java:317)
    at sun.tools.jar.Main.main(Main.java:1288)
thufir@mordor:~/NetBeansProjects/hello_client$ 

However, I don't really understand that output, just found it curious that it was a "file not found" exception.


Need Your Help

Invoke at runtime the customization panel of a Telerik's RadLayoutControl

c# .net vb.net winforms telerik

I'm using the RadLayoutControl control from Telerik UI for Winforms.

Is it better to put Facebook SSO in onCreate or onStart Method?

android facebook oncreate onstart

Is it better to put the Facebook Single Sign on Authentication process in the onCreate or onStart method?