共有ライブラリを管理するために Sonatype の Nexus Repository Manager OSS を使用する ( その12 )( 他のライブラリに依存するライブラリを作成する )
概要
- 今回の手順で確認できるのは以下の内容です。
- 他のライブラリに依存するライブラリを作成してみます。
- 他のライブラリは org.apache.commons:commons-lang3 を使用します。
参照したサイト・書籍
金勘定のためのBigDecimalそしてMoney and Currency API
http://www.slideshare.net/miyakawataku/bigdecimal-for-money-counting- BigDecimal と Money and Currency API を調べた時に参照しました。
org.apache.commons.lang3.builder - Interface Builder
https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/builder/Builder.htmlGroovyで円周率を求めてみた
http://d.hatena.ne.jp/masanobuimai/20081118/1227014122Groovy Language Documentation - Decimal literals
http://docs.groovy-lang.org/latest/html/documentation/#_decimal_literals- 小数点が付いている数字は groovy では標準で BigDecimal で処理するそうです。
Apache Maven Project - POM Reference
https://maven.apache.org/pom.html
目次
- ライブラリの仕様を決める
- feature/2-issue ブランチを作成する
- ksbysample-library-depend-nospring プロジェクトを作成する
- Order クラス、OrderBuilder クラスを作成する
- テストを作成して動作確認する
- Nexus に登録する
- ksbysample-webapp-demo プロジェクトから ksbysample-library-depend-nospring ライブラリを利用する
- ksbysample-webapp-demo プロジェクトで build.gradle に記述していない
org.apache.commons:commons-lang3:3.4
が参照される仕組みとは? - pom ファイルとは何か?
手順
ライブラリの仕様を決める
今回は以下の仕様でライブラリを作成します。
- Gradle プロジェクトとして作成します。
- GroupId は
ksbysample.library
、ArtifactId はksbysample-library-depend-nospring
にします。 - 依存するライブラリは JDK と org.apache.commons:commons-lang3 とします。
- org.apache.commons:commons-lang3 の Builder クラスを継承した OrderBuilder クラスを作成します。number, price をフィールドに持つ Order クラスを Builder パターンで生成するクラスです。
- テストは Spock で実装します。
feature/2-issue ブランチを作成する
- GitHub に Issue 2 を作成した後、feature/2-issue ブランチを作成します。
ksbysample-library-depend-nospring プロジェクトを作成する
IntelliJ IDEA の「Welcome to IntelliJ IDEA」ダイアログから「Create New Project」メニューをクリックします。
「New Project」ダイアログが表示されます。画面左側の一覧から「Gradle」を選択してから以下の画像の内容を入力後、「Next」ボタンをクリックします。
GroupId、ArtifactId を入力する画面が表示されます。以下の画像の内容を入力後、「Next」ボタンをクリックします。
以下の画像の画面が表示されます。「Create directories for empty content roots automatically」をチェックした後、「Next」ボタンをクリックします。
Project name と Project location を入力する画面が表示されます。Project location を C:\project-springboot\ksbysample-nexus-repomng\ksbysample-library-depend-nospring に変更した後、「Finish」ボタンをクリックします。
build.gradle を リンク先の内容 に変更します。変更後、Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして反映します。
以下のディレクトリに .gitkeep ファイルを作成します。
commit します。
Order クラス、OrderBuilder クラスを作成する
src/main/java の下に ksbysample.library.dependnospring パッケージを作成します。
src/main/java/ksbysample/library/dependnospring の下に Order.java を作成し、リンク先の内容 に変更します。
src/main/java/ksbysample/library/dependnospring の下に OrderBuilder.java を作成し、リンク先の内容 に変更します。
テストを作成して動作確認する
Spock でテストを作成して動作確認します。
OrderBuilder クラスのソース上で Ctrl+Shift+T を押してコンテキストメニューを表示した後、「Create New Test...」を選択します。
「Create Test」ダイアログが表示されます。「Testing library」を「Spock」に変更した後、「OK」ボタンをクリックします。
「Choose Destination Directory」ダイアログが表示されます。groovy のディレクトリを選択して「OK」ボタンをクリックします。
src/test/groovy/ksbysample/library/dependnospring の下に OrderBuilderTest.groovy が作成されますので、リンク先の内容 に変更します。
テストを実行します。
def "OrderBuilder(#number, #price) --> #total"()
メソッド名の左側の矢印アイコンをクリックしてメニューを表示した後、「Run 'OrderBuilder(#numb...()'」メニューを選択します。テストが実行され、全て成功することが確認できました。
Nexus に登録する
Gradle projects View の uploadArchives タスクをダブルクリックして実行します。Run View に実行結果が表示され、BUILD SUCCESSFUL が表示されました。
Nexus の管理画面を見ると maven-releases repository に登録されていることが確認できます。
ksbysample-webapp-demo プロジェクトから ksbysample-library-depend-nospring ライブラリを利用する
ksbysample-library-depend-nospring プロジェクトを閉じて、ksbysample-webapp-demo プロジェクトを開きます。
build.gradle を リンク先の内容 に変更します。変更後、Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして反映します。
Project View の External Libraries を見ると build.gradle に記述した
ksbysample.library:ksbysample-library-depend-nospring:1.0-RELEASE
以外に ksbysample-library-depend-nospring ライブラリが依存しているorg.apache.commons:commons-lang3:3.4
も表示されていることが確認できます。src/main/java/ksbysample/webapp/demo の下に OrderController.java を作成し、リンク先の内容 に変更します。
Gradle projects View から bootRun タスクを実行して Tomcat を起動します。
ブラウザから http://localhost:8080/order/ にアクセスすると、"数量 = 5, 単価 = 2000, 総額 = 10000" の文字列が表示されました。
Ctrl+F2 を押して Tomcat を停止します。
commmit します。
ksbysample-webapp-demo プロジェクトで build.gradle に記述していない org.apache.commons:commons-lang3:3.4
が参照される仕組みとは?
ksbysample-library-depend-nospring-1.0-RELEASE.jar の中に情報が入っているのかと思い解凍してみると、以下の構造でした。
ksbysample-library-depend-nospring-1.0-RELEASE ├ generated ├ ksbysample │ └ library │ └ dependnospring │ ├ Order.class │ └ OrderBuilder.class └ META-INF └ MANIFEST.MF
META-INF/MANIFEST.MF かなと思い、中を見てみましたが以下の内容しか書かれていませんでした。jar ファイルの中には依存関係を解決するような情報はないようです。
Manifest-Version: 1.0
Nexus にアップロードされているファイルを見てみます。
maven-releases repository の中の ksbysample-library-depend-nospring ライブラリの中を見ると jar 以外に ksbysample-library-depend-nospring-1.0-RELEASE.pom というファイルだけアイコンが異なっていました。このファイルの中を確認してみます。
ksbysample-library-depend-nospring-1.0-RELEASE.pom ファイルの中に org.apache.commons:commons-lang3:3.4
の記述がありました。おそらく jar ファイル以外にこのファイルもダウンロードされて依存関係が解決されているものと思われます。
pom ファイルとは何か?
- 以下の URL に POM について説明がありました。プロジェクトの情報や依存するライブラリ等の情報を記載しておくファイルのようです。
- Apache Maven Project - POM Reference
https://maven.apache.org/pom.html
- Apache Maven Project - POM Reference
ソースコード
ksbysample-library-depend-nospring/build.gradle
group 'ksbysample.library' version '1.0-RELEASE' apply plugin: 'java' apply plugin: 'groovy' apply plugin: 'maven' sourceCompatibility = 1.8 targetCompatibility = 1.8 compileJava.options.compilerArgs = ['-Xlint:all'] compileTestGroovy.options.compilerArgs = ['-Xlint:all'] compileTestJava.options.compilerArgs = ['-Xlint:all'] repositories { jcenter() } dependencies { compile("org.apache.commons:commons-lang3:3.4") testCompile("org.spockframework:spock-core:1.0-groovy-2.4") } uploadArchives { def nexusUrl = "http://localhost:8081" def nexusUsername = "admin" def nexusPassword = "admin123" repositories { mavenDeployer { repository(url: "${nexusUrl}/repository/maven-releases") { authentication(userName: nexusUsername, password: nexusPassword) } snapshotRepository(url: "${nexusUrl}/repository/maven-snapshots") { authentication(userName: nexusUsername, password: nexusPassword) } } } }
- 今回は最初から
version '1.0-RELEASE'
にします。 - dependencies に
compile("org.apache.commons:commons-lang3:3.4")
を記述します。
Order.java
package ksbysample.library.dependnospring; import java.math.BigDecimal; import java.math.RoundingMode; public class Order { private BigDecimal number; private BigDecimal price; public BigDecimal getNumber() { return number; } public void setNumber(BigDecimal number) { this.number = number; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public BigDecimal getTotal() { return number.multiply(price) .setScale(0, RoundingMode.FLOOR); } }
- number, price の型を BigDecimal にしているのは Spock でテストを書く時に BigDecimal の場合どうなるのか試すためです。
OrderBuilder.java
package ksbysample.library.dependnospring; import org.apache.commons.lang3.builder.Builder; import java.math.BigDecimal; public class OrderBuilder implements Builder<Order> { private Order order; public OrderBuilder() { this.order = new Order(); } public OrderBuilder number(int number) { this.order.setNumber(new BigDecimal(Integer.toString(number))); return this; } public OrderBuilder price(int price) { this.order.setPrice(new BigDecimal(Integer.toString(price))); return this; } @Override public Order build() { return this.order; } }
OrderBuilderTest.groovy
package ksbysample.library.dependnospring import spock.lang.Specification import spock.lang.Unroll class OrderBuilderTest extends Specification { @Unroll def "OrderBuilder(#number, #price) --> #total"() { given: Order order = new OrderBuilder() .number(number) .price(price) .build() expect: order.number == number order.price == price order.total == total where: number | price || total 0 | 1 || 0 1 | 0 || 0 1 | 1 || 1 Integer.MAX_VALUE | 1 || Integer.MAX_VALUE 1 | Integer.MAX_VALUE || Integer.MAX_VALUE Integer.MAX_VALUE | Integer.MAX_VALUE || 4611686014132420609 } }
order.price
等は BigDecimal 型を返しますが、groovy だと上の書き方で動作しており BigDecimal を特に意識しなくてよいので楽でした。
ksbysample-webapp-demo/build.gradle
dependencies { compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') compile('ksbysample.library:ksbysample-library-simpleutils:1.0-RELEASE') compile('ksbysample.library:ksbysample-library-depend-nospring:1.0-RELEASE') }
- dependencies に
compile('ksbysample.library:ksbysample-library-depend-nospring:1.0-RELEASE')
を追加します。
OrderController.java
package ksbysample.webapp.demo; import ksbysample.library.dependnospring.Order; import ksbysample.library.dependnospring.OrderBuilder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/order") public class OrderController { @RequestMapping @ResponseBody public String index() { Order order = new OrderBuilder() .number(5) .price(2000) .build(); return String.format("数量 = %d, 単価 = %d, 総額 = %d" , order.getNumber().intValue() , order.getPrice().intValue() , order.getTotal().intValue()); } }
履歴
2016/08/13
初版発行。