1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Spring Batch 6】Jarを作成してMacのシェルスクリプトからバッチを実行する

1
Posted at

はじめに

この記事は自分の学習用、備忘録として書いてるものです。
もし内容に間違いなどがあればご指摘ください。

・使用技術
Java21
Spring Boot4.0.6
Spring Batch6.0.3
MySQL

・環境
Mac

この記事の目的

Spring BatchアプリをEclipse上の実行から切り離し、Jarファイルとして作成してコマンドから実行する流れを整理する。

今回は、MavenでJarを作成し、Mac用のrunHelloBatch.shからSpring Batchを実行するところまでをまとめる。


最終的なゴール

最終的には、以下の状態を目指す。

1. Maven packageでJarファイルを作成する
2. target配下にJarが生成されることを確認する
3. Mac用のrunHelloBatch.shを作成する
4. chmodで実行権限を付与する
5. runHelloBatch.shからJarを実行する
6. param1 / param2をJobParametersとして渡す
7. Spring Bootが起動し、バッチが実行されることを確認する
8. ログファイルの出力場所を確認する

今回やりたいこと

今まではEclipseの実行構成からSpring Batchを起動していた。

ただし、実際のバッチ処理では、Eclipseから起動するのではなく、Jarファイルを作成してコマンドやスクリプトから実行することが多いと聞く。

今回の目的は、以下の流れを理解すること。

開発中
  → Eclipseから実行

リリース・実行時
  → Jarを作成する
  → java -jarで実行する
  → 引数でJobParametersを渡す
  → ログを確認する

つまり、Spring Batchアプリを「開発環境上で動くもの」から「外部から実行できるリリース資材」にする練習。


Maven packageでJarを作成する

Spring Bootプロジェクトでは、Mavenのpackageを実行することでJarファイルを作成できる。

Eclipseの場合は、以下のように実行した。

プロジェクトを右クリック
→ 実行
→ Mavenビルド
→ ゴールに package を指定
→ 実行

ターミナルで実行するなら、プロジェクト直下で以下。

./mvnw package

package実行時にテストで失敗した

最初にpackageを実行したとき、ビルドが失敗した。

エラーの内容は、Jar作成そのものではなく、packageの途中で実行されるテストが失敗していた。

エラーの中心は以下。

Tests run: 1, Failures: 0, Errors: 1

さらに原因として、以下が出ていた。

InvalidJobParametersException:
param1の値はnullです。DEV、TEST、PRODのいずれかを指定してください。

これは、テスト実行時にSpring BootのApplicationContextが起動し、その中でSpring BatchのJobも起動しようとしたため。

しかし、今回のテスト実行時にはparam1が渡されていなかった。

その結果、自作のJobParameters Validatorでparam1=nullと判定され、テストが失敗した。

流れとしては以下。

mvn package
  → compile
  → test
  → Spring Bootのテストが起動
  → Batch Jobも自動実行される
  → param1が渡されていない
  → Validatorでエラー
  → test失敗
  → package失敗

対応:Jar作成を優先してテストをスキップした

今回の目的は、まずJarを作成してバッチを実行すること。

そのため、EclipseのMavenビルド設定で以下のようにした。

ゴール: package -DskipTests
プロファイル: 空欄

-DskipTestsを付けることで、テストを実行せずにJar作成まで進める。

./mvnw package -DskipTests

これでBUILD SUCCESSになった。

ここで分かったことは以下。

Javaコードのコンパイルは通っている
Jar作成処理自体も問題ない
⭐️失敗していたのは別の記事で作成して放置していたpackage中に実行されるテストだった

Mavenビルドのプロファイルにpom.xmlを指定しない

間違えた箇所の1つに
最初は、EclipseのMavenビルド設定で「プロファイル」にpom.xmlを指定していた。

しかし、ログには以下のような警告が出ていた。

The requested profile "pom.xml" could not be activated because it does not exist.

pom.xmlはMavenの設定ファイルであって、プロファイル名ではない。

そのため、今回のように特別なMaven profileを作っていない場合、プロファイルの設定は空欄にしないといけなかった

ゴール: package -DskipTests
プロファイル: 空欄

Jarが作成される場所

packageが成功すると、プロジェクト配下のtargetフォルダにJarが作成される。

例。

hello-spring-batch/
├─ src/
├─ pom.xml
└─ target/
   └─ hello-spring-batch-0.0.1-SNAPSHOT.jar

Jar名はpom.xmlartifactIdversionによって変わる。

そのため、実行前に実際のJar名を確認する。

ls target

Jarを直接実行するコマンド

Jarは以下のように実行できる。

java -jar target/hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

各部分の意味

java

Javaを起動するコマンド。

-jar

Jarファイルを実行する指定。

target/hello-spring-batch-0.0.1-SNAPSHOT.jar

実行対象のJarファイル。

param1=PROD param2=1000

Spring BatchのJobParametersとして渡す値。

Tasklet側で以下のように受け取っている場合、

@Value("#{jobParameters['param1']}")
private String param1;

@Value("#{jobParameters['param2']}")
private String param2;

実行時には以下のように値が入る。

param1 → PROD
param2 → 1000

Windows用の実行ファイルをMac用に置き換える

最初に使っていた実行用テキストはWindows用だった。

set PATH=C:\pleiades-2023\java\21\bin;%PATH%
cd C:\pleiades-2023\workspace\hello-spring-batch\target
java -jar hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

しかし自分んがWindowsではなくMacを使っているため内容を修正する必要があった。
WindowsとMacでは、スクリプトの書き方が違う。

対応関係は以下。

Windowsのset PATH=...
  → Macではexport PATH=...

WindowsのC:\...
  → Macでは/Users/...

Windowsの.bat
  → Macでは.sh

java -jar
  → Macでも同じ

今回改めてMac用に変更した内容が以下の通り。

#!/bin/bash

export PATH=$(/usr/libexec/java_home -v 21)/bin:$PATH

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch/target

java -jar hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

今回のMacでは、以下でJava 21が使えることを確認した。

java -version

出力例。

java version "21.0.5" 2024-10-15 LTS

そのため、export PATH=...は不要だった。


Mac用のrunHelloBatch.sh

最初は以下のようなシェルスクリプトにした。

#!/bin/bash

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch/target

java -jar hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

このスクリプトは、以下の流れで動く。

1. targetフォルダへ移動する
2. target内のJarを指定して実行する
3. param1=PROD param2=1000をJobParametersとして渡す

実行権限を付ける

Macでは、.shファイルを実行するために実行権限が必要になる。

runHelloBatch.shがデスクトップにある場合は、以下。

cd ~/Desktop
chmod +x runHelloBatch.sh

Downloadsフォルダにある場合は、以下。

cd ~/Downloads
chmod +x runHelloBatch.sh

実行する。

./runHelloBatch.sh

Spring Bootのロゴが出ればJarは起動できている

実行後に以下のようなSpring Bootのロゴが出た。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v4.0.6)

この時点で、Jar自体は起動できている。

つまり、少なくとも以下は成功している。

Jarファイルは存在している
java -jarで起動できている
Spring Bootアプリとして読み込まれている

ログファイルがtarget/logに出力された理由

実行後、Eclipseのプロジェクト直下にはログが見当たらなかった。

確認したところ、ログは以下に出力されていた。

hello-spring-batch/target/log/

理由は、runHelloBatch.shtargetフォルダに移動してからJarを実行していたため。

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch/target
java -jar hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

一方、logback.xmlではログ出力先を以下のようにしていた。

<property name="logDir" value="./log/" />

この./log/./は、Jarが置いてある場所ではなく、Javaコマンドを実行したときのカレントディレクトリを基準にする。

今回のカレントディレクトリはtarget

そのため、ログは以下に出た。

hello-spring-batch/target/log/

これは異常ではなく、正常な動き。


プロジェクト直下のlogに出したい場合

プロジェクト直下にログを出したいなら、runHelloBatch.shcd先をプロジェクト直下にする。

#!/bin/bash

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch

java -jar target/hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

この書き方にすると、./log/の基準がプロジェクト直下になる。

出力先は以下。

hello-spring-batch/log/

この方が分かりやすい。

プロジェクト直下に移動
  → target配下のJarを指定
  → logはプロジェクト直下に出る

自然なrunHelloBatch.shの書き方

今回の学習では、最終的に以下の形が自然。

#!/bin/bash

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch

java -jar target/hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

この書き方にする理由

1. プロジェクト直下を基準にできる
2. target配下のJarを明示的に指定できる
3. logback.xmlの./log/がプロジェクト直下を指す
4. ログの出力場所が分かりやすい

各コードの説明

#!/bin/bash

#!/bin/bash

このファイルをbashで実行するための指定。

シェルスクリプトの先頭に書く。


cd ...

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch

プロジェクト直下へ移動している。

この移動先が、相対パスの基準になる。

例えばlogback.xmlで以下を書いている場合、

<property name="logDir" value="./log/" />

./log/は、ここでcdした場所を基準にする。


java -jar ...

java -jar target/hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

作成したJarを実行している。

target/hello-spring-batch-0.0.1-SNAPSHOT.jarは、Maven packageで作成したJarファイル。

param1=PROD param2=1000は、Spring BatchのJobParameters。


なぜこのように書くといいのか

Eclipseに依存せず実行できる

Eclipseの実行ボタンを使わなくても、Jarとシェルスクリプトがあればバッチを実行できる。

これは実務のバッチ実行に近い。


実行コマンドを固定できる

毎回コマンドを手入力しなくてよい。

./runHelloBatch.sh

これだけで実行できる。


JobParametersを明示できる

実行時に渡す値がスクリプトに書かれているため、どのパラメータで実行したか分かりやすい。

param1=PROD param2=1000

ログの出力場所を制御しやすい

cdする場所を決めることで、./log/の基準も決まる。

cd target
  → target/log/

cd プロジェクト直下
  → プロジェクト直下/log/

この考え方を理解しておくと、ログがどこに出たのか迷いにくい。


注意する箇所

1. packageはテストも実行する

mvn packageはJarを作るだけではない。

途中でテストも実行される。

今回のように、テスト実行時にBatch Jobが自動起動して失敗することがある。

Jar作成を優先するなら、以下でテストをスキップできる。

./mvnw package -DskipTests

ただし、これは一時的な回避策。

本来はテスト側でBatch Jobの自動実行を止めるなど、テストが通るように直すのが自然。

例。

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(properties = "spring.batch.job.enabled=false")
class HelloSpringBatchApplicationTests {

    @Test
    void contextLoads() {
    }
}

contextLoadsの目的は、SpringのApplicationContextが起動できるかの確認。

Job実行テストではないなら、テスト時にBatch Jobを自動実行しないようにするのが分かりやすい。


2. Mavenのプロファイルにpom.xmlを入れない

EclipseのMavenビルド設定で、プロファイルにpom.xmlを入れる必要はない。

pom.xmlはMavenの設定ファイル。

profileを定義していないなら、プロファイルは空欄でよい。

ゴール: package -DskipTests
プロファイル: 空欄

3. Jar名は必ず確認する

Jar名はプロジェクト設定によって変わる。

実行前に以下で確認する。

ls target

実際に出ているJar名に合わせて、java -jarの指定を修正する。


4. Javaバージョンを確認する

今回の環境ではJava 21を使っていた。

java -version

出力例。

java version "21.0.5" 2024-10-15 LTS

Eclipseでは動くのにターミナルでは動かない場合、Javaのバージョン違いが原因になることがある。


5. .shには実行権限が必要

Macでは、シェルスクリプトに実行権限を付ける必要がある。

chmod +x runHelloBatch.sh

実行する。

./runHelloBatch.sh

6. ./log/はJarの場所ではなくカレントディレクトリ基準

ここは特に注意。

logback.xmlに以下を書いている場合、

<property name="logDir" value="./log/" />

./log/は、Jarがある場所ではなく、java -jarを実行した場所を基準にする。

cd target
java -jar xxx.jar

この場合は、

target/log/

に出る。

cd プロジェクト直下
java -jar target/xxx.jar

この場合は、

プロジェクト直下/log/

に出る。


7. Eclipseの表示は自動更新されないことがある

ターミナルからJarを実行してファイルが作成されても、Eclipseの画面にすぐ表示されないことがある。

その場合は、プロジェクトを右クリックして以下を実行する。

Refresh

今回学んだこと

今回の学習で一番重要だったのは、Jar作成とバッチ実行の流れ。

Maven packageでJarを作る
  → java -jarで実行する
  → JobParametersを渡す
  → ログで結果を確認する

また、Jar作成時のエラーも、単に「Jarが作れない」と見るのではなく、どのフェーズで失敗しているかを見る必要がある。

今回の場合は、Jar作成処理ではなく、package中のテストで失敗していた。


まとめ

今回やったことは以下。

1. EclipseのMavenビルドでpackageを実行した
2. テスト失敗により一度BUILD FAILUREになった
3. package -DskipTestsでJar作成を優先した
4. target配下にJarが作成された
5. Windows用のbat相当の処理をMac用のshに置き換えた
6. chmod +xで実行権限を付けた
7. ./runHelloBatch.shでJarを実行した
8. Spring Bootが起動することを確認した
9. ログがtarget/logに出る理由を確認した
10. プロジェクト直下/logに出すならcd先を変えると分かった

今回の理解ポイントは以下。

Jarはリリース資材
mvn packageはJar作成前にテストも実行する
-DskipTestsはテストを実行せずJar作成を優先する指定
java -jarはJarを実行するコマンド
param1=PROD param2=1000はJobParameters
.shはMac用の実行スクリプト
./log/はカレントディレクトリ基準

最終的なMac用スクリプトは以下の形が分かりやすい。

#!/bin/bash

cd /Users/kounoyuuta/Desktop/workspace/SpringBatch/hello-spring-batch

java -jar target/hello-spring-batch-0.0.1-SNAPSHOT.jar param1=PROD param2=1000

参考記事

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?