jetma / jav8

Automatically exported from code.google.com/p/jav8
0 stars 0 forks source link

Add Support for Apache JMeter #18

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Apache JMeter does not run with jav8 currently.

There are several issues preventing jav8 working with JMeter
1. jav8 Bindings does not follow JSR 223 spec
2. jav8 does not have multi-threaded support

The use case is that we often want to use client side javascript code for load 
testing.  Since Rhino is slow, limited in script size (no more than 64k 
functions or 64k per function) and does not actually run any browser using v8 
would be ideal to solve these problems.

Installing jav8 to JMeter is simple.  Just copy the jar into the lib directory 
and create a JSR223 Element with a jav8 type.  Unfortunately things go downhill 
from there.

Bindings 
--------
The JSR223 Bindings passed by JMeter's JSR223TestElement.java are not passed to 
the V8 environment.  This is because v8 assumes that calls are like
...
Bindings g = this.eng.getBindings(ScriptContext.ENGINE_SCOPE);

        g.put("array", array2);
...

whereas JMeter JSR223TestElement.java sets up bindings with
...
        if (bindings == null) {
            bindings = scriptEngine.createBindings();
        }
        populateBindings(bindings);
...
    protected void populateBindings(Bindings bindings) {
...
        final Logger logger = LoggingManager.getLoggerForShortName(getClass().getName());
        bindings.put("log", logger);
...

then call the bindings with
...
                return compiledScript.eval(bindings);
...

A hack/patch is to update V8CompiledScript.java eval method to have
...
    @Override
    public Object eval(ScriptContext context) throws ScriptException
    {
        try {
            // Messy hack to import in from context
            for (Map.Entry<String,Object> entry : context.getBindings(ScriptContext.ENGINE_SCOPE).entrySet())
            {
                this.engine.put(entry.getKey(),entry.getValue());
            }

            return this.engine.getV8Context().bind(this.internalExecute(this.data, context));
        } catch (Exception e) {
            throw new ScriptException(e);
        }
    }
...

However there is probably a cleaner solution.

Multithreading  
--------------
The two cases that need to be supported are compiled scripts and eval'ed 
javascript.  JMeter blows up immediately using compiled scripts and runs with 
memory leaks and eventual blow ups when running eval'ed code.
* Need to use Locker

Unfortunately I'm not a C++ person so I haven't been able to get this to work.

Original issue reported on code.google.com by mr...@skermvas.com on 20 Jun 2013 at 3:54

GoogleCodeExporter commented 9 years ago

Original comment by flier...@gmail.com on 23 Dec 2013 at 11:25