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 2012/07/08 22:27:52 UTC

svn commit: r1358829 - in /jmeter/trunk: src/components/org/apache/jmeter/assertions/ src/components/org/apache/jmeter/extractor/ src/components/org/apache/jmeter/modifiers/ src/components/org/apache/jmeter/timers/ src/components/org/apache/jmeter/visu...

Author: pmouawad
Date: Sun Jul  8 20:27:52 2012
New Revision: 1358829

URL: http://svn.apache.org/viewvc?rev=1358829&view=rev
Log:
Bug 53520 - JSR223 Elements : Use Compilable interface to improve performances on File scripts
Bugzilla Id: 53520

Modified:
    jmeter/trunk/src/components/org/apache/jmeter/assertions/JSR223Assertion.java
    jmeter/trunk/src/components/org/apache/jmeter/extractor/JSR223PostProcessor.java
    jmeter/trunk/src/components/org/apache/jmeter/modifiers/JSR223PreProcessor.java
    jmeter/trunk/src/components/org/apache/jmeter/timers/JSR223Timer.java
    jmeter/trunk/src/components/org/apache/jmeter/visualizers/JSR223Listener.java
    jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java
    jmeter/trunk/src/protocol/java/org/apache/jmeter/protocol/java/sampler/JSR223Sampler.java
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/src/components/org/apache/jmeter/assertions/JSR223Assertion.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/assertions/JSR223Assertion.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/assertions/JSR223Assertion.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/assertions/JSR223Assertion.java Sun Jul  8 20:27:52 2012
@@ -20,6 +20,7 @@ package org.apache.jmeter.assertions;
 
 import java.io.IOException;
 
+import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 
@@ -39,9 +40,10 @@ public class JSR223Assertion extends JSR
         AssertionResult result = new AssertionResult(getName());
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            scriptEngine.put("SampleResult", response);
-            scriptEngine.put("AssertionResult", result);
-            processFileOrScript(scriptEngine);
+            Bindings bindings = scriptEngine.createBindings();
+            bindings.put("SampleResult", response);
+            bindings.put("AssertionResult", result);
+            processFileOrScript(scriptEngine, bindings);
             result.setError(false);
         } catch (IOException e) {
             log.warn("Problem in JSR223 script ", e);

Modified: jmeter/trunk/src/components/org/apache/jmeter/extractor/JSR223PostProcessor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/JSR223PostProcessor.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/JSR223PostProcessor.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/JSR223PostProcessor.java Sun Jul  8 20:27:52 2012
@@ -38,7 +38,7 @@ public class JSR223PostProcessor extends
     public void process() {
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            processFileOrScript(scriptEngine);
+            processFileOrScript(scriptEngine, null);
         } catch (ScriptException e) {
             log.warn("Problem in JSR223 script ", e);
         } catch (IOException e) {

Modified: jmeter/trunk/src/components/org/apache/jmeter/modifiers/JSR223PreProcessor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/JSR223PreProcessor.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/modifiers/JSR223PreProcessor.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/modifiers/JSR223PreProcessor.java Sun Jul  8 20:27:52 2012
@@ -38,7 +38,7 @@ public class JSR223PreProcessor extends 
     public void process() {
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            processFileOrScript(scriptEngine);
+            processFileOrScript(scriptEngine, null);
         } catch (ScriptException e) {
             log.warn("Problem in JSR223 script ", e);
         } catch (IOException e) {

Modified: jmeter/trunk/src/components/org/apache/jmeter/timers/JSR223Timer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/timers/JSR223Timer.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/timers/JSR223Timer.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/timers/JSR223Timer.java Sun Jul  8 20:27:52 2012
@@ -38,7 +38,7 @@ public class JSR223Timer extends JSR223T
         long delay = 0;
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            Object o = processFileOrScript(scriptEngine);
+            Object o = processFileOrScript(scriptEngine, null);
             if (o == null) {
                 log.warn("Script did not return a value");
                 return 0;

Modified: jmeter/trunk/src/components/org/apache/jmeter/visualizers/JSR223Listener.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/JSR223Listener.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/visualizers/JSR223Listener.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/visualizers/JSR223Listener.java Sun Jul  8 20:27:52 2012
@@ -20,6 +20,7 @@ package org.apache.jmeter.visualizers;
 
 import java.io.IOException;
 
+import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 
@@ -42,9 +43,10 @@ public class JSR223Listener extends JSR2
     public void sampleOccurred(SampleEvent event) {
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            scriptEngine.put("sampleEvent", event);
-            scriptEngine.put("sampleResult", event.getResult());
-            processFileOrScript(scriptEngine);
+            Bindings bindings = scriptEngine.createBindings();
+            bindings.put("sampleEvent", event);
+            bindings.put("sampleResult", event.getResult());
+            processFileOrScript(scriptEngine, bindings);
         } catch (ScriptException e) {
             log.warn("Problem in JSR223 script ", e);
         } catch (IOException e) {

Modified: jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/util/JSR223TestElement.java Sun Jul  8 20:27:52 2012
@@ -23,12 +23,18 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
 import java.util.Properties;
 
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
+import org.apache.commons.collections.map.LRUMap;
 import org.apache.commons.io.IOUtils;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jmeter.samplers.Sampler;
@@ -67,6 +73,13 @@ public abstract class JSR223TestElement 
     private String script; // script (if file not provided)
 
     private String scriptLanguage; // JSR223 language to use
+
+    /**
+     * Cache of compiled scripts
+     */
+    private static Map<String, CompiledScript> compiledScriptsCache = 
+            Collections.synchronizedMap(
+                    new LRUMap(JMeterUtils.getPropDefault("jsr223.compiled_scripts_cache_size", 100)));
     //-- For TestBean implementations only
 
     public JSR223TestElement() {
@@ -101,56 +114,102 @@ public abstract class JSR223TestElement 
             throw new ScriptException("Cannot find engine named: "+lang);
         }
 
-        initScriptEngine(scriptEngine);
         return scriptEngine;
     }
 
-    protected void initScriptEngine(ScriptEngine sem) {
+    /**
+     * Populate variables to be passed to scripts
+     * @param bindings Bindings
+     */
+    protected void populateBindings(Bindings bindings) {
         final String label = getName();
         final String fileName = getFilename();
         final String scriptParameters = getParameters();
         // Use actual class name for log
         final Logger logger = LoggingManager.getLoggerForShortName(getClass().getName());
-
-        sem.put("log", logger);
-        sem.put("Label", label);
-        sem.put("FileName", fileName);
-        sem.put("Parameters", scriptParameters);
+        bindings.put("log", logger);
+        bindings.put("Label", label);
+        bindings.put("FileName", fileName);
+        bindings.put("Parameters", scriptParameters);
         String [] args=JOrphanUtils.split(scriptParameters, " ");//$NON-NLS-1$
-        sem.put("args", args);
+        bindings.put("args", args);
         // Add variables for access to context and variables
         JMeterContext jmctx = JMeterContextService.getContext();
-        sem.put("ctx", jmctx);
+        bindings.put("ctx", jmctx);
         JMeterVariables vars = jmctx.getVariables();
-        sem.put("vars", vars);
+        bindings.put("vars", vars);
         Properties props = JMeterUtils.getJMeterProperties();
-        sem.put("props", props);
+        bindings.put("props", props);
         // For use in debugging:
-        sem.put("OUT", System.out);
+        bindings.put("OUT", System.out);
 
         // Most subclasses will need these:
         Sampler sampler = jmctx.getCurrentSampler();
-        sem.put("sampler", sampler);
+        bindings.put("sampler", sampler);
         SampleResult prev = jmctx.getPreviousResult();
-        sem.put("prev", prev);
+        bindings.put("prev", prev);
     }
 
 
-    protected Object processFileOrScript(ScriptEngine scriptEngine) throws IOException, ScriptException {
-        File scriptFile = new File(getFilename());        
+    /**
+     * This method will run inline script or file script with special behaviour for file script:
+     * - If ScriptEngine implements Compilable script will be compiled and cached
+     * - If not if will be run
+     * @param scriptEngine ScriptEngine
+     * @param bindings {@link Bindings} might be null
+     * @return Object returned by script
+     * @throws IOException
+     * @throws ScriptException
+     */
+    protected Object processFileOrScript(ScriptEngine scriptEngine, Bindings bindings) throws IOException, ScriptException {
+        if(bindings == null) {
+            bindings = scriptEngine.createBindings();
+        }
+        populateBindings(bindings);
+        File scriptFile = new File(getFilename()); 
+        // Hack as in bsh-2.0b5.jar BshScriptEngine implements Compilable but throws new Error
+        boolean supportsCompilable = scriptEngine instanceof Compilable 
+                && !(scriptEngine.getClass().getName().equals("bsh.engine.BshScriptEngine"));
         if (scriptFile.exists()) {
             BufferedReader fileReader = null;
             try {
-                fileReader = new BufferedReader(new FileReader(scriptFile)); // TODO Charset ?
-                return scriptEngine.eval(fileReader);
+                if(supportsCompilable) {
+                    String cacheKey = 
+                            getScriptLanguage()+"#"+
+                            scriptFile.getAbsolutePath()+"#"+
+                                    scriptFile.lastModified();
+                    CompiledScript compiledScript = 
+                            compiledScriptsCache.get(cacheKey);
+                    if(compiledScript==null) {
+                        synchronized (compiledScriptsCache) {
+                            compiledScript = 
+                                    compiledScriptsCache.get(cacheKey);
+                            if(compiledScript==null) {
+                                // TODO Charset ?
+                                fileReader = new BufferedReader(new FileReader(scriptFile), 
+                                        (int)scriptFile.length()); 
+                                compiledScript = 
+                                        ((Compilable) scriptEngine).compile(fileReader);
+                                compiledScriptsCache.put(cacheKey, compiledScript);
+                            }
+                        }
+                    }
+                    return compiledScript.eval(bindings);
+                } else {
+                    // TODO Charset ?
+                    fileReader = new BufferedReader(new FileReader(scriptFile), 
+                            (int)scriptFile.length()); 
+                    return scriptEngine.eval(fileReader, bindings);                    
+                }
             } finally {
                 IOUtils.closeQuietly(fileReader);
             }
         } else {
-            return scriptEngine.eval(getScript());
+            return scriptEngine.eval(getScript(), bindings);
         }
     }
 
+
     /**
      * Return the script (TestBean version).
      * Must be overridden for subclasses that don't implement TestBean

Modified: jmeter/trunk/src/protocol/java/org/apache/jmeter/protocol/java/sampler/JSR223Sampler.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/java/org/apache/jmeter/protocol/java/sampler/JSR223Sampler.java?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/java/org/apache/jmeter/protocol/java/sampler/JSR223Sampler.java (original)
+++ jmeter/trunk/src/protocol/java/org/apache/jmeter/protocol/java/sampler/JSR223Sampler.java Sun Jul  8 20:27:52 2012
@@ -23,6 +23,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 
@@ -59,8 +60,9 @@ public class JSR223Sampler extends JSR22
         result.sampleStart();
         try {
             ScriptEngine scriptEngine = getScriptEngine();
-            scriptEngine.put("SampleResult",result);
-            Object ret = processFileOrScript(scriptEngine);
+            Bindings bindings = scriptEngine.createBindings();
+            bindings.put("SampleResult",result);
+            Object ret = processFileOrScript(scriptEngine, bindings);
             result.setSuccessful(true);
             result.setResponseCodeOK();
             result.setResponseMessageOK();

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1358829&r1=1358828&r2=1358829&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Sun Jul  8 20:27:52 2012
@@ -61,7 +61,11 @@ Furthermore it doesn't put anymore in Ca
 <p>
 A major change has occured on JSR223 Test Elements, previously variables set up before script execution where stored in ScriptEngineManager which was created once per execution, 
 now ScriptEngineManager is a singleton shared by all JSR223 elements and only ScriptEngine is created once per execution, variables set up before script execution are now stored 
-in ScriptEngine context, see <bugzilla>53365</bugzilla>. 
+in Bindings created on each execution, see <bugzilla>53365</bugzilla>.
+</p>
+
+<p>
+JSR223 Test Elements using Script file are now Compiled if ScriptEngine supports this feature, see <bugzilla>53520</bugzilla>.
 </p>
 
 <!-- =================== Bug fixes =================== -->
@@ -79,7 +83,6 @@ in ScriptEngine context, see <bugzilla>5
 <li><bugzilla>53348</bugzilla> - JMeter JMS Point-to-Point Request-Response sampler doesn't work when Request-queue and Receive-queue are different</li>
 <li><bugzilla>53357</bugzilla> - JMS Point to Point reports too high response times in Request Response Mode</li>
 <li><bugzilla>53440</bugzilla> - SSL connection leads to ArrayStoreException on JDK 6 with some KeyManagerFactory SPI</li>
-
 </ul>
 
 <h3>Controllers</h3>
@@ -105,6 +108,7 @@ in ScriptEngine context, see <bugzilla>5
 <h3>General</h3>
 <ul>
 <li><bugzilla>53365</bugzilla> - JSR223TestElement should cache ScriptEngineManager</li>
+<li><bugzilla>53520</bugzilla> - JSR223 Elements : Use Compilable interface to improve performances on File scripts</li>
 </ul>
 
 <!-- =================== Improvements =================== -->