我对某些外部jar有运行时依赖性,我想“重新”到一个jar中。这些外部依赖项存储在external_jars目录中,我希望不必全部列出它们(即,如果我的依赖项发生更改,则不需要更改构建脚本)。有什么想法吗?
Google为我提供了一个很好的答案 - 如果你不介意将每个jar列为依赖:
http://markmail.org/message/zijbwm46maxzzoo5
粗略地说,我想要下面的内容,将lib目录中的所有jar组合成out.jar(带有一些合理的覆盖规则)。
jar -combine -out out.jar -in lib/*.jar
答案 0 :(得分:65)
弗拉基米尔的答案是正确的,但我觉得他的建议意味着重新包装一个大的out.jar中的所有罐子,然后将其作为单个<zipfileset>
或类似的东西送到Ant Jar任务。这种两步法是不必要的。我不确定这是否与Ant版本相关联,但我有Ant 1.7.1,其<jar>
任务理解<zipgroupfileset>
,它允许直接提供第三方罐子的所有内容。
<jar destfile="MyApplication.jar">
<zipgroupfileset dir="lib" includes="*.jar" />
<!-- other options -->
<manifest>
<attribute name="Main-Class" value="Main.MainClass" />
</manifest>
</jar>
答案 1 :(得分:54)
只需将zipgroupfileset
与Ant Zip task
<zip destfile="out.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</zip>
这将使所有包含的jar库内容变得扁平化。
答案 2 :(得分:23)
你可以查看jarjar:
答案 3 :(得分:9)
首先尝试将JAR提取到编组目录:
<target name="combine-jars">
<mkdir dir="${marshall.dir}"/>
<unzip dest="${marshall.dir}">
<fileset dir="${external.jar.dir}">
<include name="**/*.jar"/>
</fileset>
</unzip>
<jar destfile="${combined.jar}" basedir="${marshall.dir"}>
<delete dir="${marshall.dir}"/>
</target>
${marshall.dir}
是临时目录,${external.jar.dir}
是保留JAR的地方,${combined.jar}
是目标JAR。
答案 4 :(得分:4)
如果使用maven,为什么不呢? :) 只需使用maven-shade-plugin,就像魅力一样!
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
答案 5 :(得分:2)
这是我的解决方案:
<target name="-post-jar">
<echo>Packaging ${application.title} into a single JAR</echo>
<jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar">
<zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/>
<zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
</target>
答案 6 :(得分:1)
您是否考虑过使用Maven或其他自动管理依赖项的系统?然后,您不需要指定每个库的位置,它们的名称以及您的直接依赖项具有的传递依赖性。您只需在一个位置说明依赖关系及其版本是什么,系统将负责下载库,配置类路径和构建项目。
答案 7 :(得分:1)
这个问题得到了很好的回答。我想提一个我觉得有用的工具 - One-Jar。 One-Jar更干净地处理资源(通过保留所有资源)。如果代码需要process MANIFEST files.
,这会更有用从网站复制的示例XML ..
<import file="one-jar-ant-task.xml"/>
<target name="hello" depends="init">
<!-- Build lib.jar -->
<javac destdir="${classes.dir}/lib">
<src path="${lib.dir}" />
</javac>
<jar destfile="${build.dir}/lib.jar" >
<fileset dir="${classes.dir}/lib"/>
</jar>
<!-- Build classes for main.jar -->
<javac destdir="${classes.dir}/src">
<src path="${src.dir}" />
<classpath path="${build.dir}/lib.jar"/>
</javac>
<!-- Construct the One-JAR file -->
<one-jar destfile="hello.jar" manifest="hello.mf">
<main>
<!-- Construct main.jar from classes and source code -->
<fileset dir="${classes.dir}/src"/>
</main>
<lib>
<fileset file="${build.dir}/lib.jar" />
</lib>
</one-jar>
<echo>
Now you can run the Hello One-JAR example using
$ java -jar hello.jar
</echo>
</target>
答案 8 :(得分:1)
如果你正在用ant构建(我正在使用eclipse中的ant),你可以添加额外的jar文件 通过对蚂蚁说来添加它们...... 如果你有一个由多人维护的项目,但它适用于一个人项目并且很容易,那么这不一定是最好的方法。
例如,构建.jar文件的目标是:
<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
<manifest>
<attribute name="Author" value="ntg"/>
................................
<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
</manifest>
</jar>
我刚添加了一行来制作它:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
,其中
<property name="external-lib-dir" value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
是外部罐子的目录。 就是这样......你也可以添加多个zipgroupfileset标签。
答案 9 :(得分:0)
好吧,我不是那么喜欢编程 - 但是对我来说更简单的东西......如果问题意味着 - 将jar文件合并到一个。当然,这是手动的,肮脏的解决方案。 我只是解开了所有的tars ...然后......通过将untarring-in形成的所有目录添加到新的tar文件中来创建一个新的tar文件。有效。
答案 10 :(得分:0)
Maven或其他构建工具无法“管理”多个版本的类文件的解析。实际上,Maven首先会通过传递包含项目未明确要求的所有下游jar文件来解决这些问题。
假设项目的传递闭包中的某个地方(项目所需的所有库和模块,以及所有它依赖的项目,递归地),有两个版本的类文件。 Maven怎么可能知道哪一个是'正确的'?程序员打算使用哪一个?
它不能,因为当显式依赖关系被抛弃而转向传递时(保存XML类型),此信息丢失了。