You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2015/09/13 22:12:50 UTC
svn commit: r1702817 - in /jmeter/trunk: bin/jmeter.properties
src/core/org/apache/jmeter/control/IfController.java xdocs/changes.xml
Author: pmouawad
Date: Sun Sep 13 20:12:47 2015
New Revision: 1702817
URL: http://svn.apache.org/r1702817
Log:
Bug 58406 - IfController : Use Nashorn Engine if available for JavaScript evaluation
Bugzilla Id: 58406
Modified:
jmeter/trunk/bin/jmeter.properties
jmeter/trunk/src/core/org/apache/jmeter/control/IfController.java
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1702817&r1=1702816&r2=1702817&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Sun Sep 13 20:12:47 2015
@@ -1023,6 +1023,13 @@ beanshell.server.file=../extras/startup.
# Default is true. Use false to revert to previous behaviour
#CookieManager.check.cookies=true
+# Ability to revert to Rhino as default Javascript Engine used by IfController
+# JMeter works as following:
+# - JDK < 8 : Rhino
+# - JDK >= 8 : Nashorn
+# If you want to use Rhino on JDK8, set this property to true
+#ifcontroller.use_rhino=false
+
# (2.0.3) JMeterThread behaviour has been changed to set the started flag before
# the controllers are initialised. This is so controllers can access variables earlier.
# In case this causes problems, the previous behaviour can be restored by uncommenting
Modified: jmeter/trunk/src/core/org/apache/jmeter/control/IfController.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/control/IfController.java?rev=1702817&r1=1702816&r2=1702817&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/control/IfController.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/control/IfController.java Sun Sep 13 20:12:47 2015
@@ -20,8 +20,15 @@ package org.apache.jmeter.control;
import java.io.Serializable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleScriptContext;
+
import org.apache.jmeter.samplers.Sampler;
+import org.apache.jmeter.testelement.ThreadListener;
import org.apache.jmeter.testelement.property.StringProperty;
+import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.mozilla.javascript.Context;
@@ -53,18 +60,92 @@ import org.mozilla.javascript.Scriptable
// for unit test code @see TestIfController
-public class IfController extends GenericController implements Serializable {
+public class IfController extends GenericController implements Serializable, ThreadListener {
private static final Logger logger = LoggingManager.getLoggerForClass();
- private static final long serialVersionUID = 240L;
+ private static final long serialVersionUID = 241L;
private static final String CONDITION = "IfController.condition"; //$NON-NLS-1$
private static final String EVALUATE_ALL = "IfController.evaluateAll"; //$NON-NLS-1$
private static final String USE_EXPRESSION = "IfController.useExpression"; //$NON-NLS-1$
+
+ private static final String USE_RHINO_ENGINE_PROPERTY = "ifcontroller.use_rhino";
+
+ private static final boolean USE_RHINO_ENGINE =
+ getInstance().getEngineByName("nashorn") == null || //$NON-NLS-1$
+ JMeterUtils.getPropDefault(USE_RHINO_ENGINE_PROPERTY, false) ;
+
+ private static final ThreadLocal<ScriptEngine> NASHORN_ENGINE = new ThreadLocal<ScriptEngine>() {
+
+ /* (non-Javadoc)
+ * @see java.lang.ThreadLocal#initialValue()
+ */
+ @Override
+ protected ScriptEngine initialValue() {
+ return getInstance().getEngineByName("nashorn");//$NON-NLS-N$
+ }
+
+ };
+
+ private interface JsEvaluator {
+ boolean evaluate(String testElementName, String condition);
+ }
+
+ private static class RhinoJsEngine implements JsEvaluator {
+ @Override
+ public boolean evaluate(String testElementName, String condition) {
+ boolean result = false;
+ // now evaluate the condition using JavaScript
+ Context cx = Context.enter();
+ try {
+ Scriptable scope = cx.initStandardObjects(null);
+ Object cxResultObject = cx.evaluateString(scope, condition
+ /** * conditionString ** */
+ , "<cmd>", 1, null);
+ result = computeResultFromString(condition, Context.toString(cxResultObject));
+ } catch (Exception e) {
+ logger.error(testElementName+": error while processing "+ "[" + condition + "]\n", e);
+ } finally {
+ Context.exit();
+ }
+ return result;
+ }
+ }
+
+ private static class NashornJsEngine implements JsEvaluator {
+ @Override
+ public boolean evaluate(String testElementName, String condition) {
+ try {
+ ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(NASHORN_ENGINE.get().createBindings(), ScriptContext.ENGINE_SCOPE);
+ Object o = NASHORN_ENGINE.get().eval(condition, newContext);
+ return computeResultFromString(condition, o.toString());
+ } catch (Exception ex) {
+ logger.error(testElementName+": error while processing "+ "[" + condition + "]\n", ex);
+ }
+ return false;
+ }
+ }
+
+ private static JsEvaluator JAVASCRIPT_EVALUATOR = USE_RHINO_ENGINE ? new RhinoJsEngine() : new NashornJsEngine();
+
+ /**
+ * Initialization On Demand Holder pattern
+ */
+ private static class LazyHolder {
+ public static final ScriptEngineManager INSTANCE = new ScriptEngineManager();
+ }
+
+ /**
+ * @return ScriptEngineManager singleton
+ */
+ public static ScriptEngineManager getInstance() {
+ return LazyHolder.INSTANCE;
+ }
/**
* constructor
*/
@@ -101,38 +182,37 @@ public class IfController extends Generi
* evaluate the condition clause log error if bad condition
*/
private boolean evaluateCondition(String cond) {
- logger.debug(" getCondition() : [" + cond + "]");
-
- String resultStr = "";
- boolean result = false;
-
- // now evaluate the condition using JavaScript
- Context cx = Context.enter();
- try {
- Scriptable scope = cx.initStandardObjects(null);
- Object cxResultObject = cx.evaluateString(scope, cond
- /** * conditionString ** */
- , "<cmd>", 1, null);
- resultStr = Context.toString(cxResultObject);
-
- if (resultStr.equals("false")) { //$NON-NLS-1$
- result = false;
- } else if (resultStr.equals("true")) { //$NON-NLS-1$
- result = true;
- } else {
- throw new Exception(" BAD CONDITION :: " + cond + " :: expected true or false");
- }
-
- logger.debug(" >> evaluate Condition - [ " + cond + "] results is [" + result + "]");
- } catch (Exception e) {
- logger.error(getName()+": error while processing "+ "[" + cond + "]\n", e);
- } finally {
- Context.exit();
+ if(logger.isDebugEnabled()) {
+ logger.debug(" getCondition() : [" + cond + "]");
}
+ return JAVASCRIPT_EVALUATOR.evaluate(getName(), cond);
+ }
+ /**
+ * @param condition
+ * @param resultStr
+ * @return boolean
+ * @throws Exception
+ */
+ private static final boolean computeResultFromString(String condition, String resultStr) throws Exception {
+ boolean result;
+ switch(resultStr) {
+ case "false":
+ result=false;
+ break;
+ case "true":
+ result=true;
+ break;
+ default:
+ throw new Exception(" BAD CONDITION :: " + condition + " :: expected true or false");
+ }
+ if(logger.isDebugEnabled()) {
+ logger.debug(" >> evaluate Condition - [ " + condition + "] results is [" + result + "]");
+ }
return result;
}
-
+
+
private static boolean evaluateExpression(String cond) {
return cond.equalsIgnoreCase("true"); // $NON-NLS-1$
}
@@ -209,4 +289,12 @@ public class IfController extends Generi
public void setUseExpression(boolean selected) {
setProperty(USE_EXPRESSION, selected, false);
}
+ @Override
+ public void threadStarted() {
+
+ }
+ @Override
+ public void threadFinished() {
+ NASHORN_ENGINE.remove();
+ }
}
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1702817&r1=1702816&r2=1702817&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Sun Sep 13 20:12:47 2015
@@ -74,6 +74,7 @@ Summary
<ul>
<li>In RandomTimer class, protected instance timer has been replaced by getTimer() protected method, this is related to <bugzilla>58100</bugzilla>. This may impact 3rd party plugins.</li>
+ <li>If Controller will now use by default Nashorn Engine under Java8. If you want to revert to Rhino Engine, use property <code>ifcontroller.use_rhino=true</code>, see <bugzilla>58406</bugzilla></li>
</ul>
<!-- =================== Improvements =================== -->
@@ -94,6 +95,7 @@ Summary
<h3>Controllers</h3>
<ul>
+ <li><bug>58406</bug>IfController : Use Nashorn Engine if available for JavaScript evaluation</li>
</ul>
<h3>Listeners</h3>