Reputation: 872
I write Groovy script in my JSR223 PreProcessor like this
import groovy.json.JsonSlurper;
class jmeter {
def parsingJSON(String fileName){
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
vars.put("myVar", object.event_id)
return object.event_id
}
}
def running = new jmeter()
running.parsingJSON( "C:/Users/payload.json")
this will return exception
ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor Dummy
javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: vars for class: jmeter
But when I remove the class , so it looks like this
import groovy.json.JsonSlurper;
def parsingJSON(String fileName){
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
vars.put("myVar", object.event_id)
return object.event_id
}
parsingJSON( "C:/Users/payload.json")
It will run without any issue.
My question: I understand vars
is JMeter internal API , but can't we use vars.put()
or vars.get()
in Groovy script using class{}
in JSR223 Sampler / PreProcessor in JMeter?
[UPDATE after getting input 1 Jul 19]:
I write the codes in Intellij and looks like this. It runs perfectly fine.
import groovy.json.JsonSlurper
import org.apache.jmeter.threads.JMeterVariables
class jmeter {
JMeterVariables vars;
jmeter(JMeterVariables vars) {
this.vars = vars;
}
def parsingJSON(String fileName){
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
vars.put("myVar", object.event_id)
println("My Var " + vars.get("myVar"))
return object.event_id
}
}
class runTest {
static void main(String[] args) {
JMeterVariables vars = new JMeterVariables();
def running = new jmeter(vars)
running.parsingJSON( "C:/Users/payload")
}
}
The code basically put the value to parameter myVar , so I can use it in my HTTP Request Sampler. I copy paste it to JMeter JSR223 PreProcessor, then create HTTP Request sampler and put ${myVar} in the Body Data
I expect the value of "myVar" will be reflected in the Body Data. But after I run it , I see the parameter ${myVar} in Result Tree Listener , instead of the value.
[UPDATE after getting input from Dmitry 3 July 2019]
I use IntelliJ and write the code like this
import groovy.json.JsonSlurper
import org.apache.jmeter.threads.JMeterVariables
class Global {
static vars = [:]
}
Global.vars.jmeterVars = vars
class jmeter {
def parsingJSON(String fileName){
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
Global.vars.jmeterVars.put("myVar", object.event_id) //This will return java.lang.NullPointerException: Cannot invoke method put() on null object
println("My Var " + vars.get("myVar"))
return object.event_id
}
}
class runTest {
static void main(String[] args) {
def running = new jmeter()
running.parsingJSON( "C:/Users/payload")
}
}
This time even IntelliJ returns me an error
Exception in thread "main" java.lang.NullPointerException: Cannot invoke method put() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:43)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:135)
at jmeter.parsingJSON(jmeter.groovy:21)
at jmeter$parsingJSON.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at runTest.main(jmeter.groovy:38)
Basically, the error is caused by Global.vars.jmeterVars.put("myVar", object.event_id)
[UPDATE] : 17 July 2019 with input from user7294900
I wrote the code like this in IntelliJ
import groovy.json.JsonSlurper
import org.apache.jmeter.threads.JMeterVariables
class jmeter2 {
JMeterVariables vars;
jmeter2(JMeterVariables vars) {
this.vars = vars;
}
public addvar(String VarName, String value) {
vars.put(VarName, value);
}
def parsingJSON(String fileName) {
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
addvar("myVar", object.event_id)
println("My Var " + vars.get("myVar"))
return object.event_id
}
}
class runTest {
static void main(String[] args) {
JMeterVariables vars = new JMeterVariables();
def running = new jmeter2(vars)
running.parsingJSON( "C:/Users/payload.json")
}
}
It works perfectly fine in Intellij. I just need to add some jar dependencies to Intellij (slf4j-simple-1.7.2
, apachejmeter_core
, logkit-1.2.2
). IntelliJ will return the result. So far so good.
I copied paste the code to JMeter , by creating JSR223 sampler
, debug sampler
, and Results Tree listener
.
I can't see any myVar
created by JSR223 sampler in the Listener.
JMeter log also doesn't show any issue
2019-07-17 12:33:15,806 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2019-07-17 12:33:15,806 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2019-07-17 12:33:15,812 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group
2019-07-17 12:33:15,812 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Thread Group.
2019-07-17 12:33:15,812 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2019-07-17 12:33:15,812 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 delayedStart=false
2019-07-17 12:33:15,813 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2019-07-17 12:33:15,813 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2019-07-17 12:33:15,813 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2019-07-17 12:33:15,825 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2019-07-17 12:33:15,825 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2019-07-17 12:33:15,825 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2019-07-17 12:33:15,825 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
The file payload.json only contains a very simple json
{
"event_id": "01DE95CRARFQ4X9WEKXACQYHVX",
"event_type": "form_response"
}
I am not sure why JMeter doesn't like the script. Any idea maybe? Thanks.
Upvotes: 3
Views: 8573
Reputation: 58822
If you want to add variable(s) you need to pass current JMeterVariables
object to jmeter object,
The following code add variable aaa
to existing JMeter variables
import org.apache.jmeter.threads.JMeterVariables;
class jmeter {
JMeterVariables vars;
jmeter(JMeterVariables vars) {
this.vars = vars;
}
public addvar() {
vars.put("aaa","bbb");
}
}
def running = new jmeter(vars);
running.addvar();
So Intellij recognize JMeterVariables
you will have to add ApacheJMeter_core.jar
from JMeter's lib\ext folder
Upvotes: 0
Reputation: 168132
If you want to keep your code structure with minimal changes consider introducing a separate class holding static variables which will be accessible everywhere in your Groovy script.
Something like:
import groovy.json.JsonSlurper
class Global {
static vars = [:]
}
Global.vars.jmeterVars = vars
class jmeter {
def parsingJSON(String fileName) {
def payload = new File(fileName).getText();
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(payload)
Global.vars.jmeterVars.put("myVar", object.event_id)
return object.event_id
}
}
def running = new jmeter()
running.parsingJSON("C:/Users/payload.json")
More information:
Upvotes: 0