简体   繁体   中英

Build Executable Jar with Gradle for Gatling

The Problem

I've created a Scala and Gatling project with which I want to perform some load test. The idea is that I build an executable jar, which I then simply execute to run said load test.

I have so far no problems running the load test in my IDE. However, when I try to assemble it with:

gradle assemble

The jar is empty ie contains my utility classes from src/main/scala , but nothing from src/gatling/* (see below for my setup).

I've experimented with fat jars but that task gives me the error:

Execution failed for task ':fatJar'.
> Cannot expand ZIP 'D:\projects\load-test\build\classes\java\main' as it does not exist.

I have no idea why it expects java in the first place.

My Setup

The structure of my project is as follows:

load-test/
├── src/
│   ├── gatling/
│   │   ├── resources
│   │   └── scala
│   ├── main/
│   │   ├── resources
│   │   └── scala
│   └── test/
│       ├── resources
│       └── scala
├── ...
└── build.gradle

I've found out, that the Gatling plugin is very stubborn and it only includes the Gatling depencies in gatlingCompileClasspath . So In order to be able to write a loadtest, I need to have a gatling sourceset. The main/scala dir is used to implement some utility functions such as creating custom timestamps etc. test/scala tests those.

My build.gradle is as follows:

plugins {
    id "com.github.maiflai.scalatest" version "0.25"
    id 'io.gatling.gradle' version "3.4.0"
    id "scala"
}

apply plugin: "scala"
apply plugin: "com.github.maiflai.scalatest"

compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false

repositories {
    jcenter()
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}

sourceSets {
    gatling {
        scala.srcDirs = ["src/gatling/scala"]
        resources.srcDirs = ["src/gatling/resources"]
    }

    test {
        scala.srcDirs = ["src/test/scala"]
        resources.srcDirs = ["src/test/resources"]
    }

}

dependencies {
    testCompile "gradle.plugin.com.github.maiflai:gradle-scalatest:0.25"
    testCompile "org.scala-lang:scala-library:2.12.12"
    testCompile 'org.scalatest:scalatest_2.12:3.0.0'
    testRuntime 'org.pegdown:pegdown:1.4.2'
}


gatling {
    toolVersion = '3.4.0'
    scalaVersion = '2.12.12'
    simulations = {
        include "**/*Simulation.scala"
    }
    systemProperties = ['file.encoding': 'UTF-8']
}


task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Version': project.version,
                'Main-Class': 'io.gatling.app.Gatling'
    }
    setArchiveBaseName project.name + '-all'
    from { 
        configurations.gatlingRuntimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    } {
        exclude 'META-INF/MANIFEST.MF'
        exclude 'META-INF/*.SF'
        exclude 'META-INF/*.DSA'
        exclude 'META-INF/*.RSA'

    }
    with jar
}

After a lot of experimenting and hours of searching for hints in the documentation, this is the build gradle snippit that did the trick:

configurations {
    fatJarDependencies.extendsFrom gatling
}

task fatJar(type: Jar, dependsOn: [':gatlingClasses', ':processResources']) {
    manifest {
        attributes 'Implementation-Title': 'Preparing test',
                'Implementation-Version': '',
                'Main-Class': 'io.gatling.app.Gatling'
    }
    classifier = 'all'
    from files(sourceSets.main.output.classesDirs)
    from files(sourceSets.gatling.output)
    from { configurations.fatJarDependencies.collect { it.isDirectory() ? it : zipTree(it) } } {
        exclude 'META-INF/MANIFEST.MF'
        exclude 'META-INF/*.SF'
        exclude 'META-INF/*.DSA'
        exclude 'META-INF/*.RSA'
    }
    with jar
}

The key are the following:

1. configurations

fatJarDependencies.extendsFrom gatling

You need to extend gatling , because something like configurations.gatlingRuntimeClasspath.collect or configurations.gatling.collect does nothing in your fatJar task, even though those configurations exists (the latter at least). This is necessary in order to get the dependencies into your jar (gatling itself, scala and whatnot).

2. dependsOn

To be precise:

(type: Jar, dependsOn: [':gatlingClasses', ':processResources'])

Especially gatlingClasses , which I found through scanning the documentation page of the gatling gradle plugin . This adds the code under src/gatling/*

I can run a simulation by executing the following ( -DConfig is optional):

java -Dconfig.resource=myConf.conf -jar the-jar-i-created.jar -s org.comp.pckg.DemoSimulation

As pointed out by George Leung , it is also possible to generate the reports outside of the jar, if you start the comment as above (I mistakenly forgot that I added the option -nr ). In order to customize the folder I added a gatling.conf in src/gatling/resources with the following values:

gatling {
  core {
    directory {
      results = "/gatling/reports"
    }
  }
}

This overrides the default values that you can find here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM