Build executable JAR for Gatling load test

stackoverflower picture stackoverflower · Jan 12, 2015 · Viewed 14.1k times · Source

I am new to Gatling (2.1.2) and want to do a small prototype project to show to my colleagues.

According to the quick start page, there are several ways I can run a simulation with Gatling:

  1. decompress the Gatling bundle into a folder and drop my simulation files into user-files/simulations folder. bin/gatling.sh will compile and run the simulation files.
  2. use the gatling-maven-plugin maven plugin to execute the simulation.
  3. create a project with gatling-highcharts-maven-archetype, and run the Engine class.

and I found those problems

For 1, it is hard to add dependencies for simulation classes. I have to figure out what the jars are needed and drop them to the lib folder.

For 2, it requires maven to be installed.

For 3, it only runs from an IDE

I just want a simple executable JAR file with all the dependencies bundled together (my simulation, Gatling and third party), and run it from any machine (like EC2 instances).

Is there a way to achieve this?

Update 1:

I tried method 3, but moving all the project files from test folder to main, and used maven-assembly-plugin to build a jar with dependencies. When I tried to run the file, I got the following error:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at Engine$.delayedEndpoint$Engine$1(Engine.scala:7)
    at Engine$delayedInit$body.apply(Engine.scala:4)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at Engine$.main(Engine.scala:4)
    at Engine.main(Engine.scala)
Caused by: java.nio.file.FileSystemNotFoundException
    at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
    at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
    at java.nio.file.Paths.get(Paths.java:143)
    at io.gatling.core.util.PathHelper$.uri2path(PathHelper.scala:32)
    at IDEPathHelper$.<init>(IDEPathHelper.scala:7)
    at IDEPathHelper$.<clinit>(IDEPathHelper.scala)
    ... 11 more

I guess this is something to do with Gatling configuration, but don't know what has gone wrong.

Answer

voho picture voho · Apr 7, 2015

I tried to do something similar. I could not use Maven as well. I will try to remember how I did this.

1) I have configured maven-assembly-plugin to generate single JAR with dependencies like this:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
</plugin>

You need to ensure all required libraries (gatling, scala runtime, zinc compiler) are present on your resulting classpath.

2) Check the scope of your dependencies as Maven packs only classes defined with scope=compile by default. The most simple way is probably to use no test dependencies.

3) Create a launch script, e.g. launch.sh. It should contain something like this:

#!/bin/sh
USER_ARGS="-Dsomething=$1"
COMPILATION_CLASSPATH=`find -L ./target -maxdepth 1 -name "*.jar" -type f -exec printf :{} ';'`
JAVA_OPTS="-server -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms512M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:+AggressiveOpts -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false ${JAVA_OPTS}"
java $JAVA_OPTS $USER_ARGS -cp $COMPILATION_CLASSPATH io.gatling.app.Gatling -s your.simulation.FullClassName

To explain, I took gatling`s own launch script for inspiration. Note mainly the presence of target directory in classpath parameter definition.

4) Compile your compiled target directory and launch.sh to a single directory and distribute this (e.g. as archive). Then you can the scenarios by executing ./launch.sh.

I know this is not a standard solution, but it worked for me. Hopefully it will help you too. If you have any problems or tips to improve, please share with us.