いしぐめも

プログラミングとかしたことを書きます。

Maven実行時のプロキシ設定をsettings.xmlに書かずに適用する

settings.xml を書かずにプロキシを使いたいあなたに。(認証プロキシはダメでした)

結論

http.proxyHost, http.proxyPort, https.proxyHost, https.proxyPortJVMオプションに与えてあげればよいです。

コマンドラインオプションで指定する

つまり、こんな感じ↓

mvn package -Dhttp.proxyHost=<PROXY_HOST> -Dhttp.proxyPort=<PROXY_PORT> -Dhttps.proxyHost=<PROXY_HOST> -Dhttps.proxyPort=<PROXY_PORT>

環境変数で指定する

MAVEN_OPTS 環境変数を使うと引数に明示的に書かなくてもよくなります。Dockerfileで使うならこんな感じ↓

FROM maven
ARG MAVEN_OPTS

# 中略

RUN mvn package

としてMAVEN_OPTSを受け取れるようにしてやり、ビルド時に

docker build . --build-arg MAVEN_OPTS="\
  -Dhttp.proxyHost=<PROXY_HOST> \
  -Dhttp.proxyPort=<PROXY_PORT> \
  -Dhttps.proxyHost=<PROXY_HOST> \
  -Dhttps.proxyPort=<PROXY_PORT>

といった感じで指定すればよいみたいですね。

解説

解説、というまでもないですが、一応公式のドキュメントを貼っておきます。

java.net のプロキシ設定

このドキュメントにあるように、JavaのネットワークAPIを使用しているライブラリは -Dhttp.proxyHost などでいけます。

Javaネットワークとプロキシ

MAVEN_OPTS

https://maven.apache.org/configure.html

MAVEN_OPTS について、Mavenのドキュメントにはこうあります。

MAVEN_OPTS environment variable:
This variable contains parameters used to start up the JVM running Maven and can be used to supply additional options to it.

これを使用することで、明示的にコマンドラインオプションで書く必要がなくなります。

なぜこんな記事を書いたか?

mavenを内部的に使用しているDockefileを書いているんですが、認証プロキシ用に settings.xml を書きたくないですよね。(セキュリティ的にもHTTP_PROXYなどでできるのがベストですが)

自分も同じ気持ちで書きたくないなーってウダウダ考えながら mavenソースコードを読んでいると、以下のような記述を見かけました。

maven/DefaultDownloader.java at master · apache/maven · GitHub

private static class SystemPropertiesProxyAuthenticator
    extends Authenticator
{
    @Override
    protected PasswordAuthentication getPasswordAuthentication()
    {
        return new PasswordAuthentication( System.getProperty( "http.proxyUser" ),
                                            System.getProperty( "http.proxyPassword", "" ).toCharArray() );
    }
}

これ見て、getProperty('http.proxyUser')getProperty( "http.proxyPassword", "" ) とかいうコードがあったので、「ウオオオ、認証プロキシをJVMのオプションで実は渡せるのか?!」 と舞い上がってしまい記事を書きかけたというのがキッカケです。

認証プロキシだめっぽいです

しかし、実際に依存モジュールを解決するのは maven-dependency-plugin で、認証プロキシ用のコードは見当たりませんでした。(たぶん)

となると、上記maven本体の認証プロキシ用のコードは何のためにあるのか?って感じですがどなたかご存知でしたらコメントなどいただけると嬉しいです。

終わりに

本来の目的であった認証プロキシをsettings.xmlで指定せずに使えるようにするのは失敗に終わりましたが、環境変数もしくはコマンドラインオプションでプロキシは指定できるということが、どなたかの参考になれば幸いです。