Details
-
Task
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.0
-
None
Description
After runnning Jexl tests I have noticed that the thread from testCancelForever() test is still executing, and its stack trace is as follows:
org.apache.commons.jexl3.ScriptCallableTest$TestContext.runForever(ScriptCallableTest.java:159) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:606) org.apache.commons.jexl3.internal.introspection.MethodExecutor.invoke(MethodExecutor.java:93) org.apache.commons.jexl3.internal.Interpreter.call(Interpreter.java:1816) org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1535) org.apache.commons.jexl3.parser.ASTFunctionNode.jjtAccept(ASTFunctionNode.java:18) org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1119) org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:55) org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:210) org.apache.commons.jexl3.internal.Script$Callable.interpret(Script.java:364) org.apache.commons.jexl3.internal.Script$Callable.call(Script.java:372) - locked org.apache.commons.jexl3.internal.Script$Callable@35595365 java.util.concurrent.FutureTask.run(FutureTask.java:262) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) java.lang.Thread.run(Thread.java:745)
may be its worth rewriting the test to something like this
public static class TestContext extends MapContext implements JexlContext.NamespaceResolver { protected volatile boolean x = false; public int runForever() { while (true) { if (x) { break; } } return 1; } ... @Test public void testCancelForever() throws Exception { JexlScript e = JEXL.createScript("runForever()"); TestContext tctx = new TestContext(); Callable<Object> c = e.callable(tctx); ExecutorService executor = Executors.newFixedThreadPool(1); Future<?> future = executor.submit(c); Object t = 42; try { t = future.get(100, TimeUnit.MILLISECONDS); Assert.fail("should have timed out"); } catch (TimeoutException xtimeout) { // ok, ignore future.cancel(true); tctx.x = true; } finally { executor.shutdown(); }