Gradle で Multi-project を作成する ( その6 )( Multi-project は settings.gradle に include を書くだけでもよいのでは? )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その5 )( lib+webappx2編、Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
目次
- 2つ Multi-project を作成した上での考察。。。include だけでもいいのでは?
- gradle-multiprj-includeonly ディレクトリを作成する
- Gradle Wrapper のファイル一式をコピーする
gradlew init
コマンドを実行する- IntelliJ IDEA で gradle-multiprj-includeonly プロジェクトを開く
- IntelliJ IDEA で sample-lib プロジェクトを新規作成する
- setting.gradle に
include 'sample-lib'
を追加する - sample-lib プロジェクトに StrNumUtils クラスを追加する
- IntelliJ IDEA で sample-webapp プロジェクトを新規作成する
- setting.gradle に
include 'sample-webapp'
を追加する - sample-webapp プロジェクトに SampleController クラスを追加する
- 動作確認
- まとめ
手順
2つ Multi-project を作成した上での考察。。。include だけでもいいのでは?
ここまで2つ Multi-project を作成してみましたが、そこまで凝る必要がなければ setting.gradle に include 文を記述するだけで十分な気がするんですよね。。。
たぶんこんな感じで作っても Multi-project になる気がします。
- ルートディレクトリの直下に build.gradle を作成してサブプロジェクトの共通の設定を書けば確かに便利だが、実はルートディレクトリ直下には build.gradle はなくてもよい(サブプロジェクト毎に別々に build.gradle があるだけでOK)。
- ルートディレクトリの下に作成したサブプロジェクトの中のディレクトリ・ファイルはそのままでもよい(何も削除する必要はない)。
- ルートディレクトリ直下の setting.gradle に
include '<サブプロジェクト名>'
を記述すれば Multi-project になる。
試してみます。以下のような作り方でも Multi-project になるはずです。
- プロジェクトのルートディレクトリを作成する。
- Gradle Wrapper のファイル一式をコピーする。
gradlew init
コマンドを実行する。- IntelliJ IDEA でプロジェクトを開く。
- 後は以下の作業の繰り返し。
gradle-multiprj-includeonly ディレクトリを作成する
D:\project-springboot\ksbysample-boot-miscellaneous
の下に gradle-multiprj-includeonly ディレクトリを作成します。
Gradle Wrapper のファイル一式をコピーする
gradle-multiprj-lib-webapp2 プロジェクトから Gradle Wrapper のファイル一式をコピーします。
gradlew init
コマンドを実行する
コマンドラインから gradlew init
コマンドを実行します。
gradle-multiprj-includeonly ディレクトリ内に setting.gradle、build.gradle が作成されて、
setting.gradle には以下の内容が記述されています。コメントの部分は削除します。
/* * This file was generated by the Gradle 'init' task. * * The settings file is used to specify which projects to include in your build. * * Detailed information about configuring a multi-project build in Gradle can be found * in the user manual at https://docs.gradle.org/5.4/userguide/multi_project_builds.html */ rootProject.name = 'gradle-multiprj-includeonly'
build.gradle は以下の内容が記述されています。今回このファイルは何も変更しません。
/* * This file was generated by the Gradle 'init' task. * * This is a general purpose Gradle build. * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ */
IntelliJ IDEA で gradle-multiprj-includeonly プロジェクトを開く
IntelliJ IDEA で gradle-multiprj-includeonly プロジェクトを開きます。Project Tool Window と Gradle Tool Window は以下のように表示されます。
IntelliJ IDEA で sample-lib プロジェクトを新規作成する
gradle-multiprj-includeonly ディレクトリの下に sample-lib プロジェクトを新規作成します。Gradle プロジェクトとして作成します。
ディレクトリ・ファイルは以下のようになります。今回はこのディレクトリの中は何も削除しません(Gradle Wrapper も残したままです)。
setting.gradle に include 'sample-lib'
を追加する
setting.gradle に include 'sample-lib'
を追加します。
rootProject.name = 'gradle-multiprj-includeonly' include 'sample-lib'
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、Gradle Tool Window に sample-lib プロジェクトが表示されます。
sample-lib プロジェクトに StrNumUtils クラスを追加する
sample-lib/src/main/java の下に ksbysample.lib.samplelib パッケージを作成した後、StrNumUtils.java を新規作成して以下の内容を記述します。
package ksbysample.lib.samplelib; public class StrNumUtils { public static String plus(String v1, String v2) { return String.valueOf(Integer.parseInt(v1) + Integer.parseInt(v2)); } }
IntelliJ IDEA で sample-webapp プロジェクトを新規作成する
gradle-multiprj-includeonly ディレクトリの下に sample-webapp プロジェクトを新規作成します。Spring Initializr で作成します。
ディレクトリ・ファイルは以下のようになります。このディレクトリの中は何も削除しません。
setting.gradle に include 'sample-webapp'
を追加する
setting.gradle に include 'sample-webapp'
を追加します。
rootProject.name = 'gradle-multiprj-includeonly' include 'sample-lib' include 'sample-webapp'
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、Gradle Tool Window に sample-webapp プロジェクトが表示されます。
sample-webapp プロジェクトに SampleController クラスを追加する
sample-webapp プロジェクトの build.gradle に sample-lib プロジェクトへの依存関係を追加します。
plugins { id 'org.springframework.boot' version '2.1.4.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'ksby.ksbysample-boot-miscellaneous' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation project(":sample-lib") }
- dependencies block に
implementation project(":sample-lib")
を追加します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
sample-webapp/src/main/java/ksbysample/webapp/samplewebapp/SampleController.java を新規作成して以下の内容を記述します。
package ksbysample.webapp.samplewebapp; import ksbysample.lib.samplelib.StrNumUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/sample") public class SampleController { @RequestMapping @ResponseBody public String index() { return StrNumUtils.plus("1", "2"); } }
動作確認
最初に clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されることを確認します。
Run/Debug Configuration に SampleWebappApplication が自動で登録されているので、ここから Tomcat を起動して、
http://localhost:8080/sample にアクセスすると 3
と表示されます。
Project Tool Window で見ると以下のディレクトリ構成になっており、sample-lib-1.0-SNAPSHOT.jar、sample-webapp-0.0.1-SNAPSHOT.jar が生成されています。
コマンドプロンプトから java -jar sample-webapp-0.0.1-SNAPSHOT.jar
コマンドで Tomcat を起動してから、
http://localhost:8080/sample にアクセスしても 3
と表示されます。
まとめ
setting.gradle に include 文を書くだけでも Multi-project とみなされますね。プロジェクトが1つでも最初から Multi-project のディレクトリ・ファイル構成で作っておいて、開発途中にちょっとしたスタブが欲しい時にはサブプロジェクトを作成して setting.gradle に include を追加して対応する、というのもありなのかもしれません。
履歴
2019/04/24
初版発行。
Gradle で Multi-project を作成する ( その5 )( lib+webappx2編、Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- Gradle で Spring を使用しないライブラリ+Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)の Multi-project を作成します。
- sample-stubapp プロジェクト(こちらが sample-lib の StrNumUtils クラスを呼び出します)を作成した後、sample-webapp の SampleController クラスを本実装して Multi-project を完成させます。
参照したサイト・書籍
Spring @WebMvcTest with Spock Framework
https://allegro.tech/2018/04/Spring-WebMvcTest-with-Spock.htmlSpring Boot RestTemplate POST JSON Example
https://howtodoinjava.com/spring-boot2/resttemplate-post-json-example/
目次
- Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する
- IntelliJ IDEA で sample-stubapp プロジェクトを作成する
- sample-stubapp プロジェクトから不要なファイルを削除する
- sample-stubapp プロジェクトの build.gradle を変更する
- gradle-multiprj-lib-webapp2 プロジェクトの build.gradle を変更する
- settings.gradle に sample-stubapp プロジェクトの include 文を追加する
- application.properties に
server.port=9080
を追加する - StubWebapiController クラスを新規作成する
- sample-webapp の SampleController クラスを本実装する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- Run Dashboard から sample-webapp、sample-stubapp を起動して動作確認する
- sample-webapp、sample-stubapp を jar ファイルから起動して動作確認する
- まとめ
手順
Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する
IntelliJ IDEA で sample-stubapp プロジェクトを作成する
IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースの Web アプリケーションのプロジェクトを作成します。
※DevTools と Web の2つをチェックします。
作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。
sample-stubapp プロジェクトから不要なファイルを削除する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\sample-stubapp\
の下には以下のディレクトリ・ファイルがありますが、
src ディレクトリと build.gradle 以外を削除します。削除すると以下の状態になります。
sample-stubapp プロジェクトの build.gradle を変更する
sample-stubapp プロジェクトの build.gradle を以下の内容に変更します。必要な設定は gradle-multiprj-lib-webapp2 の build.gradle に記述したので、このファイルには sample-lib への依存関係だけ記述します。
dependencies {
implementation project(":sample-lib")
}
gradle-multiprj-lib-webapp2 プロジェクトの build.gradle を変更する
gradle-multiprj-lib-webapp2 プロジェクトの build.gradle を以下のように変更します。
.......... configure(subprojects.findAll { it.name ==~ /^(sample-webapp|sample-stubapp)$/ }) { .......... }
it.name ==~ /^(sample-webapp)$/
→it.name ==~ /^(sample-webapp|sample-stubapp)$/
に変更します。
settings.gradle に sample-stubapp プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2
の下の settings.gradle に include 'sample-stubapp'
を追加します。
rootProject.name = 'gradle-multiprj-lib-webapp2' include 'sample-lib' include 'sample-webapp' include 'sample-stubapp'
追加後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると sample-stubapp が追加されます。
また IntelliJ IDEA の画面右下に「Run Dashboard」のダイアログが表示されます。「Show run configurations Run Dashboard」リンクをクリックすると Run Dashboard Tool Window が表示されます。
※ちなみに Run Dashboard Tool Window は Run/Debug Configurations で Spring Boot に2つ以上設定を追加すれば表示させることができます。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
Project Tool Window を見ると以下のディレクトリ構成になっています。sample-stubapp/build/libs の下に sample-stubapp-1.0.0-RELEASE.jar が生成されています。
application.properties に server.port=9080
を追加する
sample-stubapp/src/main/resources/application.properties に server.port=9080
を追加します。
server.port=9080
StubWebapiController クラスを新規作成する
以下の仕様の StubWebapiController クラスを作成します。
- URL は
/plus
にする。 - HTTP メソッドは POST のみ有効にする。
- データは JSON で渡す。
{ "v1": "<数値文字列>", "v2": "<数値文字列>" }
のフォーマットする。 - レスポンスは
{ "result": "<数値文字列>" }
のフォーマットで返す。 - エラー処理は考慮しない。
sample-stubapp/src/main/java/ksbysample/webapp/samplestubapp の下に PlusForm、PlusResponse、StubWebapiController クラスを新規作成し、以下の内容を記述します。
■PlusForm
package ksbysample.webapp.samplestubapp; public class PlusForm { private String v1; private String v2; public String getV1() { return v1; } public void setV1(String v1) { this.v1 = v1; } public String getV2() { return v2; } public void setV2(String v2) { this.v2 = v2; } }
■PlusResponse
package ksbysample.webapp.samplestubapp; public class PlusResponse { private String result; PlusResponse() { } PlusResponse(String result) { this.result = result; } public String getResult() { return result; } public void setResult(String result) { this.result = result; } }
■StubWebapiController
package ksbysample.webapp.samplestubapp; import ksbysample.lib.samplelib.StrNumUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class StubWebapiController { @PostMapping("/plus") public PlusResponse plus(@RequestBody PlusForm plusForm) { String result = StrNumUtils.plus(plusForm.getV1(), plusForm.getV2()); PlusResponse plusResponse = new PlusResponse(result); return plusResponse; } }
テストを作成します。今回は Spock で作成します。
sample-stubapp/src/test/groovy/ksbysample/webapp/samplestubapp/StubWebapiControllerTest.groovy が新規作成されますので、以下の内容を記述します。
package ksbysample.webapp.samplestubapp import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc import spock.lang.Specification import spock.lang.Unroll import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* @SpringBootTest @AutoConfigureMockMvc class StubWebapiControllerTest extends Specification { @Autowired private MockMvc mvc @Unroll def "plus WebAPI のテスト(#v1, #v2 --> #result)"() { expect: mvc.perform(post("/plus") .contentType(MediaType.APPLICATION_JSON_UTF8) .content(""" { "v1": ${v1}, "v2": ${v2} } """)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath('$.result').value(result)) where: v1 | v2 || result "1" | "2" || "3" "999" | "1" || "1000" } }
テストを実行すると成功しました。画面左側で WARNING が出ているのは IntelliJ IDEA の JUnit の Run/Debug Configuration に JDK 11 のオプションを 設定していないためです。
sample-stubapp/src/test/java/ksbysample/webapp/samplestubapp/SampleStubappApplicationTests.java は不要なので削除します。
sample-webapp の SampleController クラスを本実装する
sample-webapp/src/main/java/ksbysample/webapp/samplewebapp/SampleWebappApplication.java を以下のように変更します。
package ksbysample.webapp.samplewebapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class SampleWebappApplication { private final RestTemplateBuilder restTemplateBuilder; public SampleWebappApplication(RestTemplateBuilder restTemplateBuilder) { this.restTemplateBuilder = restTemplateBuilder; } public static void main(String[] args) { SpringApplication.run(SampleWebappApplication.class, args); } @Bean public RestTemplate restTemplate() { return this.restTemplateBuilder .rootUri("http://localhost:9080") .build(); } }
private final RestTemplateBuilder restTemplateBuilder;
とコンストラクタインジェクションの処理を追加します。@Bean public RestTemplate restTemplate() { ... }
を追加します。
sample-stubapp/src/main/java/ksbysample/webapp/samplestubapp の下の PlusForm、PlusResponse クラスを sample-webapp/src/main/java/ksbysample/webapp/samplewebapp の下にコピーします。
sample-webapp/src/main/java/ksbysample.webapp.samplewebapp.SampleController.java を以下の内容に変更します。
package ksbysample.webapp.samplewebapp; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; @Controller @RequestMapping("/sample") public class SampleController { private final RestTemplate restTemplate; public SampleController(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @RequestMapping @ResponseBody public String index() { PlusForm plusForm = new PlusForm(); plusForm.setV1("1"); plusForm.setV2("2"); HttpHeaders httpHeaders = new HttpHeaders(); HttpEntity<PlusForm> request = new HttpEntity<>(plusForm, httpHeaders); ResponseEntity<PlusResponse> response = restTemplate.postForEntity("/plus", request, PlusResponse.class); return response.getBody().getResult(); } }
テストを作成します。こちらも Spock で作成します。
sample-webapp/src/test/groovy/ksbysample/webapp/samplewebapp/SampleControllerTest.groovy が新規作成されますので、以下の内容を記述します。
package ksbysample.webapp.samplewebapp import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpMethod import org.springframework.http.MediaType import org.springframework.test.annotation.DirtiesContext import org.springframework.test.web.client.MockRestServiceServer import org.springframework.test.web.servlet.MockMvc import org.springframework.web.client.RestTemplate import spock.lang.Specification import static org.springframework.test.web.client.match.MockRestRequestMatchers.method import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @SpringBootTest @AutoConfigureMockMvc @DirtiesContext class SampleControllerTest extends Specification { @Autowired private MockMvc mvc @Autowired RestTemplate restTemplate def "/sample にアクセスすると 3 と表示される"() { setup: MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build() mockServer.expect(requestTo("http://localhost:9080/plus")) .andExpect(method(HttpMethod.POST)) .andRespond(withSuccess('{"result": "3"}', MediaType.APPLICATION_JSON_UTF8)) expect: mvc.perform(get("/sample")) .andExpect(status().isOk()) .andExpect(content().string("3")) } }
テストを実行すると成功しました。
sample-webapp/src/test/java/ksbysample/webapp/samplewebapp/SampleWebappApplicationTests.java は不要なので削除します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
全ての実装が完了したので build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
Run Dashboard から sample-webapp、sample-stubapp を起動して動作確認する
Run Dashboard から sample-webapp、sample-stubapp を起動します。Run Dashboard から起動すると使用されているポート番号が表示されるのが分かりやすくていいですね。
ブラウザから http://localhost:8080/sample にアクセスすると画面上に "3" の文字が表示されました。
確認後、sample-webapp、sample-stubapp を停止します。
sample-webapp、sample-stubapp を jar ファイルから起動して動作確認する
今度は生成された jar ファイルから起動して確認してみます。コマンドプロンプトから jar ファイルが生成されている build/libs ディレクトリに移動した後、java -jar sample-webapp-1.0.0-RELEASE.jar
、java -jar sample-stubapp-1.0.0-RELEASE.jar
コマンドを実行します。
ブラウザから http://localhost:8080/sample にアクセスすると画面上に "3" の文字が表示されました。
確認後、sample-webapp、sample-stubapp を停止します。
まとめ
- サブプロジェクトに Spring Boot ベースの Web アプリケーションを2つ以上作成する場合、共通の設定はプロジェクトのルートディレクトリの build.gradle にまとめられます。
- Spring Boot ベースのサブプロジェクトと Spring Boot ベースではないサブプロジェクトが混在していて、Spring Boot ベースのサブプロジェクトの設定だけを プロジェクトのルートディレクトリの build.gradle にまとめる場合には
configure(subprojects.findAll { it.name ==~ /^(sample-webapp|sample-stubapp)$/ }) { ... }
のように記述して設定を適用するサブプロジェクトを指定できます。 - IntelliJ IDEA の Run Dashboard を表示させる方法がよく分かっていなかったのですが、Run/Debug Configurations で Spring Boot の下に2つ以上設定を追加すれば自動で現れることが分かりました。
- 簡単なサンプルを書いていたつもりでしたが、テストまで書くと意外に辛いですね。。。 書き方が分からなくて調べながらやっていて結構時間がかかりました。
履歴
2019/04/22
初版発行。
Gradle で Multi-project を作成する ( その4 )( lib+webappx2編、Multi-project の設定ファイルと Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その3 )( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Gradle で Spring を使用しないライブラリ+Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)の Multi-project を作成します。
- 2回に分けて書きます。
- Spring を使用しないライブラリは lib+cmdapp 編で作成した sample-lib プロジェクトをそのままコピーして利用します。
- Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)は新規に作成します。
参照したサイト・書籍
目次
- 方針
- gradle-multiprj-lib-webapp2 ディレクトリを作成する
- gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする
- IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する
- 続く。。。
手順
方針
- 以下のディレクトリ構成の Multi-project を作成します。
gradle-multiprj-lib-webapp2 ├ sample-lib <-- Spring を使用しないライブラリの Project ├ sample-stubapp <-- Spring Boot ベースの Web アプリケーション(スタブ)の Project └ sample-webapp <-- Spring Boot ベースの Web アプリケーション(メイン)の Project
- Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)の Project では Profile は作成しません。
- テスティングフレームワークは全ての Project で JUnit 5 と Spock を使用できるようにします。
- checkstyle, spotbugs, pmd, error-prone は今回は導入しません。
- Spring Boot ベースの Web アプリケーション(メイン)では 8080番ポートを、Spring Boot ベースの Web アプリケーション(スタブ)では 9080番ポートを使用します。
- Web アプリケーションが2つあるので、
gradle-multiprj-lib-webapp2 ディレクトリを作成する
ksby/ksbysample-boot-miscellaneous の repository を checkout している D:\project-springboot\ksbysample-boot-miscellaneous
の下に gradle-multiprj-lib-webapp2 ディレクトリを作成します。
gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp\
から以下のファイルをコピーします。
- gradle ディレクトリ
- sample-lib ディレクトリ
- この下の build, out ディレクトリは削除します。
- .gitignore
- build.gradle
- gradlew
- gradlew.bat
- settings.gradle
settings.gradle は以下の内容に変更します。
rootProject.name = 'gradle-multiprj-lib-webapp2' include 'sample-lib'
コピー後、コマンドプロンプトから gradlew wrapper
コマンドを実行します。
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\
の下には以下のディレクトリ・ファイルがある状態になります。
IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする
gradle-multiprj-lib-webapp2 プロジェクトをオープンします。
オープン後 Project Tool Window は以下のようになり、
Gradle Tool Window は以下のようになります。
gradle-multiprj-lib-cmdapp プロジェクトの時は gradle-multiprj-lib-cmdapp(root)
と表示されていたのですが、今回は Tasks
と表示されていますね。。。 Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新しても変わりませんでした。
gradle-multiprj-lib-cmdapp プロジェクトをオープンしてみるとこちらも Tasks
に変わっていました。どうも IntelliJ IDEA を 2019.1 にバージョンアップしたのが原因のようです。
※Project SDK は default の設定で JDK 11 を使うように設定済なので、今回は変更の手順は書きません。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
ここまでで build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
sample-lib/build/libs の下に sample-lib-1.0.0-RELEASE.jar も生成されており、問題ないようです。
Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する
IntelliJ IDEA で sample-webapp プロジェクトを作成する
IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースの Web アプリケーションのプロジェクトを作成します。
※DevTools と Web の2つをチェックします。
作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。
sample-webapp プロジェクトから不要なファイルを削除する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\sample-webapp\
の下には以下のディレクトリ・ファイルがありますが、
src ディレクトリと build.gradle 以外を削除します。削除すると以下の状態になります。
settings.gradle に sample-webapp プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2
の下の settings.gradle に include 'sample-webapp' を追加します。
rootProject.name = 'gradle-multiprj-lib-webapp2' include 'sample-lib' include 'sample-webapp'
追加後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると sample-webapp
(IntelliJ IDEA 209.1 から左側に :
が付かなくなったようです)が追加されます。
また sample-webapp 起動用の Run/Debug Configuration も自動で追加されます。
gradle-multiprj-lib-webapp2 プロジェクトの build.gradle にサブプロジェクトの Web アプリケーション共通の設定を追加し、sample-webapp プロジェクトの build.gradle を削除する
gradle-multiprj-lib-webapp2 プロジェクトの build.gradle を以下のように変更します。今回は Spring Boot ベースの Web アプリケーションを2つ作成するので、共通の設定は各サブプロジェクトの build.gradle に記述するのではなく gradle-multiprj-lib-webapp2 の build.gradle に記述するようにします。
buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } maven { url "https://repo.spring.io/release/" } } dependencies { classpath "io.spring.gradle:dependency-management-plugin:1.0.7.RELEASE" classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE" } } allprojects { repositories { mavenCentral() } } subprojects { group "ksby.ksbysample-boot-miscellaneous" version "1.0.0-RELEASE" apply plugin: "java" apply plugin: "groovy" apply plugin: "io.spring.dependency-management" sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 [compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8" [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"] dependencyManagement { imports { mavenBom("org.junit:junit-bom:5.4.2") } } dependencies { def assertjVersion = "3.12.2" def spockVersion = "1.3-groovy-2.5" // for Spock testImplementation("org.spockframework:spock-core:${spockVersion}") testImplementation("org.spockframework:spock-spring:${spockVersion}") // for JUnit 5 + AssertJ // junit-jupiter で junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine の3つが依存関係に追加される testCompile("org.junit.jupiter:junit-jupiter") testRuntime("org.junit.platform:junit-platform-launcher") testImplementation("org.assertj:assertj-core:${assertjVersion}") } def jvmArgsDefault = [ "-ea", "-Dfile.encoding=UTF-8", "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP" ] def jvmArgsAddOpens = [ "--add-opens=java.base/java.io=ALL-UNNAMED", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED", "--add-opens=java.base/java.lang.ref=ALL-UNNAMED", "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", "--add-opens=java.base/java.net=ALL-UNNAMED", "--add-opens=java.base/java.security=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED" ] def printTestCount = { desc, result -> if (!desc.parent) { // will match the outermost suite println "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" } } task testJUnit4AndSpock(type: Test) { jvmArgs = jvmArgsDefault + jvmArgsAddOpens testLogging { afterSuite printTestCount } } test.dependsOn testJUnit4AndSpock test { jvmArgs = jvmArgsDefault + jvmArgsAddOpens // for JUnit 5 useJUnitPlatform() testLogging { afterSuite printTestCount } } } configure(subprojects.findAll { it.name ==~ /^(sample-webapp)$/ }) { apply plugin: "org.springframework.boot" dependencyManagement { imports { mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) } } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") runtimeOnly("org.springframework.boot:spring-boot-devtools") testImplementation("org.springframework.boot:spring-boot-starter-test") } }
- buildscript の以下の点を変更します。
- repositories に
maven { url "https://repo.spring.io/release/" }
を追加します。 - dependencies に
classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE"
を追加します。
- repositories に
configure(subprojects.findAll { it.name ==~ /^(sample-webapp)$/ }) { ... }
の設定を追加します。
sample-webapp プロジェクトの build.gradle に残す設定はないのでファイルを削除します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
Project Tool Window を見ると以下のディレクトリ構成になっています。sample-webapp/build/libs の下に sample-webapp-1.0.0-RELEASE.jar が生成されています。
SampleController クラスを新規作成して仮実装する
Controller クラスが1つもないので /sample
にアクセスしたら "sample-webapp" の文字を返す SampleController クラスを作成します。現時点では仮実装で、sample-stubapp を作成したら、sample-stubapp 内に実装する WebAPI を呼び出すように変更します。
sample-webapp/src/main/java/ksbysample/webapp/samplewebapp/SampleController.java を新規作成し、以下の内容を記述します。
package ksbysample.webapp.samplewebapp; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/sample") public class SampleController { @RequestMapping @ResponseBody public String index() { return "sample-webapp"; } }
Rebuild Project してエラーが出ないことを確認した後、sample-webapp の Tomcat を起動します。
http://localhost:8080/sample にアクセスして "sample-webapp" の文字が出力されることを確認します。
確認後 Tomcat を停止します。
続く。。。
次回は sample-stubapp プロジェクト(こちらが sample-lib の StrNumUtils クラスを呼び出します)を作成した後、sample-webapp の SampleController クラスを本実装して Multi-project を完成させます。
履歴
2019/04/21
初版発行。
AdoptOpenJDK を 11.0.2+9 → 11.0.3+7 へ、IntelliJ IDEA を 2018.3.6 → 2019.1.1 へバージョンアップ
AdoptOpenJDK を 11.0.2+9 → 11.0.3+7 へバージョンアップする
※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。
https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot を見ると 11.0.3+7 がダウンロードできるようになっていましたので、11.0.3+7 へバージョンアップします。
OpenJDK11U-jdk_x64_windows_hotspot_11.0.3_7.msi をダウンロードして D:\Java\jdk1.8.0_202 へインストールした後、環境変数 JAVA_HOME のパスを D:\Java\jdk-11.0.3+7 へ変更します。
コマンドプロンプトから
java -version
を実行し、11.0.3
に変更されていることを確認します。開いているプロジェクトを閉じて「Welcome to IntelliJ IDEA」ダイアログを表示します。
ダイアログ下部の「Configure」-「Project Defaults」-「Project Structure」を選択します。
「Default Project Structure」ダイアログが表示されます。画面左側で「Project Settings」-「Project」を選択後、画面右側の「Project SDK」の「New...」ボタンをクリックし、表示されるメニューから「JDK」を選択します。
「Select Home Directory for JDK」ダイアログが表示されます。D:\Java\jdk-11.0.3+7 を選択した後、「OK」ボタンをクリックします。
「Default Project Structure」ダイアログに戻るので、今度は「Project SDK」の「Edit」ボタンをクリックします。
画面左側で「Platform Settings」-「SDKs」が選択された状態になるので、画面右上の入力フィールドで "11" → "11.0.3+7" へ変更します。
次に中央のリストから「11.0.2+9」を選択した後、リストの上の「-」ボタンをクリックして削除します。
「OK」ボタンをクリックして「Default Project Structure」ダイアログを閉じます。
「Welcome to IntelliJ IDEA」ダイアログに戻ったら、ksbysample-webapp-lending プロジェクトを開きます。
IntelliJ IDEA のメイン画面が開いたら、メニューから「File」-「Project Structure...」を選択します。
「Project Structure」ダイアログが表示されます。以下の画像の状態になっているので、
「Project SDK」を選択し直します。「Project SDK」を「11.0.3+7」に変更すると「Project language level」も自動で「SDK default (11 - Local variable syntax for lambda pa」が選択されました。
「OK」ボタンをクリックして「Project Structure」ダイアログを閉じます。
メイン画面に戻ると画面右下に「Indexing...」の表示が出るので、終了するまで待ちます。
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。
Project Tool Window で src/test/groovy/ksbysample、src/test/java/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample'' with Coverage」を選択し、テストが全て成功することを確認します。
特に問題は発生しませんでした。11.0.3+7 で開発を進めます。
IntelliJ IDEA を 2018.3.6 → 2019.1.1 へバージョンアップする
IntelliJ IDEA の 2019.1.1 がリリースされているのでバージョンアップします。
- IntelliJ IDEA 2019.1.1 is Here!
https://blog.jetbrains.com/idea/2019/04/intellij-idea-2019-1-1-is-here/
※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。
IntelliJ IDEA のメインメニューから「Help」-「Check for Updates...」を選択します。
「IDE and Plugin Updates」ダイアログが表示されます。左下に「Update and Restart」ボタンが表示されていますので、「Update and Restart」ボタンをクリックします。
Plugin の update も表示されました。このまま「Update and Restart」ボタンをクリックします。
Patch がダウンロードされて IntelliJ IDEA が再起動します。
メジャーバージョンアップなので起動時に「Import IntelliJ IDEA Settings From...」ダイアログが表示されます。「Previous version」を選択した状態で「OK」ボタンをクリックします。
IntelliJ IDEA が起動すると画面下部に「Indexing…」のメッセージが表示されますので、終了するまで待機します。
IntelliJ IDEA のメインメニューから「Help」-「About」を選択し、2019.1.1 へバージョンアップされていることを確認します。
Gradle Tool Window を見ると今回のバージョンからまた何も表示されなくなっていました。
左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、いつものツリーが表示されました。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。
Project Tool Window で src/test/groovy/ksbysample、src/test/java/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample'' with Coverage」を選択し、テストが全て成功することを確認します。
最後に C:\Users\root.IntelliJIdea2018.3 を削除します。
Gradle で Multi-project を作成する ( その3 )( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
目次
- Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行してみる- まとめ
手順
Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する
IntelliJ IDEA で sample-cmdapp プロジェクトを作成する
IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成します。
※シンプルなコマンドアプリケーションなので何もチェックしません。
作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。
.gitignore に設定を追加する
sample-cmdapp プロジェクトの下に作成された .gitignore から ### STS ###
、### IntelliJ IDEA ###
、### NetBeans ###
、### VS Code ###
の設定をコピーして、ルートディレクトリの .gitignore に追加します。
# Ignore Gradle project-specific cache directory .gradle # Ignore Gradle build output directory build ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr /out/ ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ ### VS Code ### .vscode/
sample-cmdapp プロジェクトから不要なファイルを削除する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp\sample-cmdapp\
の下には以下のディレクトリ・ファイルがありますが、
src ディレクトリと build.gradle 以外は不要なので削除します。削除すると以下の状態になります。
settings.gradle に sample-cmdapp プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下の settings.gradle に include 'sample-cmdapp'
を追加します。
rootProject.name = 'gradle-multiprj-lib-cmdapp' include 'sample-lib' include 'sample-cmdapp'
追加後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると :sample-cmdapp
が追加されます。
sample-cmdapp プロジェクトの build.gradle から不要な記述を削除し、sample-lib プロジェクトへの依存関係を追加する
sample-cmdapp プロジェクトの build.gradle を以下の内容に変更します。
plugins { id "org.springframework.boot" version "2.1.4.RELEASE" } dependencyManagement { imports { mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) } } dependencies { implementation("org.springframework.boot:spring-boot-starter") testImplementation("org.springframework.boot:spring-boot-starter-test") implementation project(":sample-lib") }
sample-cmdapp の設定はプロジェクトのルートディレクトリにある build.gradle に project(':sample-cmdapp') { ... }
で記述することも可能ですが、その場合 plugins { ... }
が使えなくなるので sample-cmdapp の下に build.gradle を残してこの中に設定を記述することにします。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
SampleCmdappApplication クラスに CommandLineRunner インターフェースを実装する
sample-cmdapp/src/main/java/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplication.java を以下のように変更します。
package ksbysample.cmdapp.samplecmdapp; import ksbysample.lib.samplelib.StrNumUtils; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SampleCmdappApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(SampleCmdappApplication.class, args); } @Override public void run(String... args) throws Exception { System.out.println("★★★ " + StrNumUtils.plus("1", "2")); } }
クラスに implements CommandLineRunner
を追加し run メソッドを実装します。run メソッド内で sample-lib プロジェクトの StrNumUtils クラスを呼び出すようにします。
次にテストクラスを作成します。Spring Initializr でプロジェクトを作成したので sample-cmdapp/src/test/java/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplicationTests.java が作成されていますが、このテストはファイル毎削除して Spock で作り直します。
cmdapp/src/test/groovy/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplicationTest.groovy が新規作成されますので、以下の内容を記述します。
package ksbysample.cmdapp.samplecmdapp import spock.lang.Specification class SampleCmdappApplicationTest extends Specification { def "sample-cmdapp を実行すると'★★★ 3'が出力される"() { setup: def buf = new ByteArrayOutputStream(1024) System.out = new PrintStream(buf) when: SampleCmdappApplication.main() then: buf.toString().contains("★★★ 3") } }
ここまでで以下のディレクトリ構成になります。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
各プロジェクトの build/libs ディレクトリの下に sample-cmdapp-1.0.0-RELEASE.jar、sample-lib-1.0.0-RELEASE.jar が作成されています。
sample-cmdapp-1.0.0-RELEASE.jar を zip ソフトで開いてみると BOOT-INF/lib の下に sample-lib-1.0.0-RELEASE.jar が入っていることも確認できます。
java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行してみる
Multi-project で作成した sample-cmdapp-1.0.0-RELEASE.jar が問題なく動作することをコマンドラインから確認してみます。
コマンドラインから java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行すると "★★★ 3" が出力されることが確認できました。
まとめ
- Multi-project ではルートディレクトリの build.gradle の
subprojects { ... }
に共通の設定を記述する。plugin の設定だけplugins { ... }
が使えないのでapply plugin: "..."
で記述すること。 - Spring を使用しないライブラリのサブプロジェクトを作成したい時はサブプロジェクトのディレクトリを作成した後、settings.gradle に
include '<サブプロジェクトのディレクトリ名>'
を書いてから IntelliJ IDEA の Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すればよい(おそらくコマンドだとgradle wrapper
だと思われる)。 - Spring Boot ベースのコマンドラインアプリケーションのサブプロジェクトを作成したい時は Spring Initializr でサブプロジェクトを作成してから src, build.gradle 以外を削除し、settings.gradle に
include '<サブプロジェクトのディレクトリ名>'
を書いてから IntelliJ IDEA の Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すればよい。 - サブプロジェクトの build.gradle の設定はサブプロジェクトのディレクトリの下に build.gradle を置いてその中に記述するか、ルートディレクトリの build.gradle に
project(':<サブプロジェクトのディレクトリ名>') { ... }
の形式で記述する。
Multi-project を初めて作ってみましたが、Gradle Guides の Creating Multi-project Builds に基本は書かれているので、これを読めば何とか作れるものですね。
履歴
2019/04/20
初版発行。
Gradle で Multi-project を作成する ( その2 )( lib+cmdapp編、Multi-project の設定ファイルと Spring を使用しないライブラリのプロジェクトを作成する )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その1 )( 概要 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Gradle で Spring を使用しないライブラリ+Spring Boot ベースのコマンドラインアプリケーションの Multi-project を作成します。
- 2回に分けて書きます。
- 今回は Multi-project のための各種設定ファイルとSpring を使用しないライブラリのプロジェクトを作成します。
参照したサイト・書籍
Gradle Guides - Creating Multi-project Builds
https://guides.gradle.org/creating-multi-project-builds/The Gradle Wrapper
https://docs.gradle.org/5.0/userguide/gradle_wrapper.html#sec:wrapper_generationAuthoring Multi-Project Builds
https://docs.gradle.org/current/userguide/multi_project_builds.html
目次
- 方針
- gradle-multiprj-lib-cmdapp ディレクトリを作成する
- Spring Initializr で作成したプロジェクトから Gradle Wrapper のファイルをコピーする
- Gradle を最新バージョンにする
- gradlew init を実行する
- build.gradle に subproject 共通の設定を追加する
- Spring を使用しないライブラリのプロジェクトを作成する
- IntelliJ IDEA で gradle-multiprj-lib-cmdapp プロジェクトをオープンする
- Project SDK を JDK 11 に設定する
- StrNumUtils クラスを追加する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- 続く。。。
手順
方針
- 以下のディレクトリ構成の Multi-project を作成します。
gradle-multiprj-lib-cmdapp ├ sample-cmdapp <-- Spring Boot ベースのコマンドラインアプリケーションの Project └ sample-lib <-- Spring を使用しないライブラリの Project
- Spring Boot ベースのコマンドラインアプリケーションの Project では Profile は作成しません。
- テスティングフレームワークは全ての Project で JUnit 5 と Spock を使用できるようにします。
- checkstyle, spotbugs, pmd, error-prone は今回は導入しません。
gradle-multiprj-lib-cmdapp ディレクトリを作成する
ksby/ksbysample-boot-miscellaneous の repository を checkout している D:\project-springboot\ksbysample-boot-miscellaneous
の下に gradle-multiprj-lib-cmdapp ディレクトリを作成します。
Spring Initializr で作成したプロジェクトから Gradle Wrapper のファイルをコピーする
IntelliJ IDEA で Spring Initializr の新規 Gradle プロジェクトを作成します。
ここから以下のディレクトリ・ファイルを D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下にコピーします。
- gradle ディレクトリ
- gradlew
- gradlew.bat
Gradle を最新バージョンにする
コピーした gradle/wrapper/gradle-wrapper.properties を見ると Gradle のバージョンは 5.2.1 だったのですが、https://gradle.org/releases/ を見ると Gradle の最新バージョンは 5.4 なので 5.4 にバージョンアップします。
コマンドプロンプトから gradlew wrapper --gradle-version=5.4
、gradlew --version
、gradlew wrapper
コマンドを実行します。
gradle/wrapper/gradle-wrapper.properties を見ると 5.4 になっています。
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
gradlew init を実行する
gradlew init
コマンドを実行します。選択肢は 1: basic
、1: groovy
を選択し、Project name は何も入力せずに Enter キーを押します。
gradle-multiprj-lib-cmdapp ディレクトリの下は以下のようになり、
生成された .gitignore、build.gradle、settings.gradle は以下の内容になっています。
■.gitignore
# Ignore Gradle project-specific cache directory .gradle # Ignore Gradle build output directory build
■build.gradle
/* * This file was generated by the Gradle 'init' task. * * This is a general purpose Gradle build. * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ */
■settings.gradle
/* * This file was generated by the Gradle 'init' task. * * The settings file is used to specify which projects to include in your build. * * Detailed information about configuring a multi-project build in Gradle can be found * in the user manual at https://docs.gradle.org/5.4/userguide/multi_project_builds.html */ rootProject.name = 'gradle-multiprj-lib-cmdapp'
build.gradle に subproject 共通の設定を追加する
build.gradle に subproject 共通の設定を追加します。以下の内容に変更します。
buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "io.spring.gradle:dependency-management-plugin:1.0.7.RELEASE" } } allprojects { repositories { mavenCentral() } } subprojects { group "ksby.ksbysample-boot-miscellaneous" version "1.0.0-RELEASE" apply plugin: "java" apply plugin: "groovy" apply plugin: "io.spring.dependency-management" sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 [compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8" [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"] dependencyManagement { imports { mavenBom("org.junit:junit-bom:5.4.2") } } dependencies { def assertjVersion = "3.12.2" def spockVersion = "1.3-groovy-2.5" // for Spock testImplementation("org.spockframework:spock-core:${spockVersion}") testImplementation("org.spockframework:spock-spring:${spockVersion}") // for JUnit 5 + AssertJ // junit-jupiter で junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine の3つが依存関係に追加される testCompile("org.junit.jupiter:junit-jupiter") testRuntime("org.junit.platform:junit-platform-launcher") testImplementation("org.assertj:assertj-core:${assertjVersion}") } def jvmArgsDefault = [ "-ea", "-Dfile.encoding=UTF-8", "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP" ] def jvmArgsAddOpens = [ "--add-opens=java.base/java.io=ALL-UNNAMED", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED", "--add-opens=java.base/java.lang.ref=ALL-UNNAMED", "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", "--add-opens=java.base/java.net=ALL-UNNAMED", "--add-opens=java.base/java.security=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED" ] def printTestCount = { desc, result -> if (!desc.parent) { // will match the outermost suite println "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" } } task testJUnit4AndSpock(type: Test) { jvmArgs = jvmArgsDefault + jvmArgsAddOpens testLogging { afterSuite printTestCount } } test.dependsOn testJUnit4AndSpock test { jvmArgs = jvmArgsDefault + jvmArgsAddOpens // for JUnit 5 useJUnitPlatform() testLogging { afterSuite printTestCount } } }
subprojects { ... }
内で subproject 共通の Gradle plugin を記述する時にplugins { ... }
は使えません。apply plugin: "..."
で記述します。
Spring を使用しないライブラリのプロジェクトを作成する
sample-lib ディレクトリを作成する
gradle-multiprj-lib-cmdapp ディレクトリの下に sample-lib ディレクトリを作成します。
settings.gradle に sample-lib プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下の settings.gradle に include 'sample-lib'
を追加します。
rootProject.name = 'gradle-multiprj-lib-cmdapp' include 'sample-lib'
IntelliJ IDEA で gradle-multiprj-lib-cmdapp プロジェクトをオープンする
gradle-multiprj-lib-cmdapp プロジェクトを以下の画像の手順でオープンします。
IntelliJ IDEA のメイン画面が表示されると Project Tool Window には以下のように表示されます。
Gradle Tool Window は以下のように表示されます。
Project SDK を JDK 11 に設定する
IntelliJ IDEA のメインメニューから「File」-「Project Structure...」を選択し「Project Structure」ダイアログを表示し「Project SDK」で JDK 11 を、「Project language level」で「SDK default(11 - local variable syntax for lambda parameters)」を選択して「OK」ボタンをクリックします。
StrNumUtils クラスを追加する
sample-lib/src/main/java の下に ksbysample.lib.samplelib パッケージを作成し、その下に StrNumUtils.java を新規作成して以下の内容を記述します。
package ksbysample.lib.samplelib; public class StrNumUtils { public static String plus(String v1, String v2) { return String.valueOf(Integer.parseInt(v1) + Integer.parseInt(v2)); } }
テストクラスも作成します。今回は JUnit 5 で作成します。
src/test/java/ksbysample/lib/samplelib/StrNumUtilsTest.java が新規作成されるので、以下の内容を記述します。
package ksbysample.lib.samplelib; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class StrNumUtilsTest { @Test @DisplayName("plusメソッドのテスト") void plus() { assertThat(StrNumUtils.plus("1", "2")).isEqualTo("3"); } }
ここまでで以下のディレクトリ構成になります。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
sample-lib ディレクトリの下に build, out ディレクトリが作成されており、sample-lib/build/libs の下に sample-lib-1.0.0-RELEASE.jar が出力されていました。
ここまでは問題なさそうです。
続く。。。
次回は Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成して Multi-project を完成させます。
履歴
2019/04/20
初版発行。
Gradle で Multi-project を作成する ( その1 )( 概要 )
概要
記事一覧はこちらです。
- Gradle の Multi-project を作成したことがないので、作成手順を覚えるために作成してみます。
- 以下のパターンの Multi-project を作成してみる予定です。Spring Boot ベースのアプリケーションを最低1つ+ライブラリのプロジェクト(Spring ベースかは問わない)を最低1つ+何か加えたものという構成です。
- 他にやりたいパターンが思い浮かんだら変えるかもしれません。
- 作成した Multi-project は ksby/ksbysample-boot-miscellaneous の repository にコミットします。
履歴
2019/04/18
初版発行。