I am trying to execute JMeter script from Java code using
String jmeterHome = "D:/tmp/apache-jmeter-3.3";
StandardJMeterEngine jmeter = new StandardJMeterEngine();
JMeterUtils.loadJMeterProperties(jmeterHome + "/jmeter.properties");
JMeterUtils.setJMeterHome(jmeterHome);
JMeterUtils.initLocale();
SaveService.loadProperties();
File script = new File(jmeterHome + "/http_localhost.jmx");
HashTree testPlanTree = SaveService.loadTree(script);
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
String logFile = jmeterHome + "/file.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
jmeter.configure(testPlanTree);
jmeter.run();
In JMeter GUI in "Thread Group" configuration I am setting "Number Of Threads" to be "${__P(xxx,20)}". It works fine from the GUI - I can execute script with default value of "20". But the code above does not start any threads. Java code prints that it is trying to start zero threads.
I have seen Jmeter functions don't executing when calling from java code and I do have following dependencies in my project
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_http</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_functions</artifactId>
<version>3.3</version>
</dependency>
Your code is wrong, you are not referencing the correct jmeter.properties path.
Working example:
String jmeterHome = "/data/jmeter/jmeters/apache-jmeter-3.3/";
StandardJMeterEngine jmeter = new StandardJMeterEngine();
JMeterUtils.setJMeterHome(jmeterHome);
JMeterUtils.loadJMeterProperties(jmeterHome + "bin/jmeter.properties");
JMeterUtils.initLocale();
SaveService.loadProperties();
File script = new File("/data/jmeter/workspace/JMeterFromJava/scenario/localhost.jmx");
HashTree testPlanTree = SaveService.loadTree(script);
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (summariserName.length() > 0) {
summer = new Summariser(summariserName);
}
String logFile = "/data/jmeter/workspace/JMeterFromJava/results/file.jtl";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(logFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
jmeter.configure(testPlanTree);
jmeter.run();
EDIT 29 september 2017:
You submitted to bugzilla a demo project showing the problem. It helped understand your problem.
Status:
- Code works if App is ran as a Main application
- Code works if AppTest is ran from Eclipse
- But code fails when ran through mvn clean install
The failure is due to this code:
- https://github.com/apache/jmeter/blob/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java#L335
Small workaround:
final List<String> classPathUrls = new ArrayList<>();
for (final URL url : URLClassLoader.class.cast(this.getClass().getClassLoader()).getURLs()) {
classPathUrls.add(url.getPath());
}
final String classPath = StringUtils.join(classPathUrls, ";");
JMeterUtils.setProperty("search_paths", classPath);
When Jmeter functions are used in the Java code, Jmeter tries to compare the function related classes from java class path with classes from the 'search_path' (Reads classes from the jars). So Jmeter function works only if required function class is present in both the path (Jmeter has seperate class for each function).
This is why we need to make sure the 'ApacheJMeter_functions' jar added in the pom (which will be added in class path ) and the path to jmeter functions jar is set to 'search_path'.Both should have same version.
You can refer this link for more details
The problem with JMeter is that it wants to have a library in classpath with exact name of "ApacheJMeter_functions.jar" it can't be "ApacheJMeter_functions-3.3.jar" even if the files are binary equal