2011-04-26 62 views
1

我正在修改一個Ant腳本(目前正在MyEclipse中使用)從命令行工作。我這樣做是爲了讓任何人都可以簽出項目並在沒有MyEclipse的情況下構建它。我遇到的問題是MyEclipse包含幕後的依賴關係。它通過查看工作區的Ant配置並根據首選項對話框中選定的庫編譯類路徑來實現此目的。長話短說,我需要採取這些依賴關係,並使腳本足夠聰明,以便在沒有MyEclipse幫助的情況下自行包含它們。Ant可選任務SSHExec和SCP出現問題。類路徑問題?

讓我頭疼的任務是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,網絡的罐子。由於這種格式錯誤或配置錯誤的taskdef,我無法在腳本中運行任何內容。

+0

問題可以解決此問題 http://stackoverflow.com/a/39976060/3499805 – user3499805 2016-10-11 11:22:03

回答

3

這裏的問題是,SSHExec類是從一個本身無法訪問web-jars類加載器的類加載器加載的。爲taskdef提供這個類路徑不會改變這個。每個類只能從它自己的類加載器和任何父類加載器加載類,但是web-jar類加載器不是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不知道找的UserInfo(和其他JSch班)在網上罐類加載器。

我想SSHExec任務是在通常的ant類路徑中的某處,即由應用程序類加載器加載。然後從ant的類路徑中刪除SSHExec(或將jsch.jar添加到它)似乎是唯一的解決方案。

+0

謝謝@帕洛埃伯曼。這很有道理。但是,您提到刪除SSHExec可能是一個解決方案。如果我從ant classpath(ant/lib)中刪除SSHExec(ant-jsch.jar),我需要將它放在其他地方,對嗎?我不能簡單地刪除它,我可以嗎?在我看來,會導致Ant在'sshexec'taskdef上失敗,因爲在類路徑中找不到類名。我錯過了什麼嗎? – jinxed 2011-04-28 14:56:14

+1

你應該將它添加到taskdef的'classpath'或'classpathref'中,我想。例如,您可以使用一個新的''定義,引用'web-jars'路徑。 – 2011-04-28 22:16:09

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="[email protected]"><fileset dir="..."/></scp> 
</target> 

在Eclipse中Ant的不幸不會立即拿起這件事,因爲它不會在每次執行讀取~/.ant/lib;在Eclipse中運行mytarget一次,看着它失敗後,然後去: 窗口>首選項>螞蟻>運行並按恢復默認值 - 這將增加任何。jar文件從~/.ant/lib全球條目部分,你應該很好去。