- PR -

JAVAの二重起動防止は可能?

投稿者投稿内容
narucissus
会議室デビュー日: 2003/07/25
投稿数: 11
投稿日時: 2003-07-25 02:14
はじめまして。いつも記事を読ませていただいています。
今回は今作ろうと思っているプログラムで困ったことがあるので、
質問する立場で参加させていただきたいと思います。

JAVAでサーバ/クライアントモデルを使用したプログラムを作成してるのですが、
クライアント側のプログラムを二重起動させたくありません。
Pure Javaで二重起動を防止するようなことは可能なのでしょうか?
知っていらっしゃる方がいましたらご教授ください。

#自分で調べてみたところどうも無理っぽいのでJNIを使用しようかと思っているところです。
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2003-07-25 07:47
特定のポート番号を指定してjava.net.ServerSocketを作成します。
既に別なプログラムがそのポート番号を使用していた場合
java.net.BindExceptionが発生することを利用して2重起動防止が
実現できます。

コード:
import java.net.ServerSocket;
import java.net.BindException;

public class SingleProcess{
    public static void main(String[] args) {
        if (!isOnlyMe()) {
            System.err.println("既に起動されています");
            System.exit(-1);
        }
        System.out.println("単独起動されました");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // do nothing
        }
    }

    public static boolean isOnlyMe() {
        try {
            ServerSocket sock = new ServerSocket(PORT);
        } catch (BindException e) {
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    private static int PORT = 3776;
}


まりり
ぬし
会議室デビュー日: 2001/12/05
投稿数: 329
投稿日時: 2003-07-25 09:05
ロックファイル作っておくとかってのでも実現できるんじゃないでしょうか?

起動時にファイルをチェックして、あれば終了。
なければファイルを作って普通に起動。
終了時にはファイルを削除。
おっきー
大ベテラン
会議室デビュー日: 2003/05/01
投稿数: 104
投稿日時: 2003-07-25 11:11
ちょっとしたことですが、注意しないといけない点がありますね。

ネットワークを使う場合、パーソナルファイアウォールで通信を遮断されないようにする
ロックファイルを使う場合、異常終了してしまったら手動でファイルを削除しないといけない。
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-07-25 12:48
こんにちは。

どういった方法で起動させているのかはわかりませんが、
たとえば、batやショートカットやVBScriptでjavaアプリを起動しているなら、
目的のjavaアプリを起動する前に、Javaアプリが実行されているかをチェックする
exeをVCやVBなんかで作って、そのチェック結果の戻り値でjavaアプリを起動するか
をbatやVBScriptに書いてやるという方法もあると思います。
起動そのものもVCやVBの中でやってもいいと思います。

これなら起動用アプリと本来のアプリを切り分けられ、既存のJavaアプリを一切修正
する必要も無く、起動部分は好きな開発環境でできるし、開発もデバッグも楽です。

ユーザが直接Javaアプリを実行してしまえばそれまでで、シビアな二重起動チェック
はできませんが、緩やかな二重起動チェックで運用上問題なければこれでもいいかと
思います。

プラットフォームが変わっても、その起動部分のみそのプラットフォームにあった方法
に変更すればいいので。

私は、テクニックを駆使しした割に、それが原因でトラブルとちとしんどいので、こう
いう方法をよく使ってます。

<追記>
目的のJavaアプリのクラスが起動しているかを windowsのapiからチェックできるかは
わかりません。

[ メッセージ編集済み 編集者: maru 編集日時 2003-07-25 12:55 ]
narucissus
会議室デビュー日: 2003/07/25
投稿数: 11
投稿日時: 2003-07-25 17:43
たくさんの返答ありがとうございます。

ロックファイルも考えてみたのですが、ご指摘あったとおり異常終了した場合に
ロックファイルの削除をユーザにさせなければいけないという点で
あまり気が進みませんでした。

起動の方法については特に決めていなかったのですが、maruさんのおっしゃるとおり
プラットホームによって起動用のbatファイルやshファイルを用意するのは一般的になっていることですし、その方法がベストのように感じられます。
運用上特に問題はなさそうなので、あとはメンバーと話し合ってネットワークを使うかbatファイルなどを使うか決定しようと思います。


大変参考になる意見ありがとうございました。
sumin
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 93
投稿日時: 2003-07-25 19:07
スミンです。

やって見てはないので確信はないですが、ふと思うにはアプリの起動の際にJAVAのSystemクラスにsetProperty()メソッドで何かキーを設定して置くのは如何でしょうか?で、アプリが起動する時先ずSystem.getProperty(キー)でそのキーがあるかどうかを判断して起動を続けるか止めるかを決めさせればどうでしょうか?勿論、アプリの終了時とクラッシュの時にはそのキーを削除する必要がありますが。。

ご意見お願いします。
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2003-07-25 22:34
引用:

suminさんの書き込み (2003-07-25 19:07) より:
やって見てはないので確信はないですが、ふと思うにはアプリの起動の際にJAVAのSystemクラスにsetProperty()メソッドで何かキーを設定して置くのは如何でしょうか?


Propertyは永続化しないかと思います。でもこの発言で思い出しましたが
JDK1.4を使用するのであれば、Preference APIを使うと簡単に実現できそうです。

下記URLが参考になると思います。
http://www-6.ibm.com/jp/developerworks/java/020215/j_j-mer1002.html

スキルアップ/キャリアアップ(JOB@IT)