🐘

利用ライブラリをMavenリポジトリ形式でプロジェクト内のファイルとして保持する(JCenterシャットダウンに向けて)

2021/02/16に公開

Mavenリポジトリというと、JCenterMaven Centralといったインターネット上で公開されたリポジトリを使うことがほとんどかと思いますが、プロジェクト内にMavenリポジトリ形式でディレクトリを作っておいて、そこを参照するといった事もできます。

様々なプロジェクトで使うものならば、インターネット上の各種Mavenリポジトリで公開したり、社外に公開できないならばRepository Manager(Sonatype NexusやJFrog Artifactoryなど)を社内に立てるといった方法をおススメしますが、、

  • 一部のプロジェクトでしか使わない
  • 手間をかけずにやりたい

って時には、プロジェクト内にMavenリポジトリ形式でディレクトリを作って参照するといった方法も案の1つではと思います。

また、JCenterのシャットダウンに向けて、JCenterでしか公開されていないライブラリをどうするかといった問題に対しての解決方法の一つだと思います。

Mavenリポジトリのディレクトリ構成

Mavenリポジトリのディレクトリ構成は、下記のようになります。
この構成はURLでも同じです。

  • Group ID の.毎に一つのフォルダ階層
    • 例: com.github.onozaty -> com/github/onozaty といった3階層のフォルダになる
  • その下にArtifact IDのフォルダ
  • さらにその下にVersionのフォルダ
  • Versionのフォルダ配下に下記のようなファイル群
    (他にも署名ファイルや、ハッシュ値を表すようなファイルもありますが、いったん省略)
    • {Artifact ID}-{Version}.pom ※必須
    • {Artifact ID}-{Version}.jar
    • {Artifact ID}-{Version}-sources.jar
    • {Artifact ID}-{Version}-javadoc.jar

例えば、下記のような場合

  • Group ID: com.github.onozaty
  • Artifact ID: postgresql-copy-helper
  • Version: 1.0.0

フォルダ構造は下記の通りとなります。

  • com
    • github
      • onozaty
        • postgresql-copy-helper
          • 1.0.0
            • postgresql-copy-helper-1.0.0.pom
            • postgresql-copy-helper-1.0.0.jar
            • postgresql-copy-helper-1.0.0-sources.jar
            • postgresql-copy-helper-1.0.0-javadoc.jar

pomファイルは必須で、pomファイルに該当のライブラリの情報+依存関係の情報が記載されています。
この依存関係の情報を辿って、さらに必要なライブラリを取得してくれます。

リポジトリURLの指定方法

プロジェクト内にMavenリポジトリ形式のディレクトリを用意したら、それを参照するように設定します。
といっても、MavenリポジトリをURLで指定していたのを、単にディレクトリパスとして指定するだけです。

以降はビルドツールとしてGradleを使った例で記載しますが、Mavenでも同じようなことが出来ます。

build.gradleに下記のように記載します。2パターン記載していますが、どちらも同じディレクトリを指します。

repositories {
    maven {
        url "file://${projectDir}/local-repo"
    }
}
repositories {
    maven {
        url "./local-repo"
    }
}

相対パスでそのまま親を辿ることもできるので、複数プロジェクトから共通で参照するようなものを、各プロジェクトと同列のフォルダに用意するといったようなことも出来ます。

repositories {
    maven {
        url "./../local-repo"
    }
}

maven-publish によるライブラリの配置

自分で作ったライブラリをMavenリポジトリ形式で保存する場合には、maven-publishプラグインを利用します。

記述例は下記の通りです。(Gradle6 で確認しています)
Artifact IDは、そのままGradleでのプロジェクト名が利用されます。

plugins {
    id 'java'
    id 'maven-publish'
}

group = 'com.github.onozaty'
version = '1.0.0'

java {
    withJavadocJar()
    withSourcesJar()
}

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            url './../local-repo' // publish先のディレクトリを指定
        }
    }
}

publish タスクで所定のフォルダにMavenリポジトリ形式で各種ファイルが配置されます。

JCenterのシャットダウンに向けて

この記事を書いたきっかけは、JCenterのシャットダウン発表でした。

メンテナンスされているライブラリならば、Maven Centralなどに移行されると思いますが、既にメンテナンスされていないようなライブラリは移行されず、インターネット上にあるMavenリポジトリからは消える、、といった可能性があります。

そうなる前に、JCenterでしか公開されていないライブラリをプロジェクト内のMavenリポジトリとして配置しておくことで、JCenterがシャットダウンされた後でも、そのまま利用することができます。

JCenterにあるライブラリをダウンロードするためのツールとして、mvndlというものを作りました。

mvndlを使うと、JCenterにあるライブラリを、Mavenリポジトリ形式でローカルディレクトリにダウンロードすることができます。

$ ./mvndl -r jcenter -g com.github.onozaty -a postgresql-copy-helper -v 1.0.0 -d local-repo
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.pom -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.jar -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-sources.jar -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-javadoc.jar -> saved

$ find local-repo/ -type f
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-javadoc.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-sources.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.pom

Mavenのローカルキャッシュ(~/.m2)から拾うといった方法もありますが、ディレクトリ構成を再現するのが面倒なのもあって、このようなコマンドを作りました。

私が関わっているプロジェクトでJCenterでしか公開されていないライブラリが残るかわかりませんが、、その時には、このツール+今回記載した方法で対応しようと思っています。

Discussion