JShell.java



/** 他のクラスをロードして実行するクラス */
import java.lang.reflect.*;
import java.io.*;
import java.util.*;
public class JShell {

  /** サブプロセスを呼び出す処理のループ */
    public void loop() {
        while( true ) {
           System.out.print(">> "); // プロンプトの表示
           try{
               String args[] = readCommandLine();
               SubProcess sp = new SubProcess( args );
               sp.start();
               while( sp.isAlive() ){
                  Thread.yield();  // サブプロセスの終了まで休む
               }
           }
           catch( Exception e ) {
               System.err.println("Error:" + e.getMessage() );
           }
        }
    }

  /** コマンド行をトークンに分解して解釈するメソッド */
    public String[] readCommandLine() {
        try{
            BufferedReader input
               = new BufferedReader(
                    new InputStreamReader( System.in ) );
            String line = input.readLine();
            StringTokenizer st = new StringTokenizer(line);
            ArrayList list = new ArrayList();
            while( st.hasMoreTokens() )
               list.add( st.nextToken() );
            return (String[])list.toArray(
                               new String[list.size()] );
        }
        catch( Exception e ) {
            System.err.println("Error:" + e.getMessage() );
            return null;
        }
    }

  /** 最初に呼び出されるメソッド */
    public static void main( String argv[] ) {
        JShell shell = new JShell();
        shell.loop();
    }
}

/** 独立したスレッドで他のクラスの処理を実行するクラス */
import java.lang.reflect.*;
class SubProcess extends Thread {

  /** ロードするクラスの名前 */
    public String className;

  /** コマンドラインの引数 */
    public String argv[];

  /** コンストラクタ */
    SubProcess( String args[] ) {
        className = args[0];
        argv = new String[args.length-1];
        for( int i=0; i<args.length-1; i++ )
            argv[i] = args[i+1];
    }

  /** 独立したスレッドで実行する処理の内容 */
    public void run(){
        try {
             Class cls = Class.forName( className );
             Method method = getMainMethod( cls );
             Object args[] = new Object[1];
             args[0] = argv;
             if( method != null )
                 method.invoke( null, args );
        }
        catch( Exception e ) {
             System.err.println("Error:" + e.getMessage() );
        }
    }

  /** 指定されたクラスから main()メソッドを捜すメソッド */
    public Method getMainMethod( Class cls ) {
        Method[] methods = cls.getMethods();
        for( int i=0; i<methods.length; i++ ) {
            if( !methods[i].getName().equals( "main" ) ) continue;
            int modifiers = methods[i].getModifiers();
            if( !Modifier.isStatic( modifiers ) ) continue;
            Class type = methods[i].getReturnType();
            if( !type.equals(void.class) ) continue;
            Class[] prms = methods[i].getParameterTypes();
            if( prms.length != 1 ) continue;
            if( !prms[0].getName().equals("[Ljava.lang.String;") ) continue;
            return methods[i];
        }
        return null;
    }
}