- PR -

SwingによるGUIライブラリを呼び出し後のSystem.exit()

投稿者投稿内容
未記入
会議室デビュー日: 2005/02/08
投稿数: 9
投稿日時: 2005-08-23 20:48
こんばんは。
Win2K、JRE1.5あたり(曖昧ですみません)の環境を想定しています。
よろしくお願いします。

Dos上で動作するプログラムが、Swingで作られたGUIを持つライブラリをCall
した場合、Dos上で動作するプログラムのmain()関数内で明示的にSystem.exit()を
Callする必要があるかを教えてください。

Dosプロンプト上で動作するJavaプログラムがライブラリをCallするとします。
Dos上で動作するほうはGUIは使用しません。
Callされるライブラリのメソッドはユーザ問い合わせ等のモーダルダイアログを表示します。
この場合、Dos上で動作するプログラムのmain()関数がいつまでも終了しません。
main()の最後に System.exit(0)を記述するとプログラムが終了します。
未記入
会議室デビュー日: 2005/02/08
投稿数: 9
投稿日時: 2005-08-23 20:53
すみません、分かりにくいですね^^;

自分としては、ライブラリが作成したダイアログに応答した後は、
Dos上のmain()関数に戻ってくるので、System.exit()をしなくても
プログラムが終了するはずだと考えてしまうのですが、
実際は終了しません。

通常Dos上で動作する単純なプログラムを記述した場合は
System.exit()を実行しなくてもプログラムは終了します。
GUIが絡む場合は、呼び出し側にてSystem.exit()しなくてはいけないのでしょうか?

よろしくお願いします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2005-08-23 22:33
unibon です。こんにちわ。

引用:

未記入さんの書き込み (2005-08-23 20:53) より:
自分としては、ライブラリが作成したダイアログに応答した後は、
Dos上のmain()関数に戻ってくるので、System.exit()をしなくても
プログラムが終了するはずだと考えてしまうのですが、
実際は終了しません。


理論上は exit は不要なはずです。しかし、Java の古いバージョン(1.4 未満位?)だと、終了しなかったので exit が必要だったと記憶しています。Sun の Bug Database にも載っていたと思います(何番だったか思い出せません)。
バージョンが新しい環境なら exit は不要だとは思いますが、アプリケーションプログラムがどのバージョンで動くか分からないし、プログラムが終了しないのはかなり致命的だと思いますので、exit するようにしておくほうが良いかもしれません。

#以下、あとで追加。

上記は、アプリケーションプログラムの側に問題がないという前提で書きましたが、プログラムが作ったスレッドや参照が残っていることが原因で終らないのならば、プログラムの側の問題ですから、それはプログラムの側のコーディングを直して解決する必要があります。

[ メッセージ編集済み 編集者: unibon 編集日時 2005-08-23 22:37 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-08-23 22:46
実際にやってみて、うまく終了しないのであればスレッドダンプをとってみましょう。
daemon スレッド以外のが残ってたらそれが終了しない原因です。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-08-24 12:15
AWTやSwingのライブラリをコール(コンポーネントインスタンスの生成とか)
すると、コールした時点でEventDispatchスレッドが作成されますよね。

コイツはユーザースレッド扱いですので、コイツを明示的に停止してやらな
い限り、JVMは停止しませんよ。
AWT・Swingライブラリの登場当初からそうだったような…

#AWT・Swingのような内部で知らず知らずのうちにユーザースレッドが作成さ
#れてしまうようなつくりより、SWTのようにイベントループスレッドの作成
#の責任を実装者側にとらせたほうがよかったんじゃないかと思う今日この頃です。
未記入
会議室デビュー日: 2005/02/08
投稿数: 9
投稿日時: 2005-08-24 13:07
unibonさん、インギさん、シュンさん、ご返答ありがとうございます。

シュンさんのおっしゃるとおりと考えます。
状況説明に漏れてしまったのですが、DosプロンプトからCallされるライブラリでは、
JOptionPaneを用いてユーザ問い合わせのダイアログを表示しています。

JOptionPaneは次のように使用しています。
第1引数の親ハンドルはCUIから呼ばれることもあり、nullを指定しています。

String val = JOptionPane.showInputDialog(
null , "値を入力してください");

現在、ライブラリのほうを修正する必要があることが見えてきました。
恐縮ですが、
> コイツはユーザースレッド扱いですので、コイツを明示的に停止してやらな
> い限り、JVMは停止しませんよ。
このユーザスレッドを停止するにはどうすればよいのでしょうか?

よろしくお願いします。
未記入
会議室デビュー日: 2005/02/08
投稿数: 9
投稿日時: 2005-08-24 15:52
JOptionPaneでは、dispose()が使用できないので、
dispose()が使えるクラスを継承して、
自前でダイアログクラスをつくるしかないでしょうか。

CUI的なプログラムで実行する場合、JOptionPaneは使っては
いけないことになりますかね。(というか親となるフレーム等が存在しない場合)
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-08-25 13:43
dispose()とイベントディスパッチスレッドは関係無いですよ。
イベントディスパッチスレッドを停止するにはSystem#exit()するのが良いです。

CUIでもなんでも、プロセスの終了タイミングってわかっているはずだと
思いますので、そこで呼べばよいのかとおもいますが、だめなんでしょうか?

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