Ant可选任务SSHExec和SCP的问题。类路径问题?

时间:2011-04-26 21:18:46

标签: ant classpath myeclipse jsch taskdef

我正在修改Ant脚本(当前在MyEclipse中使用)以从命令行工作。我这样做是因为任何人都可以检查项目并在没有MyEclipse的情况下构建它。我遇到的问题是MyEclipse包含幕后的依赖项。它通过查看工作空间的Ant配置并根据首选项对话框中选定的库编译类路径来完成此操作。简而言之,我需要采用这些依赖关系并使脚本足够智能,以便在没有MyEclipse帮助的情况下自行包含它们。

让我头疼的任务是sshexec和scp任务。它们是可选的ant任务,需要运行jsch版本。我从MyEclipse的Ant类路径中删除了jsch,并将其添加到项目本身的lib文件夹中(lib / dev)。 MyEclipse立即抱怨SSHExec类找不到依赖类com.jcraft.jsch.UserInfo,它是jsch-0.1.44.jar的一部分。

我没有看到在构建脚本中为Ant设置类路径的方法。我有以下代码,它在脚本中添加了path元素,但我不认为Ant使用它,除非明确地与任务或其他元素相关联。

<path id="web-jars">
  <fileset dir="${web-lib}">
    <include name="**/*.jar" />
  </fileset>
  <fileset dir="${app-lib}"> <!-- this is where jsch resides --> 
    <include name="**/*.jar" />
  </fileset>
</path>

似乎我需要使用taskdef来定义sshexec和scp任务:

<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
    classpathref="web-jars"/>

MyEclipse抱怨这个,"taskdef A class needed by class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec cannot be found: com/jcraft/jsch/UserInfo"

它显然位于classpathref,web-jars中。由于这种格式错误或配置错误的taskdef,我无法在脚本中运行任何内容。

2 个答案:

答案 0 :(得分:3)

这里的问题是SSHExec类是从类加载器加载的,该类加载器本身无法访问您的web-jar类加载器。为taskdef提供此类路径不会更改此设置。每个类只能从自己的类加载器和任何父类加载器加载类,但是web-jars类加载器不是SSHExec类加载器的父类加载器(可能反过来,因为SSHExec似乎在这里找到)。

看起来像这样:

 ClassLoader    web-jars  ------------->   application CL ------------->  bootstrap CL

 taskdef 
       =>   look for SSHExec here
            => look first in parent class loader
                                     => look for SSHExec here
                                     => look first in parent class loader
                                                                     => look for SSHExec here
                                                                     => not found
                                     => look in our own classpath
                                     => found, load the class
                                     => it somehow uses interface UserInfo
                                     => look for UserInfo here
                                     => look first in parent class loader
                                                                    => look for UserInfo here
                                                                    => not found
                                     => look in our own classpath
                                     => not found, throw exception.

VM无意在web-jar类加载器中查找UserInfo(和其他JSch类)。

我认为SSHExec任务位于通常的ant类路径中,即由应用程序类加载器加载。然后从ant的类路径中删除SSHExec(或向其添加jsch.jar)似乎是唯一的解决方案。

答案 1 :(得分:0)

创建〜/ .ant / lib并在其中复制jsch.jar作为构建初始化的一部分。任何执行scp / sshexec工作的任务都应该依赖于这个初始目标。

<target name="init">
  <property name="user.ant.lib" location="${user.home}/.ant/lib"/>
  <mkdir dir="${user.ant.lib}"/>
  <copy todir="${user.ant.lib}">
    <fileset dir="${basedir}/build/tools" includes="jsch-*.jar"/>
  </copy>
</target>

<target name="mytarget" depends="init">
  <scp todir="user@host"><fileset dir="..."/></scp>
</target>

Eclipse中的Ant很遗憾不会立即选择它,因为它在每次执行时都没有读取~/.ant/lib;在Eclipse中运行 mytarget 并观察它失败后,请转到: 窗口&gt;首选项&gt; Ant&gt;运行时并按恢复默认值 - 这会将~/.ant/lib中的所有.jar文件添加到全局条目你应该好好去。