基本的なアプローチは次のとおりです。
- クラスローダーを作成し、
- マニフェストを読んでエントリ ポイント クラスを見つける
- エントリ ポイント クラスをロードし、
- リフレクションを使用してその
public static void main(String[])
メソッドを取得し、
main
コマンドのコマンドライン引数を渡して、新しいスレッドからメソッドを呼び出します。
この特定のケースの問題は、System.in および System.out ストリームをセットアップして、同じ JVM で実行されている「子アプリケーション」と通信できるようにすることです。問題は、「子アプリケーション」が、System.out が出力先のストリームであり、「親アプリケーション」が読み取るストリームであると想定していることです。しかし、「親アプリケーション」は、System.out がコンソール (または何でも) の出力ストリームであると想定しています。System.in/out/err は、両方の「アプリケーション」に対して必然的に同じ値を持つクラス フィールドであるため、これは機能しません。
解決策は、親アプリケーション クラスのコードを変更して System.in/out/err フィールドを使用しないようにすることです。「親」main
が子のメソッドを呼び出す前に、それを使用System.setOut(...)
して、バッファに書き込むカスタム出力ストリーム インスタンスに設定する必要があります。次に、コード内の代わりに、「親」が読み取ることができる一致する入力ストリーム インスタンスが必要bis
です。
もう 1 つ対処する必要があるのは、「子」アプリケーションが を呼び出す可能性ですSystem.exit()
。これは、親のプラグを抜くという不幸な結果をもたらします。
また、「子」によって作成されたスレッドやその他のもののクリーンアップなど、他のあらゆる種類の複雑さがあります。JVMがIsolates JSRを実装しない限り、これらのいくつかは基本的に解決できません(主流のJVMはそうではありません、AFAIK)。
要するに、一般的なケースでこれを行うのは非常に難しく、完全に正しくできないことがいくつかあります。これらの問題を排除/回避できない限り、代替のエントリポイントと代替の通信方法を実装する方がはるかに簡単です。