java scripting API - how to stop the evaluation

后端 未结 7 1623
孤城傲影
孤城傲影 2020-12-09 06:10

i have writen a servlet that recives a java script code and process it and returns the answer. for that i have used the java scripting API

in the code below if scrip

相关标签:
7条回答
  • 2020-12-09 07:14

    Here's some code showing the Future implementation and the Thread.stop() one. This is an interesting problem, and it points out the need for a hook in a ScriptEngine to be able to halt whatever script it's running for whatever reason. I wonder whether this would break the assumptions in most implementations since they assume eval() will be executed in a single-threaded (blocking) environment?

    Anyway, the results of executing the code below:

    // exec with Thread.stop()
    $ java ExecJavascript 
    Java: Starting thread...
    JS: Before infinite loop...
    Java: ...thread started
    Java: Thread alive after timeout, stopping...
    Java: ...thread stopped
    (program exits)
    
    // exec with Future.cancel()
    $ java ExecJavascript 1
    Java: Submitting script eval to thread pool...
    Java: ...submitted.
    JS: Before infinite loop...
    Java: Timeout! trying to future.cancel()...
    Java: ...future.cancel() executed
    (program hangs)
    

    Here's the full program:

    import java.util.concurrent.*;
    import javax.script.*;
    
    public class ExecJavascript
    {
    private static final int TIMEOUT_SEC = 5;
    public static void main( final String ... args ) throws Exception 
    {
        final ScriptEngine engine = new ScriptEngineManager()
            .getEngineByName("JavaScript");
        final String script = 
            "var out = java.lang.System.out;\n" +
            "out.println( 'JS: Before infinite loop...' );\n" +
            "while( true ) {}\n" +
            "out.println( 'JS: After infinite loop...' );\n";
        if ( args.length == 0 ) {
            execWithThread( engine, script );
        }
        else {
            execWithFuture( engine, script );
        }
    }
    
    private static void execWithThread( 
        final ScriptEngine engine, final String script )
    {
        final Runnable r = new Runnable() {
            public void run() {
                try {
                    engine.eval( script );
                }
                catch ( ScriptException e ) {
                    System.out.println( 
                        "Java: Caught exception from eval(): " + e.getMessage() );
                }
            }
        };
        System.out.println( "Java: Starting thread..." );
        final Thread t = new Thread( r );
        t.start();
        System.out.println( "Java: ...thread started" );
        try {
            Thread.currentThread().sleep( TIMEOUT_SEC * 1000 );
            if ( t.isAlive() ) {
                System.out.println( "Java: Thread alive after timeout, stopping..." );
                t.stop();
                System.out.println( "Java: ...thread stopped" );
            }
            else {
                System.out.println( "Java: Thread not alive after timeout." );
            }
        }
        catch ( InterruptedException e ) {
            System.out.println( "Interrupted while waiting for timeout to elapse." );
        }
    }
    
    private static void execWithFuture( final ScriptEngine engine, final String script )
        throws Exception
    {
        final Callable<Object> c = new Callable<Object>() {
            public Object call() throws Exception {
                return engine.eval( script );
            }
        };
        System.out.println( "Java: Submitting script eval to thread pool..." );
        final Future<Object> f = Executors.newCachedThreadPool().submit( c );
        System.out.println( "Java: ...submitted." );
        try {
            final Object result = f.get( TIMEOUT_SEC, TimeUnit.SECONDS );
        }
        catch ( InterruptedException e ) {
            System.out.println( "Java: Interrupted while waiting for script..." );
        }
        catch ( ExecutionException e ) {
            System.out.println( "Java: Script threw exception: " + e.getMessage() );
        }
        catch ( TimeoutException e ) {
            System.out.println( "Java: Timeout! trying to future.cancel()..." );
            f.cancel( true );
            System.out.println( "Java: ...future.cancel() executed" );
        }
    } 
    }
    
    0 讨论(0)
提交回复
热议问题