java scripting API - how to stop the evaluation

后端 未结 7 1659
孤城傲影
孤城傲影 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:01

    Run the evaluation in a separate thread and interrupt it after 15s using Thread.interrupt(). This will stop the eval and throw an InterruptedException, which you can catch and return a failure status.

    A better solution would be to have some sort of asynch interface to the scripting engine, but as far as I could see this does not exist.

    EDIT:

    As sfussenegger pointed out, interrupting does not work with the script engine, since it never sleeps or enters any wait state to get interrupted. Niether could I find any periodical callback in the ScriptContext or Bindings objects which could be used as a hook to check for interruptions. There is one method which does work, though : Thread.stop(). It is deprecated and inherently unsafe for a number of reasons, but for completeness I will post my test code here along with Chris Winters implementation for comparison. Chris's version will timeout but leave the background thread running, the interrupt() does nothing and the stop() kills the thread and resumes control to the main thread:

    import javax.script.*;
    import java.util.concurrent.*;
    
    class ScriptRunner implements Runnable {
    
        private String script;
        public ScriptRunner(String script) {
                this.script = script;
        }
    
        public ScriptRunner() {
                this("while(true);");
        }
    
        public void run() {
                try {
                // create a script engine manager
                ScriptEngineManager factory = new ScriptEngineManager();
                // create a JavaScript engine
                ScriptEngine engine = factory.getEngineByName("JavaScript");
                // evaluate JavaScript code from String
                System.out.println("running script :'" + script + "'");
                engine.eval(script);
                System.out.println("stopped running script");
                } catch(ScriptException se) {
                        System.out.println("caught exception");
                        throw new RuntimeException(se);
                }
                System.out.println("exiting run");
        }
    }
    
    public class Inter {
    
        public void run() {
                try {
                 Executors.newCachedThreadPool().submit(new ScriptRunner()).get(15, TimeUnit.SECONDS);
                } catch(Exception e) {
                        throw new RuntimeException(e);
                }
        }
    
        public void run2() {
                try {
                Thread t = new Thread(new ScriptRunner());
                t.start();
                Thread.sleep(1000);
                System.out.println("interrupting");
                t.interrupt();
                Thread.sleep(5000);
                System.out.println("stopping");
                t.stop();
                } catch(InterruptedException ie) {
                        throw new RuntimeException(ie);
                }
        }
    
        public static void main(String[] args) {
                new Inter().run();
        }
    }
    

提交回复
热议问题