9

build.xml には<scp>および<sshexec>タスクが含まれているため、同じディレクトリに jsch.jar およびその他のライブラリーを build.xml と一緒に提供します。

次のタスク定義:

<taskdef name="scp"
    classname="org.apache.tools.ant.taskdefs.optional.ssh.Scp"
    classpath="WebContent/WEB-INF/lib/jsch-0.1.43.jar" />

エラーをスローします

A class needed by class org.apache.tools.ant.taskdefs.optional.ssh.Scp
cannot be found: com/jcraft/jsch/UserInfo

標準の Ant インストールを変更したり (例: jsch.jar を ant lib ディレクトリに配置したり、ant-jsch.jar を削除したり)、コマンドライン フラグを追加したり、システム環境変数を変更したりすることはできません。スクリプトはデフォルトで実行する必要があります。異なるシステム上の Ant。

私は実際にここで最初に尋ねられた質問を再投稿しています: http://ant.1045680.n5.nabble.com/specifying-location-of-an-external-library-within-build-xml-td1344969.html

しかし、クラスローダーが機能することについての答えを得ることができませんでした。

4

7 に答える 7

17

最後に、実用的な解決策を見つけました(少なくともAnt 1.7.1の場合)。Ant が文句を言って混乱するので、最初にant-jsch.jarfromを削除する必要があります。ANT_HOME/lib次に、プロジェクト自体からライブラリをロードします。

<available property="ant-jsch.present" file="${ant.home}/lib/ant-jsch.jar"/>
<fail if="ant-jsch.present" message="Please remove ant-jsch.jar from ANT_HOME/lib see [http://ant.apache.org/faq.html#delegating-classloader]"/>

<path id="jsch.path">
    <pathelement location="lib/ant-jsch.jar" />
    <pathelement location="lib/jsch-0.1.44.jar" />
</path>

<taskdef name="scp" classname="org.apache.tools.ant.taskdefs.optional.ssh.Scp" classpathref="jsch.path" />
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jsch.path" />
于 2010-12-07T13:48:35.900 に答える
3

したがって、この質問は古いですが、他の人に役立つ別のアプローチを考案しました。<java>実行する適切なクラスパスを持つタスクから Ant を生成できます<scp>。これにより、クラスパスのリークの問題が回避され、Ant のインストールを変更する必要はありません。

<target name="sendfile">
    <!-- file: local file to send -->
    <!-- todir: remote directory -->
    <java classname="org.apache.tools.ant.launch.Launcher"
        fork="true" dir="${basedir}" taskname="ant+scp">
        <classpath>
            <pathelement location="/where/is/jsch-0.1.49.jar"/>
            <pathelement location="${ant.home}/lib/ant-launcher.jar"/>
        </classpath>
        <arg value="-buildfile"/>
        <arg file="${ant.file}"/>
        <arg value="-Dfile=${file}"/>
        <arg value="-Dtodir=${todir}"/>
        <arg value="sendfile.scp"/>
    </java>
</target>

<target name="sendfile.scp">
    <echo message="Sending ${file} to ${todir}"/>
    <property file="/tmp/passwordfile"/>
    <scp file="${file}" todir="username@11.22.33.44:${todir}"
        trust="true" port="22" password="${PASSWORD}"/>
</target>

パラメーターは必要ありませんが、portカスタム SSH ポートのリマインダーとしてここにあります。/tmp/passwordfileパスワードは、などに保存されるプロパティPASSWORD=mysecretpasswordです。必要に応じてこれらを変更してください。次に使用例を示します。

<ant target="sendfile">
    <!-- Example: send /etc/os-release file to remote dir /home/myself -->
    <property name="file" value="/etc/os-release"/>
    <property name="todir" value="/home/myself"/>
</ant>
于 2013-02-02T21:07:15.807 に答える
2

参考までに、私が便利だと思うアプローチは、jar を再パッケージ化することです。競合しないようにします。次のように、JarJar を使用して Ant でこれを行うことができます。

<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="${basedir}/lib/build/jar/jarjar-1.4.jar"/>

<taskdef name="scp" classname="repackaged.scp.org.apache.tools.ant.taskdefs.optional.ssh.Scp" classpath="${basedir}/lib/build/jar/repackaged-scp.jar"/>

<target name="repackage.scp" description="Repackages Ant's optional SCP task and the JSch implementation to avoid conflicting with one on Ant's classpath">
    <delete file="${basedir}/lib/build/jar/repackaged-scp.jar" failonerror="false"/>
    <jarjar basedir="." jarfile="${basedir}/lib/build/jar/repackaged-scp.jar" includes="nothing">
        <zipfileset src="${basedir}/lib/build/jar/ant-jsch-1.9.1.jar"/>
        <zipfileset src="${basedir}/lib/build/jar/jsch-0.1.50.jar"/>
        <rule pattern="com.jcraft.jsch.**" result="repackaged.scp.com.jcraft.jsch.@1"/>
        <rule pattern="org.apache.tools.ant.taskdefs.optional.ssh.**" result="repackaged.scp.org.apache.tools.ant.taskdefs.optional.ssh.@1"/>
    </jarjar>
</target>
于 2013-06-12T10:24:03.763 に答える
1

ここからの投稿に続いてこの問題を解決できました https://stackoverflow.com/a/858744/3499805 その後

<taskdef resource="net/jtools/classloadertask/antlib.xml" classpath="${basedir}/ant-lib/ant-classloadertask.jar" />
<classloader loader="system" classpath="${basedir}/ant-lib/jsch-0.1.54.jar"/>
于 2016-10-11T11:18:14.967 に答える
0

Create a path reference and then use it in your task definition:

<path id="ssh.path">
   <pathelement location="${lib1.dir}/helloworld.jar"/>
   <fileset dir="${lib2.dir}">
       <include name="*.jar"/>
   </fileset>
</path>

<taskdef name="mytask" classname="org.mytask" classpathref="ssh.path" />
于 2010-09-16T22:25:09.160 に答える