使用自定义清单创建jar,其中包含classpath中的多个库

时间:2012-06-07 09:47:54

标签: java eclipse jar manifest

我正在尝试从我的eclipse创建一个jar,为了能够使用外部.jars,我在类路径中使用这个带有多个.jars的清单:

Manifest-Version: 1.0
Sealed: true
Main-Class: src.BatchTester
Class-Path: . P:/Tools/xstream/1.4.2/lib/kxml2-2.3.0.jar P:/Tools/xstream/1.4.2/lib/xstream-1.4.2.jar P:/Tools/StringTemplate/4.0.5/lib/antlr-3.3-complete.jar P:/Tools/StringTemplate/4.0.5/lib/ST-4.0.5.jar P:/Tools/Jdbc/lib/sqljdbc4.jar

显然,如果我不将库放在类路径中,则会出现以下错误:

java.lang.NoClassDefFoundError: com/thoughtworks/xstream/XStream

但是当我把它们放在类路径中时,错误会变为:

java.lang.NoClassDefFoundError: src/BatchTester

所以它看起来无法找到我的主要课程。我在类路径中尝试了几种可能性,比如在类路径中添加或删除.,但无法使其工作。

我怎么能解决这个问题?

感谢您的时间和精力,


PS:创建.jar后,清单里面的类路径看起来像:

Class-Path: . P:/Tools/xstream/1.4.2/lib/kxml2-2.3.0.jar P:/Tools/xstr
 eam/1.4.2/lib/xstream-1.4.2.jar P:/Tools/StringTemplate/4.0.5/lib/ant
 lr-3.3-complete.jar P:/Tools/StringTemplate/4.0.5/lib/ST-4.0.5.jar P:
 /Tools/Jdbc/lib/sqljdbc4.jar 

使用新的行和空格,但即使将其更改为“正确”格式,我也遇到了同样的问题。

PS2:我知道有一些像Fat-Jar这样的插件你可以使它工作,但我不想在我的.jar中插入比需要更多的数据

3 个答案:

答案 0 :(得分:7)

最后我将所有的libs复制到了/ lib文件夹中,然后将它们添加到带有ant目标的.jar中,因为IT人员似乎没问题(因为它是一个小应用程序)。

这是蚂蚁(如果对某人有用):

<?xml version="1.0" encoding="UTF-8"?>
<project name="BatchTester" default="compile" basedir=".">
    <property name="external" value="lib/external-libs.jar"/>
    <target name="compile">
        <javac srcdir="jav"
               source="1.6"
        />
        <echo>Creating jar File</echo>
        <!--create a new .jar with all the external jars in /lib-->
        <jar jarfile="${external}">
            <zipgroupfileset dir="lib/">
                <include name="**/*.jar"/>
            </zipgroupfileset>
        </jar>
        <!--<sleep seconds="1"/>-->
        <!--create .jar file-->
        <jar jarfile="BatchTester.jar" index="true" filesetmanifest="mergewithoutmain">
            <fileset dir=".">
                <include name="**/jav/**/*.class"/>
                <exclude name="**/jav/**/*.java"/>
            </fileset>
            <zipfileset src="${external}">
                <exclude name="META-INF/*.SF"/>
            </zipfileset>
            <manifest>
                <attribute name="Main-Class" value="jav.BatchTester"/>
            </manifest>
        </jar>
        <!--delete previously created extern .jar-->
        <delete file="${external}"/>
    </target>
</project>

答案 1 :(得分:2)

抱歉,如果我的问题听起来很明显。


* 启动命令*

为了排除任何疑问,你是不是试图用这种命令启动你的jar?

java -jar myJar.jar -cp ./lib

如果使用classpath选项,则可能没有;)。选项--classpath(或-cp)和-jar不能一起使用。

也喜欢使用相对路径,比如./lib而不是P:/ Tools / ......但是,无论如何,这都无法解决你的问题。


* 套餐位置*

正如brimborium所说,你真正的包装是什么? src听起来很奇怪。我们怀疑这是一个错误。

在BatchTester类中,您为package指令编写了什么?没什么(即没有推荐的默认包装?)?

你上课是否开始(摆脱评论)

public class BatchTester {

在这种情况下,当然不应该提及src。

这是一个适用于我的清单示例。

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: jrRevy
Build-Jdk: 1.6.0_31
Main-Class: com.sopragroup.training.dojo1.MainSwingApp
Class-Path: dojo1-0.5.0-SNAPSHOT-lib/spring-core-3.1.1.RELEASE.jar doj
 o1-0.5.0-SNAPSHOT-lib/spring-asm-3.1.1.RELEASE.jar [blablabla]

具有以下执行结构

/
|
+ --dojo1-0.5.0-SNAPSHOT.jar
|
+ --dojo1-0.5.0-SNAPSHOT-lib/
    |
    + --spring-core-3.1.1.RELEASE.jar

显然,我正在使用maven构建我的应用程序,但主要的想法是在。

答案 2 :(得分:0)

清单不允许在 Class-Path:标记中使用绝对路径。您有两种选择:

  • 使用您自己在答案中已经提到的相对路径
  • 通过文件协议使用绝对路径。这也已在其他地方得到解答,它可以absolute versus relative path names in jar manifest

    使用

    Class-Path:file:/// P:/Tools/xstream/1.4.2/lib/kxml2-2.3.0.jar

此外,在没有几个限制的情况下,您不应该手动编辑manifest.mf:

  • 每行的最大长度不能超过72个字符,并且在中断一行之后,您必须在第一列中插入一个空格。
  • 最后一行之后必须有一个回车符,否则,文件将无法正确解析