为什么 client JAR 崩溃,java.lang.NoClassDefFoundError
,由 ClassNotFoundException
引起,但是从 gradle 中run
工作正常吗?客户端如何使用 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$
正如它应该的那样,上面的输出是“hello [fred]”,这很好。 Hello World 客户端代码:
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 提示 net.bounceme.mordor.hello.library.HelloLibrary
的导入语句,这似乎是正确的:
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$
这是客户端 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$
在我看来,类路径似乎正确地包含了 hello_api-dev.jar
。
这似乎值得注意:
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
但是,我不太确定这是否是问题所在,因为我似乎使用了来自 jitpack 的正确 JAR 和正确的包装。
我什至将库添加到客户端的 libs
文件夹中:
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$
这引出了一个问题:为什么 gradle 不为客户端复制库?
最佳答案
拼凑:
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.) 为什么这样做有效?
2.) 构建这些 JAR 的正确方法是什么?
这必须是为数不多的(如果不是唯一的话)阅读精美手册实际上有用的案例之一。我看到了“i”开关,它显示:
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$
然而,我并不真正理解那个输出,只是觉得好奇这是一个“找不到文件”的异常。
关于java - gradle 运行执行;已编译的 JAR 因 ClassNotFoundException 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35937896/