Ant 可选任务 SSHExec 和 SCP 的问题。类路径问题?
我正在修改 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 need by class org.apache.tools.ant.taskdefs.Optional。无法找到 ssh.SSHExec:com/jcraft/jsch/UserInfo"
它显然位于 classpathref、web-jars 中。由于这个格式错误或配置错误的taskdef,我无法运行脚本中的任何内容。
I'm in the process of modifying an Ant script (currently in use from within MyEclipse) to work from the command line. I'm doing this so anyone can check out the project and build it without MyEclipse. The problem I'm running into is that MyEclipse includes the dependencies behind the scenes. It does this by looking at the workspace's Ant configuration and compiling the classpath based on the selected libraries in the preferences dialog. Long story short, I need to take those dependencies and make the script smart enough to include them on its own, without the help of MyEclipse.
The tasks that are giving me a headache are the sshexec and scp tasks. They are optional ant tasks that require a version of jsch to run. I removed jsch from MyEclipse's Ant classpath and added it to a lib folder in the project itself (lib/dev). MyEclipse immediately complained that the SSHExec class could not find the dependent class, com.jcraft.jsch.UserInfo
which is part of jsch-0.1.44.jar.
I don't see a way to set the classpath for Ant from within the build script. I have the following code, which adds a path
element to the script, but I don't think Ant uses this unless explicitly associated to a task or another element.
<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>
It seems that I need to use taskdef
to define the sshexec and scp tasks:
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
classpathref="web-jars"/>
MyEclipse complains about this, "taskdef A class needed by class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec cannot be found: com/jcraft/jsch/UserInfo"
It's clearly in the classpathref, web-jars. And I can't run anything in the script because of this malformed or misconfigured taskdef.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
创建 ~/.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 - 这会将 ~/.ant/lib
中的任何 .jar 文件添加到< em>Global Entries 部分,您应该可以开始了。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
这里的问题是 SSHExec 类是从类加载器加载的,该类加载器本身无法访问您的 web-jars 类加载器。为taskdef 提供这个类路径不会改变这一点。每个类只能从它自己的类加载器和任何父类加载器加载类,但是 web-jars 类加载器不是 SSHExec 的类加载器的父类加载器(很可能是相反的情况,因为 SSHExec 似乎在这里找到)。
它看起来像这样:
VM 不知道在 web-jars 类加载器中查找 UserInfo(和其他 JSch 类)。
我想 SSHExec 任务位于通常的 ant 类路径中的某个位置,即由应用程序类加载器加载。然后从 ant 的类路径中删除 SSHExec(或向其中添加
jsch.jar
)似乎是这里唯一的解决方案。The problem here is that the
SSHExec
class is loaded from a classloader which itself has no access to your web-jars class loader. Supplying this classpath for the taskdef does not change this. Each class can only load classes from its own classloader and any parent class loaders, but the web-jars classloader is not a parent class loader of SSHExec's class loader (it is likely the other way around, since SSHExec seems to be found here).It looks like this:
The VM has no idea to look for UserInfo (and the other JSch classes) in the web-jars classloader.
I suppose the SSHExec task is somewhere in the usual ant classpath, i.e. loaded by the application class loader. Then removing SSHExec from ant's classpath (or adding
jsch.jar
to it) seems to be the only solution here.