1

我正在修改 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,我无法在脚本中运行任何东西。

4

2 回答 2

3

这里的问题是SSHExec该类是从类加载器加载的,该类加载器本身无法访问您的 web-jars 类加载器。为 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-jars 类加载器中查找 UserInfo(和其他 JSch 类)。

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

于 2011-04-27T00:55:34.553 回答
0

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

<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一次并观察它失败后,然后转到: Window>Preferences>Ant>Runtime并按Restore Defaults - 这会将任何 .jar 文件添加~/.ant/libGlobal Entries部分,您应该一切顺利。

于 2016-08-08T10:54:03.353 回答