プロキシ設定

このページでは、コマンドライン 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 以降のランタイムに、ホスト環境の現在のプロパティ設定を使用するように指示します。Kaffe や Apache Harmony など、他の JVM も将来このプロパティを使用する可能性があります。Java 1.4 以前のランタイムでは無視されます。

このプロパティだけで、コマンドライン Ant ビルドへのネットワークアクセスを可能にする場合がありますが、実際には結果は一貫していません。

AIX 上の IBM Java 5 ランタイムの動作を阻害するとの報告もあり、Linux では常に動作するとは限りません(おそらく gconf 設定がないため)。Oracle JDBC ドライバーや純粋な Java SVN クライアントなど、他の予期せぬ問題が発生する可能性もあります。

-autoproxy オプションをデフォルトにするには、コマンドライン実行ごとに Ant に渡す引数のリストを含む環境変数 ANT_ARGS に追加します。

Autoproxy の動作方法

java.net.useSystemProxies は起動時の一度だけチェックされます。その他のチェック(レジストリ、gconf、システムプロパティ)は、必要になるたびに動的に実行されます(ソケット接続、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

Gnome 以外の KDE や他の GUI を使用している場合でも、gconf-editor ツールを使用してこれらのエントリを追加できます。

手動による JVM オプション

任意の JVM は、適切な-D システムプロパティオプションをランタイムに渡すことで、プロキシオプションを明示的に構成できます。Ant は、Ant の JVM に渡すオプションのリストである ANT_OPTS 環境変数を介して、すべてのシェルスクリプトから構成できます。

bash の場合

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

csh/tcsh の場合

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

この行を Ant シェルスクリプト自体に挿入すると、コマンドラインを介して Ant を呼び出すシステム上で実行されているすべての継続的インテグレーションツールによって取得されます。

Windows の場合、適切な「マイコンピュータ」プロパティダイアログボックス(XP)、「コンピュータ」プロパティ(Vista)で ANT_OPTS 環境変数を設定します。

このメカニズムは、Java のバージョンに関係なく、クロスプラットフォームで信頼性があります。一度設定すると、コマンドラインを介して実行されるすべてのビルドファイルは、ビルドファイルを変更する必要なく、プロキシ設定が自動的に正しく設定されます。また、明らかに Ant の自動プロキシ設定オプションを上書きします。

次の点で制限があります。

  1. IDE では動作しません。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 ごとであるため、プロキシ設定はすべてのスレッドで開かれたすべてのソケットに適用されます。また、オプションを 1 つのビルドから JVM 全体へのセレクタに伝播する方法という問題もあります。

Ant での Java プログラムのプロキシ設定の構成

fork=true を設定せずに <java> で実行されるプログラムは、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 でプロキシを設定するには 4 つの方法があります。

  1. Ant 1.7 と Java 5 以上で -autoproxy パラメータを使用します。
  2. JVM システムプロパティを介して — これらを ANT_ARGS 環境変数に設定します。
  3. <setproxy> タスクを介して。
  4. カスタム ProxySelector 実装

プロキシ設定は、フォークされていない Ant で開始された Java プログラムと自動的に共有されます。プロキシ設定を子プログラムに渡すには、プロパティセットを使用します。

時間の経過とともに、Java 5 以降のプロキシ機能は安定し、Java コードはその機能に適応していくと予想されます。しかし、現在一部のビルドを壊しているという事実を考えると、Ant が自動プロキシ機能をデフォルトで有効にするまでにはまだ時間がかかります。それまでは、-autoproxy オプションを有効にするか、代替メカニズムのいずれかを使用して JVM を構成する必要があります。

参考資料