我正在修改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,我无法在脚本中运行任何内容。
答案 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文件添加到全局条目你应该好好去。