2011-02-24 38 views
8

我正在执行很多scpsshexec以及来自ant构建脚本的其他远程命令。如果jsch.jar不在蚂蚁lib目录中,则这些命令不起作用。为了使它工作,我将JAR复制到了ant lib目录中,但这不是一个好的解决方案,因为其他任何想运行该脚本的人都必须执行相同的操作。要从Teamcity运行ant目标,我们必须显式设置lib文件的路径。如何在ant buildfile中指定JAR的路径?

有没有一种方法可以指定JAR在Ant构建XML本身的路径?

+0

已测试过您的蚂蚁代码示例?我没有看到它不应该起作用的原因。我以同样的方式用于其他任务。 – Robert 2011-02-24 12:58:37

+0

我并不是说它不起作用,它可以工作,但我必须在ant lib目录中添加jsch.jar,这是我想避免的。道歉,如果我的问题没有正确说明。我们有这样的任务{ \t }为了做到这一点,我必须手动在ant lib中添加jsch.jar。我是否可以通过在构建文件中加入某些东西来避免这种情况 – Ravi 2011-02-24 13:10:36

+0

如果jsch.jar不在lib目录中,那么您删除的代码段也可以工作。然后你必须确保你指定了正确的相对路径或绝对路径。 – Robert 2011-02-24 17:07:21

回答

4

谢谢你的回答。我设法使它与类加载器任务一起工作。这就是我所做的。

<project basedir="." > 
    <property environment="env"/> 

    <taskdef resource="net/jtools/classloadertask/antlib.xml"> 
    <classpath> 
     <fileset dir="${basedir}/lib" includes="ant-classloader*.jar"/> 
    </classpath> 
    </taskdef> 

    <!--Add JSCH jar to the classpath--> 
    <classloader loader="system"> 
    <classpath> 
     <fileset dir="${basedir}/lib" includes="jsch*.jar"/> 
     </classpath> 
    </classloader> 

    <target name="Test"> 
     <scp todir="user1:[email protected]:/tmp" trust="true" > 
     <fileset dir="dir1"> 
      <include name="test.txt" /> 
     </fileset> 
     </scp> 
    </target> 
</project> 

正如你可以看到这里,我没有给任何从属目标为我的“测试”的目标,它只是工作。它使用classloader,它将jsch.jar附加到系统类加载器。

+0

我不认为类加载器是必要的。文件顶部的路径声明可以正常工作,并与taskdef ant任务上的classpathref属性结合使用。 – 2011-02-25 11:46:39

+0

taskdef将不得不再次声明,为此我必须从lib目录中删除ant-jsch.jar,并为scp和sshexec添加nw taskdef。 – Ravi 2011-02-27 12:07:15

+0

这个解决方案效果很好。类加载器jar和信息可以在http://enitsys.sourceforge.net/ant-classloadertask/上找到。 – zombat 2012-08-01 22:50:53

2

一个可能的解决方法是使用-lib命令行选项告诉蚂蚁在哪里查找附加jar。也许你可以创建一个包装脚本,用这个选项集调用ant

另一种方式是移动ant-jsch.jar文件(这是与Ant定义的任务,而不是你需要单独下载jsch.jar文件的jar)出你的蚂蚁lib目录中,并创建一个taskdef为你的ssh任务分开,内置的一个,然后设置classpath中执行此任务的jsch.jarant-jsch.jar

<taskdef name="sshexec" 
    classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"> 
    <classpath> 
    <pathelement location="jsch-0.1.44.jar"/> 
    <pathelement location="ant-jsch.jar" /> 
    </classpath> 
</taskdef> 

我不知道这会帮助你,虽然,因为它也涉及在修改lib目录。

据我所知,目前不可能在构建文件本身中一般指定内置任务所需的额外jar。有一些特殊情况,比如junit。

+0

如果任务需要多个JAR,那么如果出现问题,为什么不简单地将所有JAR整合到一个JAR中? – Robert 2011-02-24 17:09:12

+1

我不想更改ant lib目录,因为我没有任何控制权。这个选项在这种情况下不起作用 – Ravi 2011-02-25 10:58:20

1

为了确保你的构建更跨平台,我建议使用依赖管理。 ivy plug-in可以在构建时自动安装版本的插件版本。

这种方法意味着你永远需要安装到您的ANT lib中的最后一个罐子常春藤2.2.0.jar :-)

首先在文件的ivy.xml申报项目的依赖

<ivy-module version="2.0"> 
    <info organisation="com.myspotontheweb" module="demo"/> 
    <configurations> 
     <conf name="anttask" description="Jars implementing ANT tasks"/> 
    </configurations> 
    <dependencies> 
     <dependency org="com.jcraft" name="jsch" rev="0.1.42" conf="anttask->default"/> 
    </dependencies> 
</ivy-module> 

在您的build.xml运行常春藤和使用它的基础上的常春藤配置来填充一个自定义的类路径:

<target name='init' description='Resolve project dependencies and set classpaths'> 
    <ivy:resolve/> 
    <ivy:cachepath pathid="anttask.path" conf="anttask"/> 
</target> 

最后,在您的构建中的其他地方使用现在由ivy自动填充的类路径声明您的ANT任务。

<target name='dosomething' depends="init"> 
    <taskdef name="sshexec" 
      classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" 
      classpathref="anttask.path"/> 
    .. 
    .. 
</target> 

这种方法适用于所有的ANT插件,其中大部分是在中央Maven仓库可用。第二个好处是可以轻松升级所有版本的插件版本。

+0

这并不能解决一些需要在蚂蚁lib目录中的jar来满足类加载需求的问题。实际的ant任务在ant中附带的ant-jsch.jar中定义,而不是在单独下载的jsch.jar中定义。问题是让jsch.jar对ant-jsch.jar中的类可见。或者我错过了什么? – matt 2011-02-24 19:47:42

+0

检出taskdef任务上的“classpathref”属性。它允许您指定要在声明任务时使用的类路径。常春藤提供的帮助是在构建时下载和填充该类路径的能力。这就是Maven构建工具所做的,它的所有插件都被下载。 – 2011-02-25 09:42:46

+0

我非常喜欢你的方法,但是在这里,每个任务都必须先调用** init **任务'depends =“init”'。我正在寻找更像“改变一次,共同工作”的方案。 – Ravi 2011-02-25 11:01:18