包含外部.jar文件的Ant文件

7

我想将外部的jar包包含到我的Java项目中,我正在使用Ant。外部的.jar文件在lib文件夹中。我的build.xml文件大致如下:

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <path id="classpath">
        <fileset dir="lib" includes="**/*.jar"/>
    </path>

    <target name="clean">
        <delete dir="build"/>
    </target>

    <target name="compile">
        <mkdir dir="build"/>
        <javac srcdir="src" destdir="build" classpathref="classpath" />
    </target>

    <target name="jar">
        <mkdir dir="trash"/>
        <jar destfile="trash/test.jar" basedir="build">
            <zipgroupfileset dir="lib" includes="**/*.jar"/>
            <manifest>
                <attribute name="Main-Class" value="com.Test"/>
            </manifest>
        </jar>
    </target>

    <target name="run">
        <java jar="trash/test.jar" fork="true"/>
    </target>
</project>

但是它不起作用。当我想从外部 .jar 文件中导入一些东西时,在执行 ant compile 命令后会出现错误:package com.something 不存在。我应该编辑什么才能使它正常工作?

具体的错误信息:

  Compiling 23 source files to xy/build
  xy/src/com/Test.java:5: package com.thoughtworks.xstream does not exist
  import com.thoughtworks.xstream.*;
  ^
  1 error

你能否编辑你的问题,提供给我们确切的错误信息? - Tom
我已添加了确切的错误。 - Pajushka
在普通的jar包中很难轻松地包含外部库。你需要像one-jar这样的特殊任务来完成它。 - oers
4个回答

4

您可以尝试不使用includes属性:

<fileset dir="lib" />

并且在jar包的部分,您可以像这样包含类:
<zipgroupfileset includes="*.jar" dir="lib"/>

1

你不能将外部库放入一个jar文件中,并期望类加载器使用这些jar文件。不幸的是,这是不被支持的。

有一些ant任务,比如one jar,可以帮助你创建一个包含所需内容的jar文件。

以下内容来自于one jar的背景信息

不幸的是,这种方法行不通。Java Launcher$AppClassLoader无法加载嵌套在另一个jar文件中的jar文件中的类。尝试使用jar:file:jarname.jar!/commons-logging.jar也会走进死胡同。只有当你将支持的jar文件安装(即散布)到jarname.jar文件所在的目录中时,这种方法才能生效。

另一种方法是解压所有依赖的jar文件,并将它们重新打包到jarname.jar文件中。这种方法往往容易出错且速度较慢,并且可能会遇到重复资源的问题。

其他替代方案:

  • jarjar:Jar Jar Links是一个实用工具,可以轻松地重新打包Java库并将其嵌入到您自己的分发中。

不是完全准确的,例如像Hadoop这样的一些应用程序支持将jar放在一个jar的lib目录中,并且应用程序会处理将它们加入到类路径中。 - David Parks
1
@DavidParks,但这是因为Hadoop使用自己的类加载器。因此,这是应用程序特定的,而不是官方jar定义的一部分。 - oers

0
有时候可以直接使用jar包内容,只需要解压即可。
        <unzip src="/Developer-Java/mysql-connector-java/mysql-connector-java-5.1.22-bin.jar" dest="${build_dir}" />

0

我也使用ant将一些依赖的JAR包包含在我的JAR中。我的编译任务看起来像这样。也许类似的方法对你有用。

<target name="compile" depends="init">
   <javac srcdir="${src}" destdir="${build}" includeantruntime="false">
    <classpath>
      <pathelement path="${classpath}" />
      <fileset dir="${deps}">
         <include name="**/*.jar"/>
      </fileset>
    </classpath>
  </javac>
  <copy todir="${build}">
    <fileset dir="${src}" excludes="**/*.java"/>
  </copy>
</target>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接