SwingでスタンドアロンのJavaプログラムを作成しています。
Executable JARファイルとして、ダブルクリックにより起動するのですが、一度起動した後もう一度ダブルクリックすると同じプログラムが別に起動してしまいます。
JDK1.5、OSはWindowsが対象です。
複数起動できないようにする方法はありますでしょうか?
よろしくお願いします。
※ファイルに起動フラグを書出すという方法は考えてみましたが、クラッシュ(異常終了)したときに起動不可能になるためこの方法は使用できませんでした。
No.2ベストアンサー
- 回答日時:
私が思いつく一般的と思われる方法は2つあります。
(1)WindowsのMutexを利用する方法
WinAPIのCreateMutex()を利用し、適当な名前のMutexを作成します。
Mutex作成の成功・失敗でプログラムの二重起動を判定します。
Windowsでは一般的な方法ですので情報は手に入れやすいと思います。
ただし、Java以外の言語でプログラムを書く必要があります。
(2)ファイルチャネルのロックを利用する方法
あくまでJavaのみでということでしたら、ファイルチャネルのロックを利用する方法があります。
説明しにくいのでサンプルコードを書きます。(あくまでサンプルなので、実際に使う場合はよくテストしてください。)
仮にVMが異常終了した場合でもロックはおそらく開放されます。(Windowsがプロセスの終了を検知するため)
万が一開放されなかった場合でも、Windowsの再起動で開放されます。
--------------------------------------------------------------------------------
import java.io.File;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class Sample {
public static void main(String[] args) {
//起動チェック
final FileOutputStream fos = new FileOutputStream(new File("lock"));
final FileChannel fc = fos.getChannel();
final FileLock lock = fc.tryLock();
if (lock == null) {
//既に起動されているので終了する
return;
}
//ロック開放処理を登録
Runtime.getRuntime().addShutdownHook(
new Thread() {
public void run() {
if (lock != null && lock.isValid()) {
lock.release();
}
fc.close();
fos.close();
}
}
);
//処理を続行
}
}
--------------------------------------------------------------------------------
それから、#1さんのソケットを使う方法には以下の問題点があります。
・メッセージの送受信(起動チェック)とリスン開始(ロック)の処理が分離されている (タイミング次第で多重起動可能)
・起動されていない場合(正常系)と何らかのエラーで返信が返ってこない場合(異常系)の区別ができない
・返信が無いというのはタイムアウトになるということであり、起動時間が多少長くなる
個人用のツールならともかく、業務システムに使用するのはお勧めできません。
#念の為に書いておきますが、回答を批判しているわけではありません。
ご回答ありがとうございます。
今回は、「(2)ファイルチャネルのロックを利用する方法」を使わせていただきます。
java.util.logging.Loggerを使っていて、ファイルのロックの例はすぐ目の前にあったのですが、重複起動チェックに使用することまでは気付きませんでした。
タスクマネージャーでJavaプログラム起動中にjavaw.exeプロセスを終了する確認などもしてみました。
今のところ、この方法で特に問題はなさそうです。
非常に助かりました。ありがとうございました。
No.1
- 回答日時:
>※ファイルに起動フラグを書出すという方法は考えてみましたが、
>クラッシュ(異常終了)したときに起動不可能になるためこの方法は使用
>できませんでした。
ならば、ソケット通信を使って、二重起動を監視してみてはいかがでしょうか?
アプリケーション起動時にソケット通信を使って、他のアプリケーションへ
メッセージを送信する。送信メッセージに対する返信がなければ、自分しか
起動されていないのでOK。返信があればNG。
自分しか起動されていないことがわかったら、次に、他のアプリケーションが
二重起動されるのを防ぐために、決められたポート番号でリスンする。
このポート番号に他のアプリケーションからメッセージが送信されてきた場合は、
既に起動済みである旨のメッセージを返す。
ただし、気をつけなければならないのは、決められたポートでリスンする処理は、
アプリのメインスレッドとは別のスレッドで行う必要があるということです。
ご回答ありがとうございます。
今回はNo.2にgimmickさんから頂いた回答の「(2)ファイルチャネルのロックを利用する方法」を使うことにしました。
ソケット通信を使うことまでは気付きませんでした。
将来、別の機会に使うこともあるかもしれないので、動作確認のために実装を試みてみました。
その結果分かったことは、リスンのためにServerSocketでポートを開こうとすると、WindowsXP SP2の「Windowsファイアウォール」でブロックされてしまう場合もありそうです。
※もしかしたらローカルホストに限定すればブロックされないのかもしれませんが、まだ深くは追求していません。
おかげ様で、問題解決方法の視野を広げることができました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Windows 7 Media Playerが開かない。ファイルアイコンを右クリックしても「プロパティ」が表示されない。 2 2023/02/05 14:45
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- Windows 10 Windows10起動しない、エラー0xc0000185修復方法 2 2022/07/14 12:28
- デスクトップパソコン 「自動修復でPCを修復できませんでした」と表示されPCが起動しないのですが対処法はありますか? 5 2022/05/13 09:16
- その他(Microsoft Office) office2010とoffice365の共存でoffice365を優先で起草させたい 3 2023/01/24 10:47
- Java jdk17.06のインストーラーが起動しない 1 2023/03/27 21:58
- Windows 10 Windows10環境にてWindowsUpdate後の再起動を完全に抑止する方法はございますか? 10 2023/06/16 09:57
- Windows 10 windows 制限解除のやり方教えて 3 2023/01/02 22:46
- ノートパソコン Windows 10 動作改善方法 6 2023/04/26 22:30
- ノートパソコン .dllファイルがありませんと表示される 5 2023/04/30 03:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Eclipse開発時workディレクトリ...
-
jspで無限ループ
-
アプレットからサーバ側のプロ...
-
JBOSS+TOMCAT起動時のエラー
-
html上で、バッチやexeファイル...
-
Eclipseで、プロジェクト名のと...
-
マイクラjavaでForgeを入れたい...
-
Eclipseのアンインストールの仕方
-
サーブレットでhtml,cssや画像...
-
CloudSticky.jarが起動しない。
-
eclipseのjavaを実行できない
-
NET Framework 4 v4.0.30319 ダ...
-
Javaでping
-
「削除するか、クラスパスの正...
-
tomcatの不具合
-
split関数で区切り文字がない場合
-
classファイルについて
-
servletのコンパイルエラーにつ...
-
jspのファイルでエラーが出る
-
別のAccessファイルのフォーム...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
javaが起動しない
-
apache+tomcatの起動手順
-
Tomcatは起動しますが初期index...
-
The requested resource is no...
-
EclipseからTomcatを起動できない
-
スタンドアロンJavaプログラム(...
-
リモートからTomcatにアクセス...
-
Tomcatプロジェクトの.properti...
-
tomcatの再起動とApacheの設定...
-
Eclipse + JBOSS でのデバッグ
-
tomcatをプロジェクト毎に起動...
-
「ファイルが見つかりません D...
-
javaサーブレットから別サーバ...
-
tomcatをサービスで登録すると...
-
GRAPHS32.OCX
-
GCログに日付時刻を表示したい
-
Tomcatが起動しません。調べて...
-
apache + tomcat でtomcatが起...
-
Visual C++を複数開くには?
-
IISとXAMPPのApacheの環境設定
おすすめ情報