🐒

(ライブラリ公開者向け) JCenter から Maven Central に移行

11 min read

はじめに

2021/2/3 に以下の発表があり、同日 Twitter 上で自分の観測範囲では主に Android エンジニアを中心に話題となっていました。

https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/

JFrog 社の方針転換により影響を受ける人の多くは、主に アプリ開発者(ライブラリの利用者)側 かと思いますが、本記事では逆の立場である ライブラリの開発・公開者 側向けの内容となっています。(想定される読者層はかなりニッチでしょうね・・・)

今回の問題については、一時的にはライブラリ利用者側が公開されているライブラリのファイルを手元に保持しておくなどの対応もありますが、根本的にはライブラリの開発者側が別のリポジトリに移行してくれることを待つ(祈る)ことが、恒久的な対策として必須 となっています。

とはいえ、重大な発表の割にはタイムスケジュール的にかなりタイトで、5/1 には JCenter 含む JFrog が運用しているリポジトリが一切使えなくなってしまう というなかなかに厳しい状況のため、開発者の混乱をなるべく抑えられるよう本記事の執筆および即興ではありますが作業補助のツールを公開する事にいたしました。

なお、本記事では一旦の暫定対処ということで、Bintray (JCenter) に上げている全アーティファクトの手元への退避、および、過去の公開済みバージョンを “そのまま” OSSRH (Maven Central) へアップロード・公開するところまでをゴールとしています。そのため、過去バージョンの再ビルド等は一切行わないで済む手順となります。

今後、ライブラリの新しいバージョンを公開する際には Gradle の maven-publishプラグインなどを用いて行う形を取るのが良いかと思いますが、そちらに関してはよりたくさんの情報が既にインターネット上に見当たりますのでそれらをご参照ください。

⭐UPDATE⭐ Sonatype 社のブログでも移行ガイドが登場しました

JCenter の運営元である Sonatype 社のブログに次の記事が公開されました(2/8)。こちらも目を通しておくと良いかと思います。

https://blog.sonatype.com/what-publishers-need-to-know-about-migrating-from-jcenter-/-bintray-to-the-central-repository

また、本記事の末尾で紹介されている startship というツールが素晴らしいですね。公開操作を CLI で出来るみたいです。本記事が当初カバーしていなかった部分を担ってくれるので、こちらのツールは要チェックです!

https://github.com/saket/startship

(2/11 追記) startship をちょっと試してみましたが、今回紹介する手法では残念ながら利用できない ようでした。詳しく原因は調べていませんが、maven-metadata.xml というファイルが Staging リポジトリ内に生成されておらず、エラーが生じています。エラーとは別要因かもしれませんが、startship は open 状態のリポジトリに対してしか使えない と作者の方も issue を上げていますので、Artifact Bundle をアップロードする場合は勝手に close 状態になってしまうため現時点での利用は難しいようです。素直にブラウザ上から操作しましょう。

⭐UPDATE⭐ こちらの記事もオススメ

https://zenn.dev/red_fat_daruma/articles/0f3a01a53dc4fd

自分の作ったツールと機能はかなり被っており、アプローチも近いですが、こちらの方が自動化されている範囲が広く、アーティファクトのアップロードも対応されていますね!

(2/11 追記) 私のツール郡にもアーティファクトのアップロードを行うスクリプトを追加しました
👉 upload_bundle_jar.sh

ちょっとその前に

私自身ですが、今現在は Android の開発から離れてはいるものの、個人・業務で Android アプリの開発をしたり、個人的に開発した Android 向けのライブラリを幾つか公開しています。

一例:

※ 個人で出しているライブラリやアプリについては、近頃全くメンテナンスを出来ておらず、お恥ずかしながらずっとリポジトリも放置状態であったものの、今回の問題は急を要する事態のためちょうど今対応をやっているところです。

本記事の執筆時点では、VerticalSeekBar のみ Maven Central へ公開中の全バージョンの移行が完了している状況で、その他の公開ライブラリについてはこれから移行を開始するというタイミングとなります。本記事の内容であったり、紹介しているツールについては今後調整が入る可能性が高いため、その点につきましてはご了承ください。

(2/11 追記) 本記事に書いている手法にて jCenter にて公開していた全てのライブラリの移行を無事完了しました!

基礎知識

いきなり他の方の記事を紹介することになり恐縮なのですが、以下の記事を見ていただくのが手っ取り早いです。

https://qiita.com/yoshikawaa/items/a7a7c1d927f6e7e75320

Bintray および JCenter と比べると、ちょっと登場人物が多く、アーティファクトの署名や JIRA を使って多少英語でやり取りが必要な場面があったりとハードルが多少高めではあります。

最初私も身構えていましたが、多分 JIRA の内部的な運用はかなり自動化されているためか、レスポンスも早く、定型的なやり取りが発生するだけなのでコミュニケーション部分でトラブることはほぼ無いように思いましたので、これから作業に取り掛かる方は安心していただいて大丈夫かと思います。

用語 説明
Bintray JFrog 社が提供する汎用のパッケージリポジトリサービス
JCenter Bintray 内に設けられた Apache Maven パッケージ (Java ライブラリ) のリポジトリサービス
OSSRH OSS Repository Hosting。Sonatype 社 が提供するオープンソースプロジェクト向けのリポジトリホスティングサービス。
Maven Central OSSRH の公開セントラルリポジトリの呼称
Nexus Repository Sonatype 社が開発するリポジトリマネージャソフト。OSSRH に Web ブラウザよりアクセスする際に表示されるのはこちらのサービス。

ざっくり手順

1. まずは公式情報

OSSRH の公式情報は以下のページとなります。日本語で解説している記事等と併せてこちらも参照し、手順概要を予め把握しておくことをおすすめします。

https://central.sonatype.org/pages/producers.html

2. Bintay (JCenter) に上げてある内容を全てダウンロードする

Bintray については、例えば

https://dl.bintray.com/h6ah4i/maven

のような URL にアクセスすることで公開されているパッケージファイルにアクセスすることが可能です。普通こういったページについては、 wget を使えば一気に再帰的にダウンロードが出来るのですが各リンクにちょっとした細工が施されているためにそのままでは wget を使った一括ダウンロードがうまく働きません。

ということで簡単に再帰的に全ファイルをダウンロードしてくれるツールを用意しましたので、こちらを使えば一気に必要なファイルを取得できます。(ダウンロードしたファイル全て、何かのときのためにプライベートの git リポジトリなどに入れて保管しておきましょう)

  1. 事前に必要なツールをインストールしておく
    • git
    • bash
    • wget
    • ruby (ruby のバージョンが古い場合は、別途 bundler も入れておく)
    • gpg
  2. 次のリポジトリに必要なツールが入っていますので、クローンする
  3. セットアップ
    # 一部のツールが ruby 製なので、必要なライブラリを入れておきます
    bundle install
    
  4. ファイル一覧生成およびダウンロード
    # ファイルの一覧を生成 (※ `h6ah4i` の部分は自身の Bintray のユーザー名に置き換えてください)
    ./list_bintray_repo_files.sh https://dl.bintray.com/h6ah4i/maven > list.txt
    
    # リスト化した内容を全てダウンロード
    ./download_bintray_repo_files.rb list.txt
    

※ ↑のツールを作った後、JFrog CLI の存在に気が付きました。よく見ていませんがもしかしたらこちらのツールを応用すればより良い感じのものが作れるかもしれませんね。

3. PGP 鍵の準備

既に Bintray で利用していた鍵があればそちらをそのまま利用してもいいですし、新しく生成してあげても OK です。こちらの手順は次の公式ドキュメントを参照するのが良いでしょう。

4. Artifact Bundle の JAR ファイルを生成する

後で OSSRH の Nexus Repository Manager よりアーティファクトをアップロードする際、Artifact Bundle という形式にまとめておくとファイル 1 つ指定するだけで簡単にアップロード出来るようになるので便利です。

Artifact Bundle については、「POM ファイル」「JAR, AARファイル等」及び 「それぞれのファイル署名(.asc ファイル)」が纏められた JAR ファイル となります。

もちろん簡単な構造のファイルですので、 全て手作業で作ることも出来る のですが、いかんせんライブラリのバージョン毎この作業を繰り返すことになるため、現実的ではありません。

そこで、

  • GPG 署名ファイル (*.asc) の生成
  • md5 ファイルなど不要なファイルはフィルタリングして、1 つの JAR ファイルに纏める

ツールを用意しました。こちらも手順 2 にてクローンしたリポジトリに含まれています。

# ------
# Usage: ./build_bundle_jar.sh [-y] [-v] [-k gpg_key_name] target_dir

#      -y  No prompt mode.
#      -v  Verbose
#      -k  Specify GPG key name
# ------

# ※ -k オプションで指定する鍵名や、その後に指定するパスはご自身のものに読み替えてください。

./build_bundle_jar.sh -y -v -k C6ABE60482B734F35D5A7214FE4A8434FDD50882 ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.0
# => ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.0/bundle.jar

./build_bundle_jar.sh -y -v -k C6ABE60482B734F35D5A7214FE4A8434FDD50882 ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.1
# => ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.1/bundle.jar

./build_bundle_jar.sh -y -v -k C6ABE60482B734F35D5A7214FE4A8434FDD50882 ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.2
# => ./dl.bintray.com/h6ah4i/maven/com/h6ah4i/android/colortransitiondrawable/colortransitiondrawable/0.5.2/bundle.jar


...

※ ↑ これを必要なライブラリ、全バージョン分繰り返します。数が多い場合、find や xargs など使って良しなにやってください。

5. OSSRH アカウントの作成 (JIRA and Nexus のアカウント)

以下のページにアクセスしてアカウントを作成します。本アカウントは JIRA へのログイン及び、Nexus へのログインの際に利用することになります。

https://issues.sonatype.org/secure/Signup!default.jspa

6. JIRA にてチケットの作成

以下のページにアクセスして、 New Project のチケットを発行します。

https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

こちらにて申請を行うことで、

  • groupId の利用許可・認証
  • OSSRH リポジトリへのアクセスの許可

などのやり取りを行うことになります。私の場合は Group ID に独自ドメインを使用していましたので、TXT レコード DNS に追加する作業を行いました。

7. OSSRH Staging リポジトリへアーティファクトのアップロード

  1. 以下のページを開きます(ログイン情報は JIRA と共通です)
  2. アーティファクトを Staging リポジトリへアップロードする
    1. Upload Mode は Artifact Bundle を選択
    2. アップロード対象のファイルは、手順 4 「Artifact Bundle の JAR ファイルを生成する」 にて生成した bunldle.jar を指定する
    3. Upload Bundle ボタンを押す
  3. アップロード後、自動でチェックが行われます。ここで特に問題がなければ※ 自動的に Close ステータスに遷移します
  4. Staging リポジトリについては、build.gradle に以下のような感じで追記することで利用できるため、このタイミングでライブラリが参照できるか軽くチェックしてみましょう
    allprojects {
        repositories {
    	google()
    -	jcenter()
    +       maven { url "https://oss.sonatype.org/content/repositories/xxxyyyy-1001/" }
        }
    }
    
  5. 特に問題なければ、対象の Staging リポジトリを選択して Release ボタンを押します

※ アップロードの際にエラーになる場合
OSSRH については、Bintray よりも基準が厳しいです。以下のような場合にはエラーで弾かれてしまいますので、適宜 POM ファイルの修正などが必要となります。

  • POM ファイルが含まれていない
  • POM ファイルに必要なエントリーが含まれていない
  • 署名ファイルが不足している
  • 不要なファイル(.DS_Store 等) ※ .DS_Store についてはツール側で勝手にフィルタリングしてくれるようになっています

ref.) https://central.sonatype.org/pages/apache-maven.html

(蛇足となりますが、Bintray は Maven Central への同期機能持っているし、署名もやってくれる機能あったはずだから余裕では??? と思って今回の件の対処を始めたのですが、自分の場合は POM ファイルに不備がありBintray の Maven Central 同期機能が通らなかったために、今回自前でツールなど書く羽目になりました・・・)


(2/11 追記) アーティファクトのアップロードを行うスクリプトを追加しました。

ユーザー名、パスワード、Artifact Bundle の JAR ファイルを指定することでアップロードが行えます。(ブラウザ上からアップロードする際もそうですが、結構時間がかかりますがそういうものなので落ち着いて様子を見てあげてください)

./upload_bundle_jar.sh -u SONATYPE_NEXUS_USER -p SONATYPE_NEXUS_PASSWORD bundle_jar

8. JIRA チケットにコメントをし、クローズする

初回のリリースについては、Central リポジトリへの同期がブロックされている状態となるため、JIRA のチケットにて連絡が必要となります。特に問題がなく承認された場合、チケットはクローズしてしまって OK です。

9. 手順 7 を繰り返す

公開しているライブラリやバージョンが複数ある場合は必要回数同じことを繰り返す必要があります。

アーティファクトのアップロードについては更に自動化を進めることも可能ではあるのですが、一旦自分の規模では手作業で何とかなる数しか無かったためそこについては特にツール化等はしていません。

当初、「手順6〜8を繰り返す」と書いていましたが、Group ID が変わらない限りはチケットを新しく作る必要無いとのことです。新しく JIRA チケット作ったら DUPLICATED ステータスになってしまいました 😇

最後に

今回公開したツールについては、GitHub 側にも書いてありますが原状は Ubuntu Linux 上のみで動作確認をしております。おそらく MacOS の場合は簡単な修正で動作し、Windows の場合についても仮想マシンや Docker、WSL 2 などを用いればあまり改変せずに利用可能かと思います。

ただし、あくまで暫定対処的に作ったものあり、他の利用環境などでは問題を生じる場合等あるかと思いますので、その際は適宜手直しをするなどしてご利用いただければと思います。また、汎用的な形での修正・機能追加であれば取り込むつもりいますので、プルリク投げてもらえればと思います。

・・・ここまでたくさん書いたり、ツールも作ってしまいましたが、実は自分が発見できなかっただけでもっと楽な正攻法があるんじゃないかなーとも思っていますので、もっといい手法をご存知の方は教えていただければ助かります。

本記事が JCenter 終了の問題の解消に、多少なりとも役に立てましたら幸いです。

References