Запустите оценку в отдельном потоке и прервите его через 15 секунд, используя Thread.interrupt (). Это остановит eval и создаст исключение InterruptedException, которое вы можете перехватить и вернуть статус ошибки.
Лучшим решением было бы иметь какой-то асинхронный интерфейс для механизма сценариев, но, насколько я мог видеть, этого не существует.
EDIT:
Как указывал sfussenegger, прерывание не работает с обработчиком сценариев, поскольку оно никогда не спит или не переходит в какое-либо состояние ожидания для прерывания. Я не мог бы найти какой-либо периодический обратный вызов в объектах ScriptContext или Bindings, который можно было бы использовать в качестве ловушки для проверки прерываний. Однако есть один метод, который работает: Thread.stop (). Это устарело и небезопасно по ряду причин, но для полноты я опубликую здесь свой тестовый код вместе с реализацией Криса Уинтерса для сравнения. Время ожидания версии Криса истечет, но фоновый поток будет запущен, interrupt () ничего не сделает, а stop () убьет поток и возобновит управление основным потоком:
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();
}
}