From cbcc04c1fb17d87f97d55862fc3d7ac959ed76ae Mon Sep 17 00:00:00 2001 From: hns Date: Tue, 17 Oct 2006 11:44:51 +0000 Subject: [PATCH] * Set/Get current RequestEvaluator explicitly via ThreadLocal * Prevent NullpointerException when scripting engine is initialized from non-request-evaluator thread (merge from helma_1_5 branch) --- src/helma/framework/core/Application.java | 22 +++++++++---------- src/helma/framework/core/Prototype.java | 3 ++- .../framework/core/RequestEvaluator.java | 7 ++++++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/helma/framework/core/Application.java b/src/helma/framework/core/Application.java index 915cf859..9880b61d 100644 --- a/src/helma/framework/core/Application.java +++ b/src/helma/framework/core/Application.java @@ -102,6 +102,9 @@ public final class Application implements IPathElement, Runnable { long requestTimeout = 60000; ThreadGroup threadgroup; + // threadlocal variable for the current RequestEvaluator + ThreadLocal currentEvaluator = new ThreadLocal(); + // Map of requesttrans -> active requestevaluators Hashtable activeRequests; @@ -1192,18 +1195,15 @@ public final class Application implements IPathElement, Runnable { * @return the RequestEvaluator belonging to the current thread */ public RequestEvaluator getCurrentRequestEvaluator() { - Thread thread = Thread.currentThread(); - int l = allThreads.size(); + return (RequestEvaluator) currentEvaluator.get(); + } - for (int i = 0; i < l; i++) { - RequestEvaluator r = (RequestEvaluator) allThreads.get(i); - - if ((r != null) && (r.getThread() == thread)) { - return r; - } - } - - return null; + /** + * Set the current RequestEvaluator for the calling thread. + * @param eval the RequestEvaluator belonging to the current thread + */ + protected void setCurrentRequestEvaluator(RequestEvaluator eval) { + currentEvaluator.set(eval); } /** diff --git a/src/helma/framework/core/Prototype.java b/src/helma/framework/core/Prototype.java index 517ef2a7..0c5a3a09 100644 --- a/src/helma/framework/core/Prototype.java +++ b/src/helma/framework/core/Prototype.java @@ -122,9 +122,10 @@ public final class Prototype { props.addResource(repository.getResource("type.properties")); if (update) { RequestEvaluator eval = app.getCurrentRequestEvaluator(); + ScriptingEngine engine = eval == null ? null : eval.scriptingEngine; Iterator it = repository.getAllResources().iterator(); while (it.hasNext()) { - checkResource((Resource) it.next(), eval.scriptingEngine); + checkResource((Resource) it.next(), engine); } } } diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index a4094672..5d462a89 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -79,6 +79,7 @@ public final class RequestEvaluator implements Runnable { /** * Create a new RequestEvaluator for this application. + * @param app the application */ public RequestEvaluator(Application app) { this.app = app; @@ -89,6 +90,7 @@ public final class RequestEvaluator implements Runnable { String engineClassName = app.getProperty("scriptingEngine", "helma.scripting.rhino.RhinoEngine"); try { + app.setCurrentRequestEvaluator(this); Class clazz = app.getClassLoader().loadClass(engineClassName); scriptingEngine = (ScriptingEngine) clazz.newInstance(); @@ -112,6 +114,8 @@ public final class RequestEvaluator implements Runnable { } else { throw new RuntimeException(t.toString()); } + } finally { + app.setCurrentRequestEvaluator(null); } } } @@ -151,6 +155,7 @@ public final class RequestEvaluator implements Runnable { // initialize scripting engine initScriptingEngine(); + app.setCurrentRequestEvaluator(this); // update scripting prototypes scriptingEngine.updatePrototypes(); @@ -559,6 +564,8 @@ public final class RequestEvaluator implements Runnable { res.reportError(app.getName(), error); done = true; } + } finally { + app.setCurrentRequestEvaluator(null); } }