独自のライブラリの作り方をご紹介します!
ビルドツールはGradleを前提にまとめます。
この記事は、こんな人にオススメ!
・Javaのライブラリを作りたい
・SpringBootのコンポーネントをライブラリで提供したい
Javaライブラリの作り方
まずはピュアなJavaライブラリの作り方です。
プロジェクト作成
gradle init
コマンドでプロジェクトを作成します。
・他は現場の開発ルールや言語選定に合わせて選べばOK!
$ gradle init
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
Select type of project to generate:
1: basic
2: application
3: library
4: Gradle plugin
Enter selection (default: basic) [1..4] 3
Select implementation language:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Scala
6: Swift
Enter selection (default: Java) [1..6] 3
Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] no
Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4
Project name (default: java-library-sample):
Source package (default: java.library.sample):
> Task :init
Get more help with your project: https://docs.gradle.org/7.6/samples/sample_building_java_libraries.html
BUILD SUCCESSFUL in 54s
2 actionable tasks: 2 executed
これでプロジェクトの雛形ができあがり!
通常のアプリケーション用のプロジェクトとの違いだけ押さえておくと、java
プラグインの代わりにjava-library
プラグインを使うことです。
逆にこの差分さえ押さえておけば、既存のプロジェクトをコピペしてライブラリを作ったり https://start.spring.io/ で生成したプロジェクトからライブラリを作ったりもできます!
maven repositoryへのアップロード設定
ライブラリのアップロード先がどこなのか(AWSだとCode ArtifatとかGCPだとArtifact Registryとか)で変わるので、ここではローカルのmaven repositoryへアップロードできるようにしてみます。
plugins {
id 'java-library'
// uploadに必要なプラグイン
id 'maven-publish'
}
...
// アップロードに必要な設定
publishing {
publications {
maven(MavenPublication) {
groupId = 'java.library.sample'
artifactId = 'java-library-sample'
version = '1.0.0'
from components.java
}
}
}
ライブラリで提供するクラスを作成
ここでは足し算をしてくれるMathUtils
クラスを実装してみます。
※ライブラリを作る上でのポイントはないので、単純にどんなクラスをライブラリで提供したいかだけ考えて実装すればOKです!
public class MathUtils {
public static int plus(int n1, int n2) {
return n1 + n2;
}
}
Maven Repositoryへアップロード
ここまでできたらmaven repositoryへアップロードをしましょう!
以下のコマンドを実行すればOKです!
$ ./gradlew publish
# ローカルへのアップロードの場合
# $ ./gradlew publishToMavenLocal
この記事ではローカルリポジトリを利用するので、publishToMavenLocal
の方を実行します。
ライブラリ利用
最後にライブラリの利用側の設定です!
・「dependencies」に利用するライブラリを追加する
repositories {
mavenCentral()
// この記事ではローカルリポジトリ利用なので「mavenLocal」を追加
mavenLocal()
}
dependencies {
...
// publishingで指定した「groupId」 「artifactId」「version」と対応
implementation 'java.library.sample:java-library-sample:1.0.0'
}
apiとimplementationの違い
ここまででライブラリを作りことはできるようになったので、ライブラリを作る上で知っておくべきことを1つ紹介します。
それがapi
とimplementaion
の違いで、どちらもライブラリの依存を定義するものなのですが、利用側に依存が伝播するかしないかの違いがあります。
・「api」:依存が伝播する
Apacheのhttpclient5を利用するライブラリを提供する例で解説していきます。
implementation
ライブラリ側に以下のように依存を追加し、httpclientをカスタマイズする関数を実装しています。
dependencies {
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}
public class HttpClientCustomizer {
public static HttpClient customize(HttpClientBuilder builder) {
// カスタマイズ実装(本題ではないので省略)
return builder.build();
}
}
このライブラリを使おうとするとimplementation
では以下のようなdependenciesになります。
dependencies {
implementation 'java.library.sample:java-library-sample:1.0.0'
// 「java-library-sample」の利用に必要なライブラリを追加
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}
このように、独自ライブラリの利用に必要なライブラリを明示的に追加しなければならないということです。
これはちょっと不便ですよね。。。
依存を追加しないと当然クラスを読み込めません。
api
今後はapi
で依存を追加してみます。(クラスは同じ)
dependencies {
api 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}
このようにライブラリを定義すると、利用者側はhttpclient5の依存を追加することなく実装をすることができます!
dependencies {
implementation 'java.library.sample:java-library-sample:1.0.0'
}
なんでもかんでもapiで定義するのもちょっと違うと思うので、「『引数』『戻り値』で外部ライブラリを利用する場合はapi
を使う」と把握しておけば良いと思います!
SpringBootライブラリの作り方
ライブラリはライブラリでも、SpringBootのBeanの登録までしてくれるライブラリを提供したい場合の実装方法を紹介します。
以下のクラスをBean
登録して提供したいとします。
public class MathUtils {
public int plus(int n1, int n2) {
return n1 + n2;
}
}
通常のライブラリを提供する場合に比べ、SpringBootライブラリを提供する場合には追加でやるべきことが2つあります。
・@ConfigurationクラスでBean登録する
・@Confirutaionクラスを「org.springframework.boot.autoconfigure.AutoConfiguration.imports」に登録する
まずは@Confiruration
クラスでBean登録をします。
@Configuration
public class MathUtilsAutoConfiguration {
@Bean
public MathUtils mathUtils() {
return new MathUtils();
}
}
次にConfigurationクラス(例でいうMathUtilsAutoConfiguration
)をresources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
に記載します。
hirabay.library.springboot.MathUtilsAutoConfiguration
※パッケージ部分はクラスがあるパッケージに置き換えてください。
これ以外は、通常のライブラリと同じです!
Repositoryを使えない場合
Maven RepositoryやCode Artifact、Artifact Registry等を利用できない場合、jarファイルを直接生成・配置すると言う方法もあります。
jarファイルの生成は、gradleのjar
ジョブで実行します。
./gradlew jar
jarファイルの配置は、任意のディレクトリでよく、例えばプロジェクトルート配下のlibs
というディレクトに配置する場合、以下のようにdependenciesを定義すれば良いです。
dependencies {
...
implementation files("${project.rootDir}/libs/<jarファイル名>")
}
publishでエラーになる場合
> Invalid publication 'maven':
- Publication only contains dependencies and/or constraints without a version. You need to add minimal version information, publish resolved versions (https://docs.gradle.org/7.6/userguide/publishing_maven.html#publishing_maven:resolved_dependencies) or reference a platform (https://docs.gradle.org/7.6/userguide/platforms.html)
publishを実行すると上記のようなエラーになることがあります。
このエラーが出た場合は、publication
にversionMapping
の設定を追加しましょう。
publishing {
publications {
maven(MavenPublication) {
...
// dependency-managementで依存のversion解決をさせたい場合は必須
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
}
}
}