3回に渡ってProject Kullaで提供しているJShellの使い方について紹介してきました。今回は、ちょっと趣向を変えて、JShellが提供しているAPI、JShell APIについて解説します。
JShell APIを使えば、アプリケーションにJShellの機能を取り入れることができます。JShell APIを使用するには、JShellの動作モデルの理解が必要です。そこで、JShell APIを紹介する前に、JShellがどのように動いているのかについて解説します。
JShellの動作
JShellは意外に内部では複雑なことを行っています。試しに、JShellを起動してから、OSで実行しているプロセスを見てみましょう。JShellが実行されているのはもちろんですが、それ以外にjavaが動いていることが分かるはずです。
実をいうと、JShellはJavaのスニペットを実行するために、もう1つのJVMを使用します。そのため、JShell以外に、javaが起動しているのです。JShell動作時の構成を図1に示しました。

前述したように、JShellは2つのプロセスから構成されます。JShellはターミナルの制御に、OSSのjlineライブラリーを使用しています。JShellはjlineを利用して、カーソルの位置制御や補完機能を実現しています。
jlineからスニペットを受け取るのがJShellToolクラスです。スニペットの評価、実行の中心となるのがJSehll APIです。JShell APIはJShellToolクラスから受け取ったスニペットをまず解釈します。そして、スニペットを実行できるように、スニペットをラップしたクラスを作成します。
作成したクラスをコンパイルするのがCompiler APIです。Compiler APIはJava SE 6で導入された、クラスを動的にコンパイルするためのAPIです。詳しくは、「Java SE 6完全攻略」第89回 プログラムからコンパイル - Compiler API その1をご参照ください。
JShell APIはコンパイルされたバイトコードを、もう一方のjavaプロセスにロード、実行を委譲します。このときに、JVMの制御が必要になるのですが、これを行うためにJDI(Java Debugger Interface)を使用してJVMにアクセスします。
JDIはデバッガのためのインタフェースなので、JVMの制御はお手のものです。JShell APIはラップしたクラスを実行した結果を受け取るだけでなく、標準出力や標準エラー出力への出力も受け取ります。それらを合わせて、JShellToolクラスに戻し、jlineを使用して表示します。
このようにして、JShellはスニペットの入力から結果の表示までを行っているのです。