シェルスクリプトとcronを使ってJavaプロジェクトを自動実行する
はじめに
今回は、「シェルスクリプト」と「cron」を用いて、
Javaプロジェクトを自動実行する手順について記録していきたいと思います。
メインは「シェルスクリプト」と「cron」の設定ですが、個人的にJavaプロジェクトの扱い方に悩んだ時間が長かったため、コンパイルの部分から手順に含めていきます。
開発環境
・JDK17
・Spring Tool Suite4
※ Eclipseで作成したJavaプロジェクトで問題ありません
前提
今回は、「削除扱いになっているユーザーデータ」を「削除済みユーザーテーブル」にデータ移行をするJavaプロジェクトを自動実行するというケースで行います。
プロジェクト自体のコードは割愛しますが、実際に使用するクラスは以下の通りです。
・DBmanager → DriverManagerクラスを使用して、データベースへの接続、切断を管理するクラス
・DeletedUser → 削除済みユーザー情報を持つEntityクラス
・DeletedUserDao → 削除済みユーザーテーブルを操作するDaoクラス( insert処理 )
・InsertDeletedUser → 実行を行うMainクラス( ユーザ情報を取得し、削除済みユーザーテーブルへinsert )
・UserDao → ユーザーテーブルを操作するDaoクラス
( 削除扱いユーザー情報のSELECT処理と移行完了データのユーザーテーブルからの削除)
手順
①プロジェクト外にコンパイル後のクラスを格納するディレクトリの作成
②作成したプロジェクトのコンパイルを行う(postgeSQLドライバーも格納)
③コンパイル後のクラスを格納するディレクトリにmanifest.mfを作成する
④jarファイルを作成する
⑤シェルスクリプトファイルを作成する(実行権限の確認も行う)
⑥cronに自動実行を行う処理を記載する
①プロジェクト外にコンパイル後のクラスを格納するディレクトリの作成
保存したいディレクトリに移動してから、コンパイル後のクラスを格納する「deleted_user_compile」ディレクトリを作成する。
% cd / Users / 自分のhome / workspace
% mkdir deleted_user_compile
②作成したプロジェクトのコンパイルを行う(postgeSQLドライバーも格納)
コンパイルしたいプロジェクトのクラスが格納されているディレクトリの1つ上のディレクトリに移動し、依存関係の数が少ないクラスからコンパイルをする。
※両方満たさないと「シンボルがありません」のエラーが出てコンパイルできません。
今回の場合、依存関係の数が少ないクラスの順番は、
⒈「DBManagerクラス」
⒉「DeletedUserクラス」(エンティティクラス)
⒊「UserDaoクラス」(Daoクラス)
⒋「DeletedUserDaoクラス」(Daoクラス)
⒌「InsertDeletedUserクラス」(Mainクラス)
となっており、ざっくりな順番だと
DBManagerクラス → エンティティクラス → Daoクラス → Mainクラス
で行うと問題ないかと思います。
そして、このコンパイルディレクトリに「PostgreSQLドライバー」のjarファイルを格納することを忘れないようにします。
この時点でのコンパイルディレクトリの中身は以下のようになります。
▽deleted_user_compile
▽deleted_user_compile / shell_cron
③コンパイル後のクラスを格納するディレクトリにmanifest.mfを作成する
「deleted_user_comile」ディレクトリに移動した後、
manifest.mfを作成し、その中にメインメソッドのクラスの設定を行います。
ここでの注意点は、
「Main-Class:」の後、必ず空欄「 」を入れることと、
「〜/ InsertDeletedUser」の後改行をすることです。
これがないと上手く実行できないことがあります。
④jarファイルを作成する
コンパイルしたクラスのjarファイルを作成します。
ちなみにここで指定しているオプションは以下の通りです。
⑤シェルスクリプトファイルを作成する(実行権限の確認も行う)
Javaプロジェクト(「test_shell_cron」)に戻り、シェルスクリプトファイルを作成する。
(シェルスクリプトファイル自体は別にJavaプロジェクトに入れなくてもいいかもしれませんが、管理しやすいのでこちらに作成します。)
シェルスクリプトファイルには実行したいファイルの記載と、必要なクラスパスを記載します。
まず、1行目に 「#!/bin/bash」もしくは「#!/bin/sh」を記載する。
bashにしかない機能を使用したいときにこの記載がないと動かない可能性があるため記載しておく。
そして、自動実行したいクラスを指定する。
「java -cp 依存関係にあるクラスのパス(:繋ぎで記載する) 実行したいクラス」
今回は依存関係にあるのは、「postgreSQLドライバー」とメインクラスと依存関係にあるクラスもまとまっている「insert_deleted_user.jarファイル」のため、
その2つのをパスを記載したあと、メインクラスを記載する。
ここで、現在の「insert_deleted_user.sh」ファイルの権限を確認し、
「実行権限」が付与されていない場合は付与しておく。
所有者(ユーザー)に実行権限(x)を持たせる。
⑥cronに自動実行を行う処理を記載する
最後にcronに実行したい日時とファイルを記載します。
crontabファイルの中は、
「分 時 日 月 曜日 実行したいこと」
を記載します。
今回の場合は「毎月1日22:00にinsert_deleted_user.shファイルを実行する」ということになります。
以上となります。
1つパスが間違っていたり、1つプロジェクト内でエラーが出るともちろん自動実行はされません。
実行されないときは、「Javaプロジェクト内のエラー」なのか
「シェルスクリプトファイル内のパスの記載ミス」なのか
「crontabのパスや時間設定にミスがないか」なのかを段階ごとに確認すると発見できました。
特に「Javaプロジェクト内のエラー」はSTSやEclipse上の実行ではエラーを吐かなかったのに、
ターミナルでJavaプロジェクトを実行するとエラーを吐くなどが結構あったので、
一度コマンドでの実行でエラーが出ないか確認した方がいいなと思いました。
もっとスマートな方法もあるのかもしれませんが、発見したらまた別記事でまとめたいと思います。