我有NetBeans 6.8,我写了一个有两个库(jar文件)的类。 建立它,我得到一个带有project.jar的“dist”文件夹和一个包含两个lib jar文件的“lib”文件夹。
我怎么能在一个jar文件中得到所有这些? (我不使用Maven / Ant或类似的东西。)
答案 0 :(得分:13)
基本问题是当前版本的Java不支持开箱即用的jar中的jar。
推荐的解决方案是使用jar内MANIFEST.MF文件中的Class-Path行指向所需的库(允许相对路径),然后将所有文件一起部署并使用“java -jar your。”调用它。罐“
如果你真的想要一个“jar-inside-jar”解决方案,我们已经使用了一个罐子好几年了,但是因为我们的目标JVM在上述解决方案中运行得更好,所以它已经不再使用了。
http://one-jar.sourceforge.net/
我在Eclipse中使用了fatjar插件。我没有任何将它构建到Netbeans的经验,但是很容易构建成一个蚂蚁脚本,我相信这就是NEtbeans所使用的。
答案 1 :(得分:12)
您可以在build.xml文件中创建额外的构建目标。
并使用zipfileset
和zipgroupfileset
创建一个大jar
e.g。
<target name="YourBigJar" depends="-post-jar">
<jar destfile="BigJar.jar">
<zipfileset src="dist/Project1.jar"/>
<zipfileset src="../OtherProject/dist/project2.jar"/>
<zipgroupfileset dir="../libs/."/>
</jar>
</target>
答案 2 :(得分:12)
我同意Waverick的观点。使用NetBeans执行此操作的最简单方法是将自定义目标添加到build.xml。 (顺便说一下,由于使用NetBeans,您使用的是Ant,因为NetBeans使用Ant来构建您的jar文件。)
Waverick的Ant目标似乎旨在将来自不同NetBeans项目的已编译代码合并到当前项目的jar文件中。我的目标完全符合您的要求。
<target name="-unjar-and-copy-lib-jars">
<unjar dest="${build.classes.dir}">
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<patternset>
<exclude name="META-INF/**"/>
<exclude name="/*"/>
</patternset>
</unjar>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar,-unjar-and-copy-lib-jars" name="fat-jar">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<jar destfile="${dist.jar}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target depends="clean,fat-jar" name="clean-and-fat-jar"/>
答案 3 :(得分:3)
我找到了一篇好文章here。但似乎值得一提的是它要求dest / lib文件夹中的外部库。你可以这样做,但通常我们在根文件夹中有lib文件夹(或者我拥有的)。如果只是改变
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
到
<zipgroupfileset dir="/lib" includes="*.jar"/>.
就是这样。
答案 4 :(得分:1)
您可以使用Java以Class.getResourceAsStream()
和FileOutputStream
编程方式安装外部库。图书馆通常会进入Java\lib\ext\
。
以下是我接触它的方式:
我将我用过的所有JAR的副本放入.res
子包中。从那里,我可以将它们复制到任何地方。
private void installLibraries() {
new Thread() {
@Override
public void run() {
System.out.println("Checking for libraries");
File jre = new File(System.getProperty("java.home"));
File jar = new File(jre, "lib/ext/JAR_NAME.jar");
//Create more File objects that wrap your JAR's
try {
boolean added = false;
if (!jar.exists()) {
copyResource(jar, "JAR_NAME.jar");
added = true;
}
//Repeat for more JAR's
if (added) {
System.out.println("Libraries installed.");
} else {
System.out.println("Library check complete");
} catch (IOException ex) {
System.out.println("Library installation failed.");
ex.printStackTrace(System.out);
}
}
private void copyResource(File dest, String src) throws IOException {
System.out.println("Copying resource " + src + " to " + dest);
InputStream in = THIS_CLASS_NAME.class.getResourceAsStream("/YOUR_PACKAGE/res/" + src);
dest.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int i = 0;
while ((i = in.read(buffer)) > 0) {
out.write(buffer, 0, i);
}
out.close();
in.close();
}
}.start();
}
在执行任何其他操作之前运行此方法,您可以完全忽略Netbeans为您提供的外部JAR文件,并只分发该文件。另外,我使用此方法安装javax.comm
,它不喜欢在外部分发。它带有.dll文件和属性文件。这些文件可以使用完全相同的方法安装,但值得注意的是.dll文件必须放在Java\lib\
目录中,属性文件放在Java\lib\
目录中(不在{{1}中文件夹)。