简体   繁体   English

如何覆盖存储在 ant lib 目录中的 ant 任务

[英]How to override ant task stored in ant lib directory

At my work we use AspectJ in some of our Java projects.在我的工作中,我们在一些 Java 项目中使用 AspectJ。 To get this to work with ant builds we have been placing aspectjtools.jar within ant/lib/.为了让它与 ant 构建一起工作,我们一直将 aspectjtools.jar 放在 ant/lib/ 中。

I am now working on a particular Java project and need to use a newer version of aspectJ.我现在正在处理一个特定的 Java 项目,需要使用更新版本的 aspectJ。 I don't want to have to get everyone who uses the project to update their local copy of aspectjtools.jar.我不想让每个使用该项目的人都更新他们的 aspectjtools.jar 的本地副本。 Instead, I tried adding the newer aspectjtools.jar to the lib directory of the project and adding the following line to build.xml.相反,我尝试将较新的 aspectjtools.jar 添加到项目的 lib 目录中,并将以下行添加到 build.xml。

  <taskdef
     resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"
     classpath="./lib/aspectjtools.jar" />

However, this doesn't work as I hoped as the ANT classloader loads jars from ant/lib/ in preference to the jar I specify in the taskdef classpath.但是,这并没有像我希望的那样工作,因为 ANT 类加载器从 ant/lib/ 加载 jar 优先于我在 taskdef 类路径中指定的 jar。

Is there any way to force ant to pick the jar checked into my project instead?有什么方法可以强制 ant 选择签入我项目的 jar 吗?

can't you just update the iajc compile target to use the new jar on the classpath?你不能只更新iajc 编译目标以在类路径上使用新的jar 吗?

It's not possible to force the classloader to prefer a given jar file over another one.不可能强制类加载器优先选择给定的 jar 文件而不是另一个。 If you must relate to several version of the same class, then you should consider OSGI.如果你必须涉及同一个类的多个版本,那么你应该考虑 OSGI。

The simplest solution will be to just use libraries from the project or a Maven/Ivy repository and ignore the libraries in your global ant folder.最简单的解决方案是只使用项目或 Maven/Ivy 存储库中的库,而忽略全局 ant 文件夹中的库。

An example:一个例子:

 <taskdef 
     resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
      <classpath>
         <pathelement location="${basedir.dir}/lib/aspectjtools.jar"/>
      </classpath>
 </taskdef>

 <target name="compile" >
    <iajc outjar="demo.jar">
        <sourceroots>
            <pathelement location=”src” />
        </sourceroots>
        <aspectpath>
            <pathelement 
              location="aspects_to_be_weaved_with_classes_in_sourceroots.jar" />
        </aspectpath>
        <classpath>
            <pathelement location="${basedir}/lib/aspectjrt.jar"/>
        </classpath>
    </iajc>
  </target>

Updated: You also have to use another Ant.更新:您还必须使用另一个 Ant。 If you're using Eclipse, try the bundled one directly from the Ant view.如果您使用的是 Eclipse,请直接从 Ant 视图中尝试捆绑的。

You also have another option, but it's a little bit more difficult.您还有另一种选择,但有点困难。 That is to use AspectJ load-time weaving instead.那就是使用 AspectJ 加载时编织来代替。 If you go for that option, you can compile with an ordinary compile task, but you have to do the weaving with an JVM agent at startup.如果选择该选项,则可以使用普通的编译任务进行编译,但必须在启动时使用 JVM 代理进行编织。 You can read more about it here .你可以在这里阅读更多关于它的信息。

I hope this helps!我希望这有帮助!

The ultimate answer to my question is no.我的问题的最终答案是否定的。 The is currently no way for ANT to use a task jar from a project in preference to a task jar in the ANT lib directory. ANT 目前无法使用项目中的任务 jar 优先于 ANT lib 目录中的任务 jar。

This is possible.这个有可能。 You need to make use of this extra task to create a new class loader你需要利用这个额外的任务来创建一个新的类加载器

http://enitsys.sourceforge.net/ant-classloadertask/ http://enitsys.sourceforge.net/ant-classloadertask/

    <!--Append the dependent jars to the classpath so we don't have to install them in the ant directory-->
    <taskdef resource="net/jtools/classloadertask/antlib.xml"
             classpath="${basedir.dir}/lib/ant-classloadertask.jar"/>

    <classloader loader="ant.aspectj.loader" parentloader="project">
        <classpath>
            <pathelement location="${basedir.dir}/lib/aspectjtools.jar"/>
            <pathelement location="${basedir.dir}/lib/ant-classloadertask.jar"/>
        </classpath>
        <antparameters parentfirst="false"/>
        <handler loader="org.apache.tools.ant.AntClassLoader" adapter="org.apache.tools.ant.taskdefs.classloader.adapter.AntClassLoaderAdapter"/>
    </classloader>

    <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"
             classpath="${basedir.dir}/lib/aspectjtools.jar""
             loaderref="ant.aspectj.loader"/>

I just had a similar problem when using Spotbugs in a project while still having findbugs-ant.jar installed globally in ant/lib .我在项目中使用 Spotbugs 时遇到了类似的问题,而findbugs-ant.jar仍然全局安装在ant/lib中。 I wanted to find a way to get this working without having to delete the findbugs jar from the ant installation (that's still used by other project branches).我想找到一种方法来让它工作,而不必从 ant 安装中删除 findbugs jar(其他项目分支仍在使用)。

While I did not find any possibility to declare this inside build.xml , ant's -lib command line argument did the trick:虽然我没有发现build.xml中声明它的任何可能性,但 ant 的-lib命令行参数起到了作用:

From ant documentation:来自蚂蚁文档:

Additional directories to be searched may be added by using the -lib option.可以使用 -lib 选项添加要搜索的其他目录。 The -lib option specifies a search path. -lib 选项指定搜索路径。 Any jars or classes in the directories of the path will be added to Ant's classloader.路径目录中的任何 jar 或类都将添加到 Ant 的类加载器中。 The order in which jars are added to the classpath is as follows:将 jars 添加到类路径的顺序如下:

  • jars in the order specified by the -lib options on the command line jars 按照命令行上的 -lib 选项指定的顺序
  • jars from ${user.home}/.ant/lib (unless -nouserlib is set)来自 ${user.home}/.ant/lib 的 jars(除非设置了 -nouserlib)
  • jars from ANT_HOME/lib来自 ANT_HOME/lib 的罐子

So by specifying my local spotbugs installation in the -lib argument, I was able to run the ant build and make ant's class loader prefer these spotbugs jar files to the older findbugs jar in ANT_HOME/lib.因此,通过在-lib 参数中指定我的本地spotbugs 安装,我能够运行ant 构建并使ant 的类加载器更喜欢这些spotbugs jar 文件而不是ANT_HOME/lib 中较旧的findbugs jar。

example ant call:蚂蚁调用示例:
ant -lib my/local/path/to/spotbugs/lib spotbugs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM