JitPack.ioでGitHub上のJavaプロジェクトを簡単にライブラリとして参照する

Maven Centralに辟易しているpom職人のみなさまこんにちは。

今日はJitPack.ioというサービスを紹介しますよ。

JitPack.ioとは

JitPack.ioは一言で言うと、GitHub上のJavaプロジェクトをライブラリとして参照できるようにするサービスです。Maven Centralなどのリポジトリは無いけど、GitHubのあるプロジェクトをちょっと参照して試してみたいとかありますよね。そのリポジトリのJarを自力で作ったり、そのままソースをコピーして参照したりと色々と辛みのある作業になりますが、JitPack.ioはそれをシンプルに解決してくれます。

まあとりあえず実践して、方法と仕組みを理解してみましょう。

参照するリポジトリ

ライブラリとして参照するリポジトリとして、jitpack-libraryというのを作ってみました。これで実験します。

jitpack-libraryはGradle構成で作っていて、build.gradleは以下のような感じで、mavenプラグインをapplyする必要があるらしい。とりあえずcommons-langあたりに依存してみた。

apply plugin: 'java'
apply plugin: 'maven' // これが必要

sourceCompatibility = 1.7

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

もちろん、Maven構成でもできます。sbtもできるみたいなこと書いてるけど確認はしてない。

ソースコードは以下の何の変哲もないコードを用意してます。

package stormcat24.jitpack;

/**
 * @author stormcat24
 */
public final class Library {

    public static void foo() {
        System.out.println("foo");
    }

    public static void bar() {
        System.out.println("foo");
    }

}
リリースタグを作る

ライブラリとして参照するためには当然バージョンを指定しないといけないわけですが、JitPack.ioではGitHubのリリースタグがバージョンとなります。

今回は試しに1.0〜1.2まで作ってみました。その中で1.1を敢えてコンパイルエラーでビルドが失敗するような状態でタグ付けしています。これで参照される側の準備は完了。

参照してみる前に

実際に参照する前に、このリポジトリがJitPack.io側でどのように扱われるか確認してみます。JitPack.ioのページを見ると、GitHub repo urlを入力する項目があります。

f:id:a-yamada:20150216220755p:plain

ここにリポジトリのURLを入力してLook upをクリックすると先程作成したリリースタグの一覧が現れます。ビルドが失敗するはずのバージョン1.1も出ているということは、この時点においてはビルドの成功可否は見ていないということが推測できます。

f:id:a-yamada:20150216225429p:plain

任意のバージョンのGet itをクリックすると下にゆっくりスライドして、Gradle(またはMaven)での参照方法を教えてくれます。ご丁寧にshields.ioのバッジまで用意してくれてますねw

f:id:a-yamada:20150216225459p:plain

参照してみる

では、実際に参照してみましょう。参照する方として以下のリポジトリを用意しました。

jitpack-projectもGradleプロジェクトです。JitPack.ioが教えてくれた通りにbuild.gradleを作ってみます。

build.gradle

repositoriesにjitpack.ioのURLを追加し、dependenciesにはビルドが成功するはずの最新版1.2を指定します。

apply plugin: 'java'

sourceCompatibility = 1.7
version = '1.0'

repositories {
    mavenCentral()
    maven {
        url "https://jitpack.io"
    }
}

dependencies {
    compile 'com.github.stormcat24:jitpack-library:1.2'
}
ビルドする

ビルドして依存関係を解決します。今回はIntelliJRefresh external projectしました。

1分少々でしょうか、以下のように見事jitpack-libraryへの依存が追加されました!jitpack-libraryが参照してるcommons-langもちゃんと追加されてますね。

f:id:a-yamada:20150216225857p:plain

依存している成果物は?

ライブラリはソースとしてではなくJarとして参照しています。今回はGradleを利用しているので、成果物は~/.gradle/caches/modules-2/files-2.1/com.github.stormcat24/jitpack-library/1.2/ に配置されています。

これはJitPack.ioからダウンロードされたもので、これはすなわちJitPack.io側でJarがビルドされたことを意味しています。おそらく初回のダウンロードにかかった時間を考えると、指定のバージョンに初めて参照リクエストがあったときにビルドしていると思われます。

ビルドが失敗するバージョンを参照する

コンパイルエラーが起きるはずである1.1を参照するようにbuild.gradleを修正します。

dependencies {
    compile 'com.github.stormcat24:jitpack-library:1.1'
}

再度依存関係を更新すると、以下のエラーがでました。pomのダウンロードに失敗したようです。ダウンロード失敗というより、JitPack.ioでの生成の失敗でしょうね。

Could not GET 'https://jitpack.io/com/github/stormcat24/jitpack-library/1.1/jitpack-library-1.1.pom'. Received status code 500 from server: Not found

JitPack.io側を再度確認してみると、バージョン1.1はBuild errorになってました。

f:id:a-yamada:20150216232050p:plain

ログのリンクがあるので詳細を見てみると、コンパイルエラーが出て途中で終了していることがわかります。これでJitPack.ioが実際にビルドしてJarを作ってることがわかりました。

ビルドの仕組み

エラーログから判明しましたが、JitPack.ioはJarを生成するために以下のgradle installしているようです。これがあるために、参照されるリポジトリapply plugin: 'maven'が必要なんですね。

$ ./gradlew --daemon -Pgroup=com.github.stormcat24 -Pversion=1.1 install

成果物のgroupには「com.github.ユーザー名」を、versionにはリリースタグ名を、そしてartifactにはリポジトリ名が利用されることになります。今回、gradle.propetiesでもバージョンを指定していますが、こちらは完全に無視されました。リリースタグ名が正義ですね。

まとめ

GoLangにはgo getすればライブラリとして簡単に取り込める素晴らしい仕組みがありますが、JitPack.ioも考え方は基本的に同じでしょうね。良いサービスですが課題もまだまだあるとみてます。

Javaのビルド時間

当然リポジトリのビルド時間に依存するので、初回に参照する人は結構時間が取られることになりますね。数分まって結局NGだったとか、ちょっとツライですね。この辺はもうちょっとサクサクトライアンドエラーしたいところ。

参照される側の前提条件

検証の結果、GitHub上のJavaリポジトリを参照するには、参照される側にもいくつか前提条件があるとわかりましたね。

  • Gradle/Mavenでローカルインストールができるようになっていること。Gradleであれば、apply plugin: 'maven'が必要となる。
  • リリースタグが運用されていること
  • リリースタグをビルドして、Jarを生成できる状態になっていること

使ってみたいリポジトリがこの前提を満たしているかどうかは、現時点ではそんなに期待できないと思われます。JitPack.ioをエコシステムとして活用していくには、サービスの成熟ももちろんのことですがJavaOSS文化も併せて変えていくとか、レギュレーションを定着させていく必要があると思うのでかなり体力要りそうです。

とはいえまだまだ課題はあるにせよ、JitPack.ioはJava系開発を返そうなポテンシャルは持ってると思うので今後に期待ですね。てか、こういう動きはOracleがガンガン主導していってほしい。