好的,所以这就是我们所拥有的:
我们有两个库包,我们已经编译成罐子。
package starwars; public class JarJar { public void JarSayHello() { System.out.println("Jaaaaar!!"); } }
package barwars; public class BarBar { public void BarSayHello() { System.out.println("Baaaaa!!"); } }
我们用
编译它们javac -d bin -sourcepath src src/barwars/BarBar.java jar cvf barwars.jar -C bin .
和
javac -d bin -sourcepath src src/starwars/JarJar.java jar cvf starwars.jar -C bin .
很好地为我们准备了罐子。
现在我们想将这两个jar包含到另一个java项目中。
所以我们有
package a_pack; import starwars.JarJar; import barwars.BarBar; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World"); JarJar myJar = new JarJar(); myJar.JarSayHello(); BarBar myBar = new BarBar(); myBar.BarSayHello(); } }
Manifest.txt
Main-Class: a_pack.HelloWorld Class-Path: libs/starwars.jar libs/barwars.jar
现在我们用以下代码编译:
javac -d bin -sourcepath src -cp "libs/starwars.jar;libs/*" src/a_pack/HelloWorld.java jar cvfm helloworld.jar manifest.txt -C bin .
这个编译运行正常。
现在我有两个问题。
首先 - 如果我将此jar文件移动到其他地方,并尝试运行它,那么我会得到:
Exception in thread "main" java.lang.NoClassDefFoundError: starwars/JarJar
现在我可以通过将libs文件夹移动到我移动jar的位置来解决这个问题。但是这让我觉得很乱(如果那个位置已经有一个libs文件夹怎么办?)。
理想情况下,我想要做的是在jar中包含引用的jar,所以有一个jar包含在其自身内部运行所需的所有内容。
这可能吗? (这是好的做法吗?)
答案 0 :(得分:7)
可能,是的。好的做法,没有。
Jars只是zip文件,因此您可以解压缩并重新压缩内容。随着项目规模的扩大,更大的问题是管理所有这些独立的罐子。
大多数项目不使用命令行进行编译。相反,IDE可以让您的罐子保持最新状态。大多数现代Java项目都使用Maven或Ivy将jar放在存储库中,并根据需要将它们删除。
查看Eclipse的Eclipse,Netbeans或Intellij。并研究Maven来构建您的项目。