Getting Content is not allowed in prolog when running in Java - jmeter

I am facing Content is not allowed in prolog exception when I run my xxx.jmx file from Java (Jmeter 5.0).
I tested the jmx in the GUI mode and everything works fine and in the Java I am just following the standard way to call the jmx file and execute it.
The jmx just have some normal stuff. Sending HTTP request and validate the expected and received XML (I am using this snipped to validate):
import org.apache.commons.io.FileUtils
expect = FileUtils.readFileToString(new File('some_path'))
XmlParser parser = new XmlParser()
expectedXML = new XmlSlurper().parseText(expect)
actualXML = new XmlSlurper().parseText(prev.getResponseDataAsString())
if (expectedXML != actualXML) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage('Mismatch between expected and actual XML \n'+ prev.getResponseDataAsString())
and the stack trace:
2018/10/24 15:18:03,386 12675 [ERROR ] [Thread Group 1-1] (JSR223Assertion.java:52) – Problem in JSR223 script: Validate resposne
javax.script.ScriptException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320)
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:72)
at javax.script.CompiledScript.eval(CompiledScript.java:92)
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:221)
at org.apache.jmeter.assertions.JSR223Assertion.getResult(JSR223Assertion.java:49)
at org.apache.jmeter.threads.JMeterThread.processAssertion(JMeterThread.java:901)
at org.apache.jmeter.threads.JMeterThread.checkAssertions(JMeterThread.java:892)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:565)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at groovy.util.XmlSlurper.parse(XmlSlurper.java:207)
at groovy.util.XmlSlurper.parse(XmlSlurper.java:260)
at groovy.util.XmlSlurper.parseText(XmlSlurper.java:286)
at groovy.util.XmlSlurper$parseText.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at Script1.run(Script1.groovy:9)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
... 10 more
UPDATE 1:
The problem of using Response Assertion is it cannot ignore the space or tab. So if the format is not exactly the same when I use equal will always fail. Any ideas how to ignore these things by using Response Assertion?
UPDATE 2:
I found out that the issue is not related to the BOM. Is becasue if I run the jmx from my Java application:
prev.getResponseDataAsString()
above function always return:
${__FileToString(${inputFilePath},,)}
but not the actual response. This function is come from the body data of the HTTP Request sampler!!!!!! If I give the acutal body there then I am able to run the jmx...... Any idea how to deal with this dynamic body data?

It might be the case your "expected" XML file contains BOM and it causes your code failure.
BOM is basically 3 first bytes so you can remove them using code like:
def expect = FileUtils.readFileToString(new File('some_path')).getBytes().flatten()
1.upto(3) {
expect.remove(0)
}
XmlParser parser = new XmlParser()
def expectedXML = parser.parseText(new String(expect.toArray(new Byte[0])))
The rest of your code should work fine.
Check out The Groovy Templates Cheat Sheet for JMeter article to learn more Groovy tips and tricks.
Also be informed that in majority of cases it's easier to use Response Assertion or when it comes to XML - XPath Assertion, Java code will work faster than Groovy in any case.

Related

Jmeter BeanShellSampler error: Error invoking bsh method: eval import org.apache.commons.io.FileUtils

I use BeanShell code loading 100s of sql files in jmeter:
import org.apache.commons.io.FileUtils;
File folder = new File("D:\\sql99");
File[] sqlFiles = folder.listFiles();
for (int i = 0; i < sqlFiles.length; i++) {
File sqlFile = sqlFiles[i];
if (sqlFile.isFile()) {
vars.put("query_" + i,sqlFile.getName(),
FileUtils.readFileToString(sqlFiles[i]));
}
}
but get error info :
17:42:03,301 ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import org.apache.commons.io.FileUtils; File folder = new File("D:\sql99"); Fi . . . '' : Error in method invocation: Method put( java.lang.String, java.lang.String, java.lang.String ) not found in class'org.apache.jmeter.threads.JMeterVariables'
I want to get each sql execute time in jmeter results tree. How to fix code?
Thanks!
You're trying to call JMeterVariables.put() function which accepts 2 Strings as the parameters passing 3 Strings
The correct syntax is vars.put("variable-name", "variable-value"); so you need to decide how to amend this line:
vars.put("query_" + i, sqlFile.getName(), FileUtils.readFileToString(sqlFiles[i]));
so it would contain only 2 parameters instead of 3.
Also since JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting mainly for performance reasons so it might be a good option for switching (the same code will work in Groovy without changes assuming you fix the issue with vars.put() function call)

Using UltimateThreadGroup with Java API gives Nullpointer exception

I am trying to use UltimateThreadGroup with the JMeter Java API, I am creating the UltimateThreadGroup object as in the below code[2] and add it to the Hashtree.
Finally handover it to the JMeter engine to execute. 
But It gives the following NullPointerException in the middle of execution. As I debugged the code, the Issue seems coming from JMeterThread class following method.
public JMeterThread(HashTree test, JMeterThreadMonitor monitor, ListenerNotifier note, Boolean isSameUserOnNextIteration)
But issue throws on different code lines from execution to execution. So it's difficult figure out what causing the NullPointer.
Does anybody have an idea on what's going on here? Appreciate your answers.
[1]
2020-11-03 13:08:20 DEBUG TestCompiler:273 - adding controller: kg.apc.jmeter.threads.UltimateThreadGroup#30b2b76f to sampler config
2020-11-03 13:08:22 ERROR JMeterThread:319 - Test failed!
java.lang.NullPointerException
at org.apache.jmeter.threads.AbstractThreadGroup.addTestElement(AbstractThreadGroup.java:122)
at org.apache.jmeter.threads.AbstractThreadGroup.addTestElementOnce(AbstractThreadGroup.java:131)
at org.apache.jmeter.threads.TestCompiler.subtractNode(TestCompiler.java:151)
at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:997)
at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:994)
at org.apache.jorphan.collections.HashTree.traverse(HashTree.java:976)
at org.apache.jmeter.threads.JMeterThread.initRun(JMeterThread.java:704)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:252)
at java.lang.Thread.run(Thread.java:748)
[2]
UltimateThreadGroup ultimateThreadGroup = new UltimateThreadGroup();
ultimateThreadGroup.setName(threadGroupName);
ultimateThreadGroup.setProperty(AbstractThreadGroup.ON_SAMPLE_ERROR, AbstractThreadGroup.ON_SAMPLE_ERROR_CONTINUE);
PowerTableModel dataModel = new PowerTableModel(UltimateThreadGroupGui.columnIdentifiers, UltimateThreadGroupGui.columnClasses);
dataModel.addRow(new Integer[]{2, 4, 10, 60, 10});
dataModel.addRow(new Integer[]{3, 4, 10, 120, 10});
CollectionProperty prop = JMeterPluginsUtils.tableModelRowsToCollectionProperty(dataModel, UltimateThreadGroup.DATA_PROPERTY);
ultimateThreadGroup.setData(prop);
ultimateThreadGroup.setEnabled(setEnabled);
ultimateThreadGroup.setProperty(TestElement.TEST_CLASS, UltimateThreadGroup.class.getName());
ultimateThreadGroup.setProperty(TestElement.GUI_CLASS, UltimateThreadGroupGui.class.getName());
First you need to create a Loop Controller instance like:
LoopController loopController = new LoopController();
loopController.setLoops(1);
loopController.setFirst(true);
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
loopController.initialize();
Second you need to add the Loop Controller from the step 1 to your Ultimate Thread Group:
ultimateThreadGroup.setSamplerController(loopController);
More information:
Five Ways To Launch a JMeter Test without Using the JMeter GUI
jmeter-from-code
Going forward just compare the .jmx which you generate programatically with the one which is created by JMeter GUI, you will be able to see what fields, properties, etc. are missing

Not able to import com.paytm.merchant.CheckSumServiceHelper when running beanshell script in jmeter

I am new to Jmeter's JSR223 PreProcessor. We have just integrated Paytm's payment gateway into our product and we had to run load tests using Jmeter. We have to generate a checksum using a set of values and then inject that into our Json payload. I am using Java Beanshell to execute the code. I have added the jar file available here in my bin directory and also added it to my class path before starting the tests. Here is what my code looks like:
import com.paytm.merchant.CheckSumServiceHelper;
com.paytm.merchant.CheckSumServiceHelper checkSumServiceHelper = com.paytm.merchant.CheckSumServiceHelper.getCheckSumServiceHelper();
TreeMap<String,String> parameters = new TreeMap<String,String>();
String merchantKey = "xxxxxxxxxxxxxxxxx";
parameters.put("MID", "xxxxxxxxxxxxxxxxxxxxxx");
parameters.put("ORDERID", "${orderId}");
parameters.put("TXNID", "20200113111212800110168201701179744");
parameters.put("TXN_AMOUNT", "10.01");
parameters.put("PAYMENTMODE", "DC");
parameters.put("CURRENCY", "INR");
parameters.put("TXNDATE", "2020-01-13 13:59:03.0");
parameters.put("STATUS", "TXN_SUCCESS");
parameters.put("RESPCODE", "01");
parameters.put("RESPMSG", "Txn Success");
parameters.put("GATEWAYNAME", "HDFC");
parameters.put("BANKTXNID", "777001911059826");
parameters.put("BANKNAME", "JPMORGAN CHASE BANK");
parameters.put("BANKNAME", "JPMORGAN CHASE BANK");
String checkSum = checkSumServiceHelper.genrateCheckSumGAE(merchantKey, parameters);
vars.put("checkSum", checkSum)
Here is the error I am getting as a result:
javax.script.ScriptException: Sourced file: inline evaluation of: ``import com.paytm.merchant.CheckSumServiceHelper; com.paytm.merchant.CheckSumSer . . . '' : Typed variable declaration : Class: com.paytm.merchant.CheckSumServiceHelper not found in namespace : at Line: 3 : in file: inline evaluation of: ``import com.paytm.merchant.CheckSumServiceHelper; com.paytm.merchant.CheckSumSer . . . '' : com .paytm .merchant .CheckSumServiceHelper
in inline evaluation of: ``import com.paytm.merchant.CheckSumServiceHelper; com.paytm.merchant.CheckSumSer . . . '' at line number 3
at bsh.engine.BshScriptEngine.evalSource(BshScriptEngine.java:93) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19]
at bsh.engine.BshScriptEngine.eval(BshScriptEngine.java:46) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19]
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233) ~[java.scripting:?]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:225) ~[ApacheJMeter_core.jar:5.1.1 r1855137]
at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:44) [ApacheJMeter_components.jar:5.1.1 r1855137]
at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:935) [ApacheJMeter_core.jar:5.1.1 r1855137]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:537) [ApacheJMeter_core.jar:5.1.1 r1855137]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486) [ApacheJMeter_core.jar:5.1.1 r1855137]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253) [ApacheJMeter_core.jar:5.1.1 r1855137]
at java.lang.Thread.run(Thread.java:830) [?:?]
Any kind of help to resolve this error will be highly appreciated. It might be a stupid question but I am new to this so please help!! :)
EDIT:
I am now using the groovy syntax for doing this. I am not able to view my checksum variable in View Results Tree with my debug sampler but I am able to see it in the console. The value is shown correctly in console. But the variable is not being exported.
import com.paytm.pg.merchant.CheckSumServiceHelper;
com.paytm.pg.merchant.CheckSumServiceHelper checkSumServiceHelper = com.paytm.pg.merchant.CheckSumServiceHelper.getCheckSumServiceHelper();
TreeMap parameters = new TreeMap();
String merchantKey = "xxxxxxxxxxxxxxxxx";
parameters.put("MID", "xxxxxxxxxxxxxxxxxxxxxx");
parameters.put("ORDERID", "${orderId}");
parameters.put("TXNID", "20200113111212800110168201701179744");
parameters.put("TXN_AMOUNT", "10.01");
parameters.put("PAYMENTMODE", "DC");
parameters.put("CURRENCY", "INR");
parameters.put("TXNDATE", "2020-01-13 13:59:03.0");
parameters.put("STATUS", "TXN_SUCCESS");
parameters.put("RESPCODE", "01");
parameters.put("RESPMSG", "Txn Success");
parameters.put("GATEWAYNAME", "HDFC");
parameters.put("BANKTXNID", "777001911059826");
parameters.put("BANKNAME", "JPMORGAN CHASE BANK");
parameters.put("BANKNAME", "JPMORGAN CHASE BANK");
String checkSum = checkSumServiceHelper.genrateCheckSumGAE(merchantKey, parameters);
Out. println "s====================================ssssss"
OUT. println checkSum
props.put("checkSum", checkSum);
Here is the error when I run this:
javax.script.ScriptException: javax.script.ScriptException: java.security.InvalidKeyException: Invalid AES key length: 17 bytes
I think this error is due to my input values.
Beanshell is not Java and it isn't 100% compliant with Java, you need to stick to Java 1.5 language level in general.
In particular Beanshell doesn't support Diamond Operators, you need to remove them from your code like:
TreeMap parameters = new TreeMap();
In general starting from JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting, the reasons are in:
Groovy scripts can be compiled and cached while Beanshell is being evaluated each time it's called hence Groovy performance is much higher
Groovy supports all underlying JDK language features while Beanshell got stuck at Java 5
In addition Groovy provides a lot of enhancements over normal Java SDK
Check out Apache Groovy - Why and How You Should Use It article for more details.

illegal characters at line 1 and col 1 in xml response in jmeter

I am trying to validate the xml response from an REST API using JMETER. I am using xml schema assertion to validate the response using xsd.
I am getting the following error on XML Schema Assertion
Assertion error: true
Assertion failure: false
Assertion failure message: fatal: line=1 col=1 Content is not allowed in prolog.
When i see the response that i have received i see there are some illegal characters that is added at the beginning of the response xml.
enter image description here
I have tried to modify jmeter.properties file and changed the following values
jmeter.save.saveservice.output_format=xml
jmeter.save.saveservice.data_type=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.response_code=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_name=true
Please help me in understanding how to remove the illegal characters in the response and allow the xsd validation to pass through.
These characters indicate Byte Order Mark so you can use BOMInputStream from the JSR223 PostProcessor in order to remove them from the response and replace the response data with "sanitized" XML.
Add JSR223 PostProcessor as a child of the HTTP Request sampler where you want to remove this BOM
Put the following code into "Script" area:
def is = new ByteArrayInputStream(prev.getResponseData())
def bOMInputStream = new org.apache.commons.io.input.BOMInputStream(is)
def bom = bOMInputStream.getBOM()
def charsetName = bom == null ? 'UTF-8' : bom.getCharsetName()
def reader = new InputStreamReader(new BufferedInputStream(bOMInputStream), charsetName)
prev.setResponseData(org.apache.commons.io.IOUtils.toByteArray(reader, 'UTF-8'))
That's it, your assertion shouldn't be failing anymore.
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It

JMeter / Beanshell "Error invoking bsh method: eval Sourced file:"

I'm having an issue in JMeter wherein I receive this error
2014/08/14 14:13:26 ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``String RequestUrl = vars.get("RequestUrl"); String[] params = RequestUrl.split(" . . . '' : Typed variable declaration
2014/08/14 14:13:26 WARN - jmeter.extractor.BeanShellPostProcessor: Problem in BeanShell script org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``String RequestUrl = vars.get("RequestUrl"); String[] params = RequestUrl.split(" . . . '' : Typed variable declaration
I have no clue whats wrong, and the code otherwise seems to be working. Can anyone give me some advice?
Here is the block of code in question:
String RequestUrl = vars.get("RequestUrl");
String[] params = RequestUrl.split("\\?");
String RequestTask = params[1].split("\\&")[1].split("=")[1];
System.out.println(RequestTask);
vars.put("RequestTask",RequestTask);
it should probably be mentioned that the code is in a post processor, which is paired with an Xpath extractor for "RequestUrl"
Edited to include entire error
I don't see your URL and what does XPath query return but in any case your URL parsing logic looks flaky as it strongly dependent on parameters order and presence and may bite you back in future in case of request URL change i.e. extra parameter or changed parameters order or something encoded, etc.
See below for reference:
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import java.net.URI;
import java.util.List;
String url = vars.get("RequestUrl");
List params = URLEncodedUtils.parse(new URI(url), "UTF-8");
for (NameValuePair param : params) {
if (param.getName().equals("put your actual param name here")) {
vars.put("RequestTask", param.getValue());
}
}
Also it worth checking out How to use BeanShell: JMeter's favorite built-in component for troubleshooting tips. In general to localize error logging should be used like:
log.info("something");
log.error("something else");
So if you don't see message in the log than Beanshell wasn't able to execute the line and failed somewhere above.
Also Beanshell error messages aren't very informative, I use the following construction in my scripts:
try {
//script logic here
}
catch (Throwable ex) {
log.error("Failed to do this or that", ex);
}
So error stracktrace could be read in jmeter.log file.
Hope this helps.
Could you show the whole error?
Try adding one statement after the other to see which one is root cause.
I suppose you may be making hypothesis on results (array access) which may be cause of issue.
if you are coverting a VuGen recorded JMS script to JMeter, then you have to look for the lr functions copied which WILL throw this/similar error.
For eg: int orderlinecount = Integer.parseInt(lr.eval_string("strInt"));
You have to make sure your script is free of all lr - related functions in order for the jmeter to successfully executed your script.

Resources