Gradle で Multi-project を作成する ( その13 )( doma2lib+cmdapp+webapp編、PropertiesLauncher を利用して doma2-lib の jar ファイルを外部に出す )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その12 )( doma2lib+cmdapp+webapp編、sample-webapp プロジェクトを作成する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Doma 2 の Entity、Dao を提供するライブラリ+Spring Boot ベースのコマンドラインアプリケーション+Spring Boot ベースの Web アプリケーションの Multi-project を作成します。
- doma2lib+cmdapp+webapp編のここまでの記事では実行可能 Jar ファイルを起動するのに JarLauncher を利用する方式でしたので sample-cmdapp-1.0.0-RELEASE.jar、sample-webapp-1.0.0-RELEASE.jar の中に doma2-lib-1.0.0-RELEASE.jar が入っていましたが、PropertiesLauncher を利用する方式に変更して doma2-lib-1.0.0-RELEASE.jar を外部に出すようにしてみます。
参照したサイト・書籍
E.3 Launching Executable Jars
https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html#executable-jar-launchingSpring Boot 2 and external libs with the PropertiesLauncher
https://medium.com/saas-startup-factory/spring-boot-2-and-external-libs-with-the-propertieslauncher-fc49d2d93636Gradle Docs 5.4.1 - Copy
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html
目次
- gradle-multiprj-doma2lib-cmdwebapp の build.gradle を変更する
- sample-cmdapp、sample-webapp の build.gradle を変更する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- 動作確認
- sample-webapp を IntelliJ IDEA の Run Dashboard から起動するとどうなるのか?
- 次回は。。。
手順
gradle-multiprj-doma2lib-cmdwebapp の build.gradle を変更する
PropertiesLauncher を利用するのに必要な設定と、jar ファイルを gradle-multiprj-doma2lib-cmdwebapp プロジェクトのルートディレクトリ直下の libs ディレクトリ(新規に作成します)にコピーするための task を gradle-multiprj-doma2lib-cmdwebapp の build.gradle に記述します。
build.gradle を以下のように変更します。
.......... subprojects { .......... // サブプロジェクトの build/libs の下に生成された jar ファイルを // プロジェクトのルートディレクトリ直下の libs ディレクトリにコピーする task copyJarToLibsDir(type: Copy) { from "build/libs" include "*.jar" into "${rootDir}/libs" } copyJarToLibsDir.dependsOn test check.dependsOn copyJarToLibsDir } configure(subprojects.findAll { it.name ==~ /^(doma2-lib|sample-cmdapp|sample-webapp)$/ }) { .......... } configure(subprojects.findAll { it.name ==~ /^(sample-cmdapp|sample-webapp)$/ }) { bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' } } }
- subproject block 内に
task copyJarToLibsDir(type: Copy) { ... }
を追加します。また test タスクの後に実行するためにcopyJarToLibsDir.dependsOn test
、check.dependsOn copyJarToLibsDir
の2行を追加します。 - configure は複数記述できるようなので、sample-cmdapp、sample-webapp だけに適用する設定を記述する
configure(subprojects.findAll { it.name ==~ /^(sample-cmdapp|sample-webapp)$/ }) { ... }
を追加します。この中に PropertiesLauncher を利用するのに必要な設定を記述します。
またプロジェクトのルートディレクトリ直下に libs ディレクトリを作成しておきます。
sample-cmdapp、sample-webapp の build.gradle を変更する
sample-cmdapp、sample-webapp の build.gradle では doma2-lib への依存関係を implementation
で記述しており、このままでは jar ファイル内に doma2-lib-1.0.0-RELEASE.jar が含まれてしまうので、implementation project(":doma2-lib")
→ compileOnly project(":doma2-lib")
に変更します。
■sample-cmdapp の build.gradle
dependencies { implementation("org.springframework.boot:spring-boot-starter") compileOnly project(":doma2-lib") implementation("com.univocity:univocity-parsers:2.8.1") implementation("args4j:args4j:2.33") implementation("com.github.rozidan:modelmapper-spring-boot-starter:1.0.0") }
■sample-webapp の build.gradle
dependencies { implementation("org.springframework.boot:spring-boot-starter-web") runtimeOnly("org.springframework.boot:spring-boot-devtools") compileOnly project(":doma2-lib") }
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
必要な設定は以上で完了です。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行い、jar ファイルを生成し直して libs ディレクトリに集めます。
エラーメッセージは出ずに BUILD SUCCESSFUL が出力されています。各サブプロジェクトの test タスクの後では copyJarToLibsDir タスクが実行されて、
libs ディレクトリの下に doma2-lib-1.0.0-RELEASE.jar、sample-cmdapp-1.0.0-RELEASE.jar、sample-webapp-1.0.0-RELEASE.jar がコピーされています。
sample-cmdapp-1.0.0-RELEASE.jar を表示させてみると lib ディレクトリの下には doma2-lib-1.0.0-RELEASE.jar は入っておらず、
sample-webapp-1.0.0-RELEASE.jar の方にも同様に入っていませんでした。
動作確認
employee テーブルのデータは以下の状況です。
PropertiesLauncher を利用する方式の場合、外部に配置した jar ファイルがある場所を loader.path
で指定します。今回はコマンドラインからアプリを実行する時に libs ディレクトリに移動した後 -Dloader.path=.
を追加したコマンドを使用するようにします。
コマンドラインから java -Dspring.profiles.active=product -Dloader.path=. -Dbatch.execute=EmployeeDataCsvToDbLoader -jar sample-cmdapp-1.0.0-RELEASE.jar -csvfile=D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-doma2lib-cmdwebapp\sample-cmdapp\src\test\resources\employee.csv
コマンドを実行するとエラーは出ずに終了し、
employee テーブルにもデータが登録されていました。
java -Dspring.profiles.active=product -Dloader.path=. -jar sample-webapp-1.0.0-RELEASE.jar
で sample-webapp を起動した後、
http://localhost:8080/sample にアクセスすると employee テーブルに登録されているデータが表示されました。
動作は問題なさそうです。
また libs ディレクトリから doma2-lib-1.0.0-RELEASE.jar を削除した後、sample-cmdapp を実行しようとすると java.lang.NoClassDefFoundError: ksbysample/lib/doma2lib/dao/EmployeeDao
が発生してエラーで終了しました。
sample-webapp を起動しようとすると java.lang.ClassNotFoundException: ksbysample.lib.doma2lib.entity.Employee
が発生して、こちらもエラーで終了しました。
(.....途中省略.....)
sample-webapp を IntelliJ IDEA の Run Dashboard から起動するとどうなるのか?
JarLauncher か PropertiesLauncher かは実行可能 Jar で起動する時の話ですので、Run Dashboard から起動する時には関係がありません。
Configuration でも Main class には org.springframework.boot.loader.PropertiesLauncher
ではなく ksbysample.app.samplewebapp.SampleWebappApplication
を指定しているので、
設定を変更しなくても起動します。
次回は。。。
Doma 2 の Dao インターフェース、Entity クラスを別の jar ファイルにしようとすると意外に大変ですね。今回は知らないことがいろいろありました。
Gradle で Multi-project を作成する ( その1 )( 概要 ) に記載していたパターンは一通り作成しましたが、サブプロジェクトの1つが Javascript のプロジェクト(Vue.js かな?)+1つは Spring Boot ベースのプロジェクトのパターンを作成してみたいと思ったので、もう1パターンだけ作成してみます。
履歴
2019/05/01
初版発行。