代理設定

此頁面討論命令列 Apache Ant 上的代理問題。有關代理設定的 IDE 特定資訊,請參閱您的 IDE 文件。

在 Ant 的 JVM 中執行的所有工作和執行緒都共用相同的 HTTP/FTP/Socks 代理設定。

當任何工作嘗試從 HTTP 頁面擷取內容(包括 <get> 工作)、XML/XSL 工作中的任何自動化 URL 擷取,或使用 java.net.URL 類別的任何第三方工作時,代理設定可能會影響成功與否。

任何在封鎖防火牆後撰寫建置檔案的人都會立即了解問題,並可能想要撰寫建置檔案來處理問題,但第三方建置檔案的使用者可能會發現建置檔案本身無法在防火牆後執行。

這是 Java 和 Ant 的長久問題。解決此問題的唯一方法是透過將代理詳細資料傳遞為 JVM 屬性,或是在 Java 5+ 系統上指示 Ant 讓 JVM 自行解決,來明確設定 Ant 的代理設定。

Java 5+ 代理支援

自 Ant 1.7 起

當 Ant 啟動時,如果提供 -autoproxy 命令,Ant 會設定 java.net.useSystemProxies 系統屬性。這會指示 Java 5+ 執行時期使用主機環境的目前屬性設定集。其他 JVM,例如 Kaffe 和 Apache Harmony,未來也可能會使用此屬性。Java 1.4 和更早的執行時期會忽略此屬性。

此屬性可能足以讓命令列 Ant 建置存取網路,儘管實際上結果並不一致。

它也曾被報告會中斷 AIX 上的 IBM Java 5 執行時期,而且並非總是都能在 Linux 上執行(可能是因為缺少 gconf 設定)。其他奇怪的事情也可能出錯,例如 Oracle JDBC 驅動程式或純 Java SVN 程式。

若要將 -autoproxy 選項設為預設值,請將其新增至環境變數 ANT_ARGS,其中包含在每次命令列執行時傳遞給 Ant 的引數清單。

自動代理如何運作

java.net.useSystemProxies 只會在啟動時檢查一次,其他檢查(登錄、gconf、系統屬性)會在需要時動態執行(例如,socket 連線、URL 連線等)。

Windows

JVM 會直接前往登錄檔,略過 WinInet,因為它並非存在於所有受支援的 Windows 平台上(它實際上是 IE 的一部分)。Java 7 可以在存在時使用平台上的 Windows API。

Linux

JVM 使用 gconf 函式庫來查看特定項目。所使用的 GConf-2 設定為

 - /system/http_proxy/use_http_proxy            boolean
 - /system/http_proxy/use_authentication        boolean
 - /system/http_proxy/host                      string
 - /system/http_proxy/authentication_user       string
 - /system/http_proxy/authentication_password   string
 - /system/http_proxy/port                      int
 - /system/proxy/socks_host                     string
 - /system/proxy/mode                           string
 - /system/proxy/ftp_host                       string
 - /system/proxy/secure_host                    string
 - /system/proxy/socks_port                     int
 - /system/proxy/ftp_port                       int
 - /system/proxy/secure_port                    int
 - /system/proxy/no_proxy_for                   list
 - /system/proxy/gopher_host                    string
 - /system/proxy/gopher_port                    int

如果您使用的是 KDE 或 Gnome 以外的 GUI,您仍可以使用 gconf-editor 工具來新增這些項目。

手動 JVM 選項

任何 JVM 都可以透過將適當的 -D 系統屬性選項傳遞給執行時間來明確設定其代理選項。Ant 可以透過所有 shell 腳本,使用 ANT_OPTS 環境變數來設定,它是一個提供給 Ant 的 JVM 的選項清單

對於 bash

export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"

對於 csh/tcsh

setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"

如果您將此行插入 Ant shell 腳本本身,它會被所有在系統上執行持續整合工具所選取,這些工具會透過命令列呼叫 Ant。

對於 Windows,在適當的「我的電腦」屬性對話方塊(XP)、「電腦」屬性(Vista)中設定 ANT_OPTS 環境變數

此機制適用於所有 Java 版本,跨平台且可靠。設定後,所有透過命令列執行的建置檔案都會自動正確設定其代理,無需變更任何建置檔案。它顯然也會覆寫 Ant 的自動代理設定選項。

它在以下方面受到限制

  1. 無法在 IDE 下運作。這些需要變更其自己的代理設定
  2. 不夠動態,無法處理筆電組態變更。

SetProxy 任務

setproxy 任務 可用於在建置檔案中明確設定代理。這會處理 JVM 的許多代理組態屬性,並從那一刻起控制同一個 JVM 中所有網路操作的代理設定。

如果您有一個建置檔案只能在防火牆後、舊版 JVM 上的內部使用,而且您無法變更 Ant 的 JVM 代理設定,那麼這是您最好的選擇。它很醜陋且脆弱,因為建置檔案現在包含系統組態資訊。也很難在不同使用者的許多可能的代理選項(無、HTTP、SOCKS)中正確設定這一點。

請注意,使用此任務設定的代理組態可能會覆寫其他機制設定的任何組態。它也可以搭配一些花招使用,例如只有在代理被視為可到達時才設定代理

<target name="probe-proxy" depends="init">
  <condition property="proxy.enabled">
    <and>
      <isset property="proxy.host"/>
      <isreachable host="${proxy.host}"/>
    </and>
  </condition>
</target>

<target name="proxy" depends="probe-proxy" if="proxy.enabled">
  <property name="proxy.port" value="80"/>
  <property name="proxy.user" value=""/>
  <property name="proxy.pass" value=""/>
  <setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
            proxyuser="${proxy.user}" proxypassword="${proxy.pass}"/>
</target>

自訂 ProxySelector 實作

由於 Java 讓開發人員撰寫自己的 ProxySelector 實作,理論上某人可以撰寫自己的代理選擇器類別,使用不同的政策來決定代理設定。Ant 中沒有明確支援這一點,而且據團隊所知,尚未嘗試過。

這可能是最靈活的解決方案,因為人們可以輕易想像一個 Ant 特定的代理選擇器,由 ant 屬性驅動,而非系統屬性。開發人員可以在其自訂的 build.properties 檔案中設定代理選項,並讓此設定傳播出去。

這裡有一個問題在於並行性:預設的代理選擇器是每一個 JVM,而非每個執行緒,因此代理設定會套用至所有執行緒開啟的所有 socket;我們也有一個問題,就是如何將選項從一個建置傳播到 JVM 廣泛的選擇器。

在 Ant 下設定 Java 程式的 Proxy 設定

任何使用 <java> 執行的程式,如果沒有設定 fork=true,將會採用 Ant 的設定。如果您需要不同的值,請設定 fork=false,並在 <sysproperty> 元素中提供值。

如果您希望一個分岔的程序採用 Ant 的設定,請使用 <syspropertyset> 元素來傳播一般的代理設定。下列的屬性集是一個資料類型,可以在 <java> 任務中參考,以傳遞目前的數值。

<propertyset id="proxy.properties">
  <propertyref prefix="java.net.useSystemProxies"/>
  <propertyref prefix="http."/>
  <propertyref prefix="https."/>
  <propertyref prefix="ftp."/>
  <propertyref prefix="socksProxy"/>
</propertyset>

摘要和結論

有四種方法可以在 Ant 中設定代理。

  1. 使用 Ant 1.7 和 Java 5+,使用 -autoproxy 參數。
  2. 透過 JVM 系統屬性—在 ANT_ARGS 環境變數中設定這些屬性。
  3. 透過 <setproxy> 任務。
  4. 自訂 ProxySelector 實作

代理設定會自動與在 Ant 下啟動的 Java 程式共用(未分岔的程式);若要將代理設定傳遞至子程式,請使用屬性集。

隨著時間推移,我們預期 Java 5+ 代理功能會穩定,而 Java 程式碼也會適應它們。然而,考量到它目前確實會中斷某些建置,在 Ant 預設啟用自動代理功能之前,還需要一些時間。在那之前,您必須啟用 -autoproxy 選項,或使用其中一種替代機制來設定 JVM。

進一步閱讀