Maven「Blocked mirror for repositories」の原因と直し方
Blocked mirror for repositories は、http:// のリポジトリ URL を https:// に直せば解消する。
Maven 3.8.1 以降は、外部の HTTP リポジトリへの取得を既定で止めている。
公開:
要約
pom.xml に http:// のリポジトリを書き、Maven Central に無い依存をそこから取ろうとすると、ビルドが依存の取得で止まる。
Maven 3.10.0 では次のように出る。
[ERROR] Failed to execute goal on project app: Could not collect dependencies for project com.example:app:jar:1.0
[ERROR] Failed to read artifact descriptor for com.example.legacy:legacy-lib:jar:1.0
[ERROR] Caused by: The following artifacts could not be resolved: com.example.legacy:legacy-lib:pom:1.0 (absent): Could not transfer artifact com.example.legacy:legacy-lib:pom:1.0 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [legacy (http://repo.example.com/maven2, default, releases+snapshots)]Blocked mirror for repositories は、HTTP のリポジトリへの取得を Maven 自身が止めたという意味だ。
Maven 3.8.1 から、暗号化されていない HTTP の外部リポジトリは既定でブロックされる。
通信の途中で依存をすり替えられる危険があるためだ(Maven 3.8.1 のリリースノート(新しいタブで開く))。
止めているのは、Maven 本体の conf/settings.xml にある次の mirror だ。external:http:* は「localhost 以外で、HTTP を使うすべてのリポジトリ」を指す。http://0.0.0.0/ はブロック用の見かけの URL で、実際にはそこへ接続しない。
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>エラーの角括弧の中に、止められたリポジトリの ID と URL が出る。
ここを見て、どのリポジトリを直すかを決める。
解決策
1. URL を https:// に直す
そのリポジトリが HTTPS でも配信されているなら、URL を書き換えるだけでよい。
<repositories>
<repository>
<id>legacy</id>
<url>https://repo.example.com/maven2</url>
</repository>
</repositories>Maven 3.10.0 で書き換えて実行し直すと、取得先は maven-default-http-blocker ではなく legacy (https://repo.example.com/maven2) に変わった。
2. 依存の POM が原因なら、バージョンを上げるか mirror で向け直す
リリースノートが示す直し方は 2 つある。
HTTPS の URL に直った新しいバージョンへ依存を上げるか、バージョンはそのままで settings.xml に mirror を書くかだ。
mirror は、止められたリポジトリの ID を <mirrorOf> に書き、HTTPS の URL へ向ける(Using Mirrors for Repositories(新しいタブで開く))。
<settings>
<mirrors>
<mirror>
<id>legacy-https</id>
<mirrorOf>legacy</mirrorOf>
<url>https://repo.example.com/maven2</url>
</mirror>
</mirrors>
</settings>Maven 3.10.0 で ~/.m2/settings.xml にこれを置くと、取得先が legacy-https (https://repo.example.com/maven2) に切り替わった。
3. 社内リポジトリは HTTPS にする
社内の Nexus などが HTTP でしか使えないなら、HTTPS で公開してもらうのが筋だ。
同じマシンで動かしている http://localhost のリポジトリは external:http:* の対象外で、Maven 3.10.0 でもブロックされずに接続しに行った。
よくある原因
pom.xmlにhttp://の URL を書いている。
古い手順書から写したリポジトリの URL がhttp://のままになっている。settings.xmlのプロファイルに書いている。~/.m2/settings.xmlで足したリポジトリも、HTTP なら同じように止められる。- 依存ライブラリの POM に書かれている。
自分では書いていなくても、依存の POM が HTTP のリポジトリを宣言していれば、その先の依存の取得で止まる。
リリースノートの例では、エラーにFailed to collect dependencies at A -> Bのような依存の経路が出る。 - 社内リポジトリが HTTP のままになっている。
Nexus などをhttp://で運用している。
なお、Maven 3.10.0 で http:// のリポジトリを書いた pom.xml に、Maven Central にある依存だけを書いた場合は、Central から取れて BUILD SUCCESS になった。
止まったのは、Central に無い依存を取りに行ったときだけだった。