BeanShell, custom java classes and Jmeter

This tutorial will guide you through the process of making a java class and using it within a Jmeter plan.

While JMeter does allow you to embed or include BeanShell code with the BeanShell Pre-Processor, Sampler and Post-Processor, you may find it extremely beneficial to instead create your code using your favourite java IDE which will give you the benefit of all the usual tools, documentation and support that you are used to.

So the basic plan is:

  1. code, test and compile your jar;
  2. import the compiled jar into your BeanShell code and use it

This tutorial assumes that you are are using Jmeter 2.9 and are using openjdk-7 as your default java handler.

Code and test your Java class

In this example we will create a custom class that scans a folder for files and returns a string array.

I used NetBeans but you can use whichever IDE you desire.

The first step is to create a new Java Application, I called mine “FileLister” and selected the option to create a main filelister.FileLister class. Here is the source code for a very simple class which has the following members/attributes:

  • a getter/setter for private variable folderPath
  • a scanForFiles method which returns a sorted string array of files found in folderPath
  • a printFiles method which prints out a file list and a count
  • a main method which checks that an argument is present and and calls printFiles

There are a few more checks and features I would add to make it production ready, but for the purpose of this example it will do. When you build and run it in NetBeans you should see the following output:

run:
build.xml
manifest.mf
2 files found
BUILD SUCCESSFUL (total time: 0 seconds)

Create a Jmeter Plan

When you are developing anything in Jmeter it is wise to enable console logging, so please take a moment to find your jmeter.properties file and uncomment the #log_file= line.

With that done, create a simple plan with the following structure:

  • Test Plan
    • Thread Group
      • BeanShell PreProcessor
      • BeanShell Sampler

The PreProcessor will import our jar, call the scanForFiles method and then put the file list and a count into variables.

The Sampler will retrieve these variables and print them out to the console.

Use the jar within BeanShell element

This is the most tricky bit. Although there are many ways  to manipulate java class paths I find the most reliable way to do it with BeanShell is to call addClassPath directly within a BeanShell script. You have to be aware of where your built jar file is, and either specify the full file path to it, or specify a relative path.

Note that usual short-cuts such as ‘~’ will not work. An example of a valid relative path is ../../NetBeansProjects/FileLister/dist/FileLister.jar not ~/NetBeansProjects/FileLister/dist/FileLister.jar.

The following code assumes you have the jmeter plan in a folder two levels under home, e.g. ~/perf_tests/javawalkthrough/walkthrough.jmx. It also assumes that you’ve created a folder full of test files under ~/scratch/example.

So, the code which you need to put inside the first BeanShell PreProcessor is as follows:

addClassPath("../../NetBeansProjects/FileLister/dist/FileLister.jar");
import filelister;
folderPath = "../../scratch/example";
System.out.println("Searching " + folderPath + " for files");
filelister.FileLister fl = new filelister.FileLister(folderPath);
String[] results = fl.scanForFiles();
System.out.println("Found " + results.length + " files");
vars.putObject("FILE_LIST", results);
vars.put("FILE_COUNT", Integer.toString(results.length));

And the code which goes in the BeanShell Sampler:

int fileCount = Integer.parseInt(vars.get("FILE_COUNT"));
String[] fileList = vars.getObject("FILE_LIST");
for (int i = 0; i < fileCount; i++)
{
System.out.println(fileList[i]);
}

Now you can save run with the following on a terminal jmeter -n -t walkthrough.jmx, and you should see log lines like the following:

log_file= java.io.FileNotFoundException: (No such file or directory)
[log_file-&gt; System.out]
log_file= java.io.FileNotFoundException: (No such file or directory)
[log_file-&gt; System.out]
2013/07/25 14:22:42 INFO - jmeter.util.JMeterUtils: Setting Locale to en_AU
2013/07/25 14:22:42 INFO - jmeter.JMeter: Loading user properties from: /opt/jmeter/bin/user.properties
2013/07/25 14:22:42 INFO - jmeter.JMeter: Loading system properties from: /opt/jmeter/bin/system.properties
2013/07/25 14:22:42 INFO - jmeter.JMeter: Copyright (c) 1998-2013 The Apache Software Foundation
2013/07/25 14:22:42 INFO - jmeter.JMeter: Version 2.9 r1437961
2013/07/25 14:22:42 INFO - jmeter.JMeter: java.version=1.7.0_40
...
2013/07/25 14:22:43 INFO - jmeter.threads.ThreadGroup: Started thread group number 1
2013/07/25 14:22:43 INFO - jmeter.engine.StandardJMeterEngine: All thread groups have been started
2013/07/25 14:22:43 INFO - jmeter.threads.JMeterThread: Thread started: Thread Group 1-1
Searching ../../scratch/example for files
Found 4 files
2013/07/25 14:22:43 INFO - jmeter.samplers.SampleResult: Note: Sample TimeStamps are START times
2013/07/25 14:22:43 INFO - jmeter.samplers.SampleResult: sampleresult.default.encoding is set to ISO-8859-1
2013/07/25 14:22:43 INFO - jmeter.samplers.SampleResult: sampleresult.useNanoTime=true
2013/07/25 14:22:43 INFO - jmeter.samplers.SampleResult: sampleresult.nanoThreadSleep=5000
a_file
a_fourth_file
a_third_file
another_file
2013/07/25 14:22:43 INFO - jmeter.threads.JMeterThread: Thread finished: Thread Group 1-1
2013/07/25 14:22:43 INFO - jmeter.engine.StandardJMeterEngine: Notifying test listeners of end of test
Tidying up ... @ Thu Jul 25 14:22:43 EST 2013 (1374726163687)

While this is a relatively simple example it does indicate the power which is available to you through Jmeter and BeanShell, if you can get it to work :-) Essentially anything which you can do in a java you can now do in Jmeter.

One Comment

  1. Veera says:

    Nice snippet, helps a lot for JMeters testers. Thanks a lot for putting it.

Leave a Reply

*

Contact Nixz Kerr