JVM の終了

やっと見つけました。

どうも探し方が悪かったようで、妙に時間がかかってしまいました。

というのも、IVMRunner などのインタフェースの Javadoc ばかり見ていたからなのです。いいわけですけど ^^;;

まさか、インプリメントしたクラスに定義されているとは思いもしませんでした。結局、Launch クラスに目的とするメソッド terminate がありました。でも、普通は ILaunch インタフェースを調べますよねぇ。

terminate と対になるメソッドとして isTerminated メソッドも定義されています。

これらのメソッドを使用して、LG3DLauncher クラスに terminate メソッドを定義しました。今までは Launch オブジェクトはテンポラリ変数として扱っていたのですが、それだと困ってしまうのでフィールドとして定義してあります。

    public void terminate() throws CoreException {
        System.out.println(launch + " " + launch.isTerminated());
        if (launch != null && !launch.isTerminated()) {
            launch.terminate();
        }
    }

StopActionDelegate クラスの run メソッドからはこの terminate メソッドをコールするようにしてあります。

これで実行してみましたが... NullPointerException が発生。

よく考えてみたら、WrpePlugin クラスでは、毎回 LG3DLauncher オブジェクトを生成するように記述してあったのでした。

そこで、WrpeLauncher オブジェクトが Singleton として使用されるのを利用して、LG3DLauncher オブジェクトは WrpeLauncher のフィールドとし、唯一のオブジェクトであるようにしました。

    public LG3DLauncher getLG3DLauncher() {
        if (launcher == null) {
            launcher = new LG3DLauncher();
        }
    
        return launcher;
    }

このままだと、LG3D を起動するときに現在の状態を調べて、LG3D を実行中であれば、false を戻すようにしました。

    public boolean launch() throws CoreException {
        if (launch != null && !launch.isTerminated()) {
            return false;
        } else {
            IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall();
            IVMRunner vmRunner = vmInstall.getVMRunner(ILaunchManager.RUN_MODE);
        
            ILaunchConfigurationWorkingCopy config = createConfig(vmInstall, true);
        
            launch = new Launch(config, ILaunchManager.RUN_MODE, null);

            VMRunnerConfiguration vmConfig = new VMRunnerConfiguration(classToLaunch, classpath);
            ExecutionArguments executionArguments = new ExecutionArguments(vmArgs, prgArgs);
            vmConfig.setVMArguments(executionArguments.getVMArgumentsArray());
            vmConfig.setProgramArguments(executionArguments.getProgramArgumentsArray());
            vmConfig.setBootClassPath(null);   

            vmRunner.run(vmConfig, launch, null);
            return true;
        }
    }

そして、Action クラスの方でダイアログを出すようにしてあります。

    public void run(IAction action) {
	    WrpePlugin.log("StartAction.run");
        try {   
            if (!WrpePlugin.getDefault().getLG3DLauncher().launch()) {
                MessageDialog.openInformation(
                        window.getShell(),
                        "LG3D WRPE Plug-in",
                        "LG3D is runnnig! You can execute only one LG3D.");
            }
        } catch (Exception ex) {
            WrpePlugin.log(ex);
            MessageDialog.openInformation(
                    window.getShell(),
                    "LG3D WRPE Plug-in",
                    "Execution Error Occurred. See Log.");
        }
    }

これで無事に JVM を終了させることができました。