Apache JMeter: Part 3 – Hacking JMeter to Customize the Listening Port on the Client

By default, there’s no way to set which port that the Apache JMeter client (master) listens on for the response of a test – and it always uses a random port instead! That means you have to open up your firewall on ports 45000-70000 to run it, which sucks. It’s easy enough to patch, though! Below, you can download my patched source to build your own copy:

JMeter 2.4 Patched Source

If you are using a newer version of JMeter than 2.4 (the latest, as of the time of writing this), directions follow for which files probably need to be updated. If you’ve never built JMeter or a Java application from source, you are also in luck, as all the gory details are here, too!

Updating the necessary files

In the code above, I’ve only changed a couple of small things, based on this useful post.

  1. Tell the listeners about the new port

    In src/core/org/apache/jmeter/engine/ConvertListeners.java, we need to let the listener know to respond on a given port. We use the JMeterUtils.getPropDefault method to get the port from the configuration, so we need to tell the code to use the JMeterUtils library. Go to the list of import statements at the top, and add this one to the list:


    import org.apache.jmeter.util.JMeterUtils

    Then we just need to add the port as an argument to the Listener that’s created. Replace this:


    RemoteSampleListener rtl = new RemoteSampleListenerImpl(item);

    with this:

    int callbackPort = JMeterUtils.getPropDefault("client.rmi.callbackport", 0);
    RemoteSampleListener rtl = new RemoteSampleListenerImpl(callbackPort, item);

  2. Change the Listener implementation to take the new port

    Now, all we have to do is update RemoteSampleListenerImpl to accept the new port. In src/core/org/apache/jmeter/samplers/RemoteSampleListenerImpl.java, find the RemoteSampleListenerImpl definition and replace:


    public RemoteSampleListenerImpl(Object listener) throws RemoteException {
    super();

    with:

    public RemoteSampleListenerImpl(int port, Object listener) throws RemoteException {
    super(port);

Once both of those are complete, you’re ready to compile! Once you have the finished product, you can specify the custom listening port with the brand new, super shiny client.rmi.callbackport option in jmeter.properties file (it’s not in there by default, so you’ll have to add it by hand) or from the command line:


jmeter -Jclient.rmi.callbackport=12345

Building JMeter from source

If you’re from the non-Java world, building JMeter may seem a bit weird. It’s not just as simple as the traditional apt-get or configure/make/make install. You’ll be doing all of the building with ant, with a heavy dose of manual labor along the way.

First thing first – you’re gonna need to install ant if it’s missing. If you’re using a Fedora/Red Hat/CentOS box (including Amazon Linux!) you can do:

yum install ant

You’ll also need some additional libraries for that, to add support for ReplaceRegExp:

yum install ant-apache-oro.noarch

We’re going to assume you have java jvm and hopefully the java development kit installed, otherwise go hunt down the latest version from the internet – use yum or go digging here.

Now, by default, you should just be able to go into the base directory for the package and run ant install, but for me, a bunch of things failed immediately. Here’s what I had to fix:

xstream 1.3.1 has wrong source location

I don’t know why it was released with a broken dependency location (and no forwarding), but I finally found xstream at nexus.codehaus.org

in build.properties replace

xstream.loc = http://repository.codehaus.org/com/thoughtworks/xstream/xstream/1.3.1

with

xstream.loc = https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream/1.3.1

Missing dependencies

I also found that you have to manually tell ant to go get any missing packages, which you do with this command:

ant download_jars

Can’t find javac

While building, ant died because it couldn’t find a suitable compiler. “But javac is installed!”, I said. I had to check where java thought it’s home was:


echo $JAVA_HOME
> /usr/lib/jvm/jre

Well, that’s not right!


locate javac
> /usr/lib/jvm/java-1.6.0-openjdk.x86_64/bin/

Ah ha! We’ll just re-set the environment variable! We use the directory above the bin/.


export JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk.x86_64/

Can’t find junit

Next, ant determined that it needed junit for unit testing and it wasn’t installed. This wasn’t handled by the previous download_jars installation, for reasons I don’t completely understand.


BUILD FAILED
/home/ec2-user/jakarta-jmeter-2.4/build.xml:911: Problem creating jar: /home/ec2-user/jakarta-jmeter-2.4/lib/junit/test.jar (No such file or directory) (and the archive is probably corrupt but I could not delete it)

So we go looking for where to get junit:


yum provides junit
> junit-3.8.2-6.5.3.amzn1.noarch : Java regression test package

It looks like amazon has built their own, but your system may tell you something different. We can still do:

yum install junit

Still can’t build (can’t create junit dir?)

Oh for eff’s sake. ant can’t even create the necessary directory for the junit tests.


mkdir ./lib/junit

Once all of that was done, I could finally run the command:

ant install

And all was well. Once you’ve had a successful build, you’ll need to chmod your newly-created binaries so that they can actually be run:


chmod a+x ./bin/jmeter
chmod a+x ./bin/jmeter-server

And then you should be ready to go! run ./bin/jmeter and the GUI should popup, letting you know that all is well!

Comments are closed.