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

发布于 11-03 15:22 字数 1261 浏览 6 评论 0原文

我正在修改 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

叫思念不要吵2024-11-10 15:22:00

这里的问题是 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)似乎是这里唯一的解决方案。

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:

 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.

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.

尹雨沫2024-11-10 15:22:00

创建 ~/.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 部分,您应该可以开始了。

Create ~/.ant/lib and copy jsch.jar in there as part of the build initialisation. Any tasks which do scp/sshexec work should depend on this init target.

<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>

The Ant within Eclipse unfortunately won't pick this up immediately as it does not read ~/.ant/lib on every execution; After running mytarget within Eclipse once and watching it fail, then go to:
Window>Preferences>Ant>Runtime and press Restore Defaults - this will add any .jar files from ~/.ant/lib to the Global Entries section and you should be good to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文