Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>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 <code>eval()</code> will be executed in a single-threaded (blocking) environment?</p> <p>Anyway, the results of executing the code below:</p> <pre><code>// 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) </code></pre> <p>Here's the full program:</p> <pre><code>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&lt;Object&gt; c = new Callable&lt;Object&gt;() { public Object call() throws Exception { return engine.eval( script ); } }; System.out.println( "Java: Submitting script eval to thread pool..." ); final Future&lt;Object&gt; 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" ); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload