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

Java 如何覆盖存储在ant lib目录中的ant任务,java,ant,build,classpath,aspectj,Java,Ant,Build,Classpath,Aspectj,在我的工作中,我们在一些Java项目中使用AspectJ。为了在ant构建中实现这一点,我们将aspectjtools.jar放在ant/lib/中 我现在正在处理一个特定的Java项目,需要使用更新版本的aspectJ。我不想让每个使用该项目的人都更新他们的aspectjtools.jar本地副本。相反,我尝试将较新的aspectjtools.jar添加到项目的lib目录中,并将以下行添加到build.xml中 <taskdef resource="org/aspectj/

在我的工作中,我们在一些Java项目中使用AspectJ。为了在ant构建中实现这一点,我们将aspectjtools.jar放在ant/lib/中

我现在正在处理一个特定的Java项目,需要使用更新版本的aspectJ。我不想让每个使用该项目的人都更新他们的aspectjtools.jar本地副本。相反,我尝试将较新的aspectjtools.jar添加到项目的lib目录中,并将以下行添加到build.xml中

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

但是,这并不像我所希望的那样有效,因为ANT类加载器从ANT/lib/加载jar,而不是我在taskdef类路径中指定的jar


有没有办法强迫ant选择签入到我的项目中的jar呢?

难道不能更新iajc编译目标以使用类路径上的新jar吗

不可能强制类加载器选择给定的jar文件而不是另一个。如果必须涉及同一类的几个版本,则应该考虑OSGI.< 最简单的解决方案是只使用项目或Maven/Ivy存储库中的库,而忽略全局ant文件夹中的库

例如:

 <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>


我希望这有帮助

我的问题的最终答案是否定的。目前,ANT无法优先使用项目中的任务jar而不是ANT lib目录中的任务jar。

这是可能的。 您需要利用这个额外的任务来创建一个新的类加载器



我曾尝试使用jarjar将aspectj重新打包到另一个包中,但这似乎破坏了aspectj,感觉像是一个巨大的黑客,因此我不再进一步采用这种方法。到目前为止,我的结论是,没有办法强迫ant选择签入我项目的jar。这感觉像是一个奇怪的设计选择,因为我希望特定项目的build.xml文件是选择使用哪个任务版本的最佳位置。-似乎是一个长期存在的错误。我正在看评论帖子。谢谢你的回答。我明天会测试这是否有效。这并不能解决我的问题。taskdef元素允许您指定一个类路径,但我的测试显示该类路径插入到现有类路径的末尾。这意味着ANT将始终优先使用ANT/lib/目录中的aspectjtools.jar,而不是taskdef类路径中指定的任何版本。感谢您的更新-我可以看到,使用ANT的另一个副本可以解决我的问题,但只能通过回避这个问题。加载时间编织是另一个有效的解决方案,但感觉特别复杂。对于ANT来说,为项目提供一种机制来强制使用任务的哪个版本真的很不合理吗?如果我理解你的意思是正确的,问题不在于ANT,而在于类加载器在Java中是如何工作的。如果web容器的lib文件夹中有旧版本的lib,并且希望使用war文件中的lib中的类覆盖其中一个类,则可能会遇到相同的问题。尝试在Ant的lib文件夹中使用另一个没有aspectjtools.jar的Ant版本,但只在项目的类路径上使用。类加载器的工作方式中没有任何内在因素导致这种行为。我希望ant将元素实现为嵌套类加载器,只有在ant找不到类时才会将其委托给ant。这将允许项目重写ant/lib/中的类。我将向ant开发者提出这个建议。
    <!--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"/>