好的,这就是我们得到的:
我们有两个库包,我们已经编译成 jar .
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 里 .
现在我们想将这两个jar包含到另一个java项目中 .
所以我们有
-
/project/src/a_pack/HelloWorld.java
-
/project/libs/starwars.jar
-
/project/libs/barwars.jar
-
/project/manifest.txt
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包含在其自身内部运行所需的所有内容 .
这可能吗? (这是好的做法吗?)
1 回答
可能,是的 . 好的做法,没有 .
Jars只是zip文件,因此您可以解压缩并重新压缩内容 . 随着项目规模的扩大,更大的问题是管理所有这些独立的 jar .
大多数项目不使用命令行进行编译 . 相反,IDE可以让您的 jar 保持最新状态 . 大多数现代Java项目都使用Maven或Ivy将jar放入存储库并根据需要将它们删除 .
查看Eclipse的Eclipse,Netbeans或Intellij . 并研究Maven来构建您的项目 .