【问题标题】:custom ant task with additional libraries带有附加库的自定义 ant 任务
【发布时间】:2014-03-31 01:57:01
【问题描述】:

我正在用java为ant编写一个自定义任务,我的想法是我可以给某人一个.jar,其中包含java文件,如类和库以及ant的build.xml,他可以使用它。

如果我导出我的 java 项目,.jar (antTask.jar) 包含: 一个用于编译类的文件夹,一个用于库、meta-inf 文件夹和 .classpath .project 文件

ant build.xml 如下所示:

<?xml version="1.0" ?>
<project name="repair" basedir="." default="repairTask">    
<taskdef name="antTask" classpath="antTask.jar" classname="def.RepairTask"/>
<target....

我真的不明白所有这些类路径的东西,所以有人可以告诉我我必须在我的构建文件中添加什么,以便它只适用于没有 java 代码源的这个 .jar 文件吗?

现在我收到一个错误,即 ant 找不到我在 java 代码中使用的库之一(但 antTask.jar 包含此库作为另一个 .jar):

taskdef A class needed by class def.RepairTask cannot be found: org/apache/commons/...      
using the classloader AntClassLoader[C:...\AntTask\antTask.jar]

我尝试了好几个小时,但我只是不知道如何编辑我的 build.xml,所以我只需要指向这个单个 .jar 文件,它就可以工作..

谢谢大家

【问题讨论】:

  • 你能把 Ant 的整个错误信息贴出来吗?我怀疑您正在引用第三方 JAR(如 Apache StringUtils),在您使用自定义 Ant 任务的后续项目中您可能没有引用该 JAR。
  • taskdef 找不到类 def.RepairTask 所需的类:org/apache/commons/io/input/BOMInputStream 使用类加载器 AntClassLoader[C:...\antTask.jar]。是的,它是第三方库。但它包含在生成的 antTask.jar 中,当我使用 eclipse 运行 ant build.xml(我编辑运行配置并添加缺少的 apache jar)时,一切正常,但我现在真的很想知道如何编写这进入 build.xml 所以它可以在没有 eclipse 的情况下工作

标签: java ant jar


【解决方案1】:

taskdef 所做的只是将一个任务名称 关联到一个包含执行该任务的代码的类文件。但是,为了找到该类文件,您需要告诉&lt;taskdef/&gt; 在哪里可以找到包含它的 jar。这就是类路径所做的一切。

您不必使用&lt;taskdef/&gt; 任务定义类路径。默认情况下,Ant 会在 $ANT_HOME/lib 中查找包含 &lt;taskdef/&gt; 任务代码的所有 jar。如果您将 jar 复制到该文件夹​​,您可以简单地以这种方式定义该任务:

<taskdef name="antTask" classname="def.RepairTask"/>

不需要类路径。但是,我实际上不建议这样做。相反,我建议将该 jar 文件放入您的项目中,这样其他开发人员就可以使用您的项目,而无需将该任务 jar 安装到他们的 $ANT_HOME/lib 文件夹中:

<taskdef name='antTask' classname="def.RepairTask">
    <classpath>
        <fileset dir="${basedir}/antlib/antjar"/>
    </classpath>
</taskdef>

现在,当开发人员签出需要可选任务 jar 的项目时,该任务 jar 会随项目一起提供,因此他们可以简单地进行构建。

有两种定义任务的方法。一种是给一个任务一个名字,然后告诉&lt;taskdef/&gt;什么类文件与那个jar相关联,就像你在上面所做的那样。但是,您也可以定义一个 resource,它将任务名称与其类相关联。这是包含Ant-Contrib ant tasks 的常用方法:

<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <fileset dir="${basedir}/antlib/antcontrib"/>
    </classpath>
</taskdef>

如果我展开 antcontrib jar,我会看到它在 jar 中包含一个 net/sf/antcontrib/antcontrib.properties1 文件。该文件如下所示:

...
# Logic tasks
if=net.sf.antcontrib.logic.IfTask
foreach=net.sf.antcontrib.logic.ForEach
throw=net.sf.antcontrib.logic.Throw
trycatch=net.sf.antcontrib.logic.TryCatchTask
switch=net.sf.antcontrib.logic.Switch
outofdate=net.sf.antcontrib.logic.OutOfDate
runtarget=net.sf.antcontrib.logic.RunTargetTask
timestampselector=net.sf.antcontrib.logic.TimestampSelector
antcallback=net.sf.antcontrib.logic.AntCallBack
antfetch=net.sf.antcontrib.logic.AntFetch
assert=net.sf.antcontrib.logic.Assert
relentless=net.sf.antcontrib.logic.Relentless

# Math Tasks
math=net.sf.antcontrib.math.MathTask
...

它所做的只是为每个任务定义一个类文件。我建议您对自定义 ant 任务执行类似的操作。这样,如果您决定包含其他任务,只需修改这个文件,开发人员就不必更改其 jar 中的 &lt;taskdef/&gt; 定义,或添加多个。

顺便说一句,您应该做好并确保您的课程不会与其他人可能使用的其他课程发生冲突。您可能希望为您的类名提供一个包含唯一前缀的完整路径:

<taskdef name='antTask' classname="com.vegicorp.anttasks.RepairTask">

假设你为 VegiCorp 工作......


1 Ant contrib 任务包含两个这样的文件。一种是 XML 格式,另一种是属性格式。我总是使用 XML 格式,这就是您在定义 Ant 任务资源时假设使用的格式。我使用了属性文件,因为它的格式更简单,更容易查看发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多