# JMeter Docs — Full Content > Community-maintained documentation for Apache JMeter with improved navigation, search, and reading experience. This is an independent community resource and is not affiliated with, endorsed by, or sponsored by the Apache Software Foundation. For official documentation, visit jmeter.apache.org. Site: https://docs.jmeter.ai Pages: 151 Generated: 2026-09-08T15:00:29.575Z --- Title: MCP Server URL: https://docs.jmeter.ai/mcp/ --- Point Claude Code, Qwen Code, Cursor, or any MCP client at `https://docs.jmeter.ai/api/mcp` and your agent answers JMeter questions grounded in this documentation, with a source link for every answer. Free, no API key, no signup. **Endpoint:** `https://docs.jmeter.ai/api/mcp` (Streamable HTTP, stateless) **Fair use:** 120 requests/min per IP. Exceeding it returns HTTP 429 with a `Retry-After` header — well-behaved clients back off automatically. ## Available tools | Tool | Category | Description | | :--- | :--- | :--- | | [`search_jmeter_docs`](#search_jmeter_docs) | Knowledge | BM25 semantic search across documentation, user manual, and guides | | [`get_jmeter_page`](#get_jmeter_page) | Knowledge | Fetch full markdown text of any documentation page | | [`convert_curl_or_har_to_jmx`](#convert_curl_or_har_to_jmx) | Generator | Convert cURL commands and HAR files to valid JMX XML (GET, POST, QUERY, etc.) | | [`lint_jmx_snippet`](#lint_jmx_snippet) | Diagnostics | Scan JMX XML for anti-patterns (GUI listeners, BeanShell, missing timeouts) | | [`calculate_workload_model`](#calculate_workload_model) | Calculator | Little's Law concurrency, pacing, ramp-up schedules, and JVM heap sizing | | [`plan_distributed_testing`](#plan_distributed_testing) | Topology | Pinned RMI ports, `user.properties`, firewall rules, and Docker manifests | | [`tune_linux_os`](#tune_linux_os) | System | Linux `sysctl.conf`, `limits.conf`, systemd, and Docker tuning parameters | | [`lookup_jmeter_property`](#lookup_jmeter_property) | Reference | Search curated tuning properties with defaults and config locations | | [`get_jsr223_recipe`](#get_jsr223_recipe) | Code | Production Groovy recipes (JWT decoding, HMAC signing, dynamic headers) | | [`lookup_error_playbook`](#lookup_error_playbook) | Diagnostics | Instant remediation and OS/JVM fixes for common runtime exceptions | ### search_jmeter_docs Search the full documentation: user manual, topic guides, error playbooks, release notes, and interactive tool pages. Returns ranked pages with URLs and snippets. ```json { "query": "correlation dynamic values" } ``` ### get_jmeter_page Read one page in full markdown. Accepts the complete URL or a bare path like `topics/api-load-testing`. ```json { "url": "topics/api-load-testing" } ``` ### convert_curl_or_har_to_jmx Convert one or more cURL commands or HAR (HTTP Archive 1.2) JSON files into a schema-valid, ready-to-run Apache JMeter 5.6.3 `.jmx` XML test plan. Supports all standard HTTP verbs plus RFC 9838 `QUERY` method with body payloads, Bearer token extraction, and timeouts. ```json { "input": "curl -X QUERY https://api.example.com/v1/search -H 'Content-Type: application/json' -H 'Authorization: Bearer my-jwt' -d '{\"query\":\"loadtest\"}'", "threads": 50, "rampUpSeconds": 10, "parameterizeHost": true, "parameterizeAuth": true } ``` ### lint_jmx_snippet Validate a JMX XML snippet or test plan configuration against performance best practices and anti-patterns (active GUI listeners, legacy BeanShell, uncompiled JSR223, missing timeouts, zero ramp-up). ```json { "jmxContent": "" } ``` ### calculate_workload_model Compute required thread concurrency, pacing delays, ramp-up schedules, and JVM heap recommendations based on target RPS/TPS and SLA response times using Little's Law. ```json { "targetRps": 500, "avgResponseTimeMs": 250, "safetyFactor": 1.25 } ``` ### plan_distributed_testing Generate Master-Worker RMI port assignments, `user.properties`, CLI commands, firewall/security group rules, and Docker Compose manifests for distributed load testing. ```json { "controllerIp": "10.0.0.5", "workerIps": "10.0.1.10, 10.0.1.11, 10.0.1.12", "serverPort": 1099, "serverRmiLocalPort": 50000, "clientRmiLocalPort": 60000 } ``` ### tune_linux_os Generate Linux kernel (`sysctl.conf`), file descriptor (`limits.conf`), `systemd`, and Docker/K8s configurations tuned for high-concurrency JMeter load testing. ```json { "concurrency": 25000, "ramGb": 32, "trafficType": "http_churn", "targetDistro": "ubuntu_debian", "role": "injector" } ``` ### lookup_jmeter_property Search or inspect curated JMeter tuning properties (HTTP client pool, distributed testing RMI ports, InfluxDB backend listener, result formatting, engine settings). ```json { "query": "httpclient4.idletimeout" } ``` ### get_jsr223_recipe Fetch production-ready, performant Groovy scripts for JMeter JSR223 elements (JWT decoding & expiry, HMAC-SHA256 signing, dynamic header injection, nested JSON parsing, thread-safe CSV logging). ```json { "query": "jwt" } ``` ### lookup_error_playbook Get instant root cause analysis, OS/JVM tuning parameters, and step-by-step remediation for common JMeter and JVM exceptions (`BindException`, `SocketTimeoutException`, `OutOfMemoryError`, `NoHttpResponseException`, etc.). ```json { "query": "bindexception" } ``` ## Connect your agent ### Claude Code ```bash claude mcp add jmeter-docs https://docs.jmeter.ai/api/mcp --transport http --scope user ``` `--scope user` registers the server for all your projects, no matter which folder you run the command from. Restart Claude Code after adding it, then verify with `/mcp`. ### Qwen Code, Cursor, and other MCP clients Add this to your MCP configuration file: ```json { "mcpServers": { "jmeter-docs": { "url": "https://docs.jmeter.ai/api/mcp" } } } ``` ### Verify with curl ```bash curl -X POST https://docs.jmeter.ai/api/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "curl", "version": "1.0.0" } } }' ``` ## Why connect the docs? - **Grounded answers.** Responses come from the actual JMeter documentation, not from stale model memory. - **Verifiable sources.** Every result carries the docs.jmeter.ai URL so you can check the advice. - **Always current.** The index rebuilds when the docs sync from apache/jmeter, so agents see new releases automatically. - **Zero cost.** Hosted on the community docs site with no rate-limited API key to manage. Prefer a chat interface? Use the **Ask AI** button on any page, or start with the [JMeter for Beginners guide](/topics/jmeter-for-beginners/). --- Title: User's Manual: Getting Started URL: https://docs.jmeter.ai/getting-started/get-started/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 1. Getting Started ### 1.0 Overview When using JMeter you will usually follow this process: #### 1.0.1 Test plan building To do that, you will [run JMeter in GUI Mode.](/getting-started/get-started/#running) Then you can either choose to record the application from a browser, or native application. You can use for that the menu **File → Templates... → Recording** Note you can also manually build your plan. Ensure you read this [documentation](/user-manual/test-plan/) to understand major concepts. You will also debug it using one of these options: - **Run → Start no pauses** - **Run → Start** - **Validate** on [Thread Group](/user-manual/component-reference/#Thread_Group) and [View Results Tree](/user-manual/component-reference/#View_Results_Tree) renderers or Testers (CSS/JQUERY, JSON, Regexp, XPath). Ensure you follow [best-practices](/user-manual/best-practices/) when building your Test Plan. #### 1.0.2 Load Test running Once your Test Plan is ready, you can start your Load Test. The first step is to configure the injectors that will run JMeter, this as for any other Load Testing tool includes: - Correct machine sizing in terms of CPU, memory and network - OS Tuning - Java setup: Ensure you install the latest version of Java supported by JMeter - **Increase the Java Heap size**. By default JMeter runs with a heap of 1 GB, this might not be enough for your test and depends on your test plan and number of threads you want to run Once everything is ready, you will use CLI mode (Command-line mode previously called [Non-GUI mode](#non_gui)) to run it for the Load Test. :::note Don't run load test using GUI mode ! ::: Using CLI mode, you can generate a CSV (or XML) file containing results and have JMeter [generate an HTML report](/user-manual/generating-dashboard/) at end of Load Test. JMeter will by default provide a summary of load test while it's running. You can also have [real-time results](/user-manual/realtime-results/) during your test using [Backend Listener](/user-manual/component-reference/#Backend_Listener). #### 1.0.3 Load Test analysis Once your Load Test is finished, you can use the HTML report to analyze your load test. ### 1.0.4 Let's start The easiest way to begin using JMeter is to first [download the latest production release](http://jmeter.apache.org/download_jmeter.cgi) and install it. The release contains all of the files you need to build and run most types of tests, e.g. Web (HTTP/HTTPS), FTP, JDBC, LDAP, Java, JUnit and more. If you want to perform JDBC testing, then you will, of course, need the appropriate JDBC driver from your vendor. JMeter does not come with any JDBC drivers. JMeter includes the JMS API jar, but does not include a JMS client implementation. If you want to run JMS tests, you will need to download the appropriate jars from the JMS provider. :::note See the [JMeter Classpath](#classpath) section for details on installing additional jars. ::: Next, start JMeter and go through the [Building a Test Plan](/user-manual/build-test-plan/) section of the User Guide to familiarize yourself with JMeter basics (for example, adding and removing elements). Finally, go through the appropriate section on how to build a specific type of Test Plan. For example, if you are interested in testing a Web application, then see the section [Building a Web Test Plan](/user-manual/build-web-test-plan/). The other specific Test Plan sections are: - [Advanced Web Test Plan](/user-manual/build-adv-web-test-plan/) - [JDBC](/user-manual/build-db-test-plan/) - [FTP](/user-manual/build-ftp-test-plan/) - [JMS Point-to-Point](/user-manual/build-jms-point-to-point-test-plan/) - [JMS Topic](/user-manual/build-jms-topic-test-plan/) - [LDAP](/user-manual/build-ldap-test-plan/) - [LDAP Extended](/user-manual/build-ldapext-test-plan/) - [WebServices (SOAP)](/user-manual/build-ws-test-plan/) - [Building Test Plan programmatically](/user-manual/build-programmatic-test-plan/) Once you are comfortable with building and running JMeter Test Plans, you can look into the various configuration elements (timers, listeners, assertions, and others) which give you more control over your Test Plans. ## 1.1 Requirements JMeter requires that your computing environment meets some minimum requirements. ### 1.1.1 Java Version :::note JMeter is compatible with Java 17 or higher. We highly advise you to install latest minor version of your major version for security and performance reasons. ::: Because JMeter uses only standard Java APIs, please do not file bug reports if your JRE fails to run JMeter because of JRE implementation issues. :::note Although you can use a JRE, it is better to install a JDK as for recording of HTTPS, JMeter needs `keytool` utility from JDK. ::: ### 1.1.2 Operating Systems JMeter is a 100% Java application and should run correctly on any system that has a compliant Java implementation. Operating systems tested with JMeter can be viewed on [this page](https://cwiki.apache.org/confluence/display/JMETER/JMeterAndOperatingSystemsTested) on JMeter wiki. Even if your OS is not listed on the wiki page, JMeter should run on it provided that the JVM is compliant. ## 1.2 Optional If you plan on doing JMeter development, then you will need one or more optional packages listed below. ### 1.2.1 Java Compiler If you want to build the JMeter source or develop JMeter plugins, then you will need a fully compliant JDK 8 or higher. ### 1.2.2 SAX XML Parser JMeter comes with Apache's [Xerces XML parser](http://xml.apache.org/). You have the option of telling JMeter to use a different XML parser. To do so, include the classes for the third-party parser in JMeter's [classpath](#classpath), and update the [jmeter.properties](#configuring_jmeter) file with the full classname of the parser implementation. ### 1.2.3 Email Support JMeter has extensive Email capabilities. It can send email based on test results, and has a POP3(S)/IMAP(S) sampler. It also has an SMTP(S) sampler. ### 1.2.4 SSL Encryption To test a web server using SSL encryption (HTTPS), JMeter requires that an implementation of SSL be provided, as is the case with Sun Java 1.4 and above. If your version of Java does not include SSL support, then it is possible to add an external implementation. Include the necessary encryption packages in JMeter's [classpath](#classpath). Also, update [`system.properties`](#configuring_jmeter) to register the SSL Provider. JMeter HTTP defaults to protocol level TLS. This can be changed by editing the JMeter property `https.default.protocol` in `jmeter.properties` or `user.properties`. The JMeter HTTP samplers are configured to accept all certificates, whether trusted or not, regardless of validity periods, etc. This is to allow the maximum flexibility in testing servers. If the server requires a client certificate, this can be provided. There is also the [SSL Manager](/user-manual/component-reference/#SSL_Manager), for greater control of certificates. :::note The JMeter proxy server (see below) supports recording HTTPS (SSL) ::: The SMTP sampler can optionally use a local trust store or trust all certificates. ### 1.2.5 JDBC Driver You will need to add your database vendor's JDBC driver to the [classpath](#classpath) if you want to do JDBC testing. Make sure the file is a jar file, not a zip. ### 1.2.6 JMS client JMeter now includes the JMS API from Apache Geronimo, so you just need to add the appropriate JMS Client implementation jar(s) from the JMS provider. Please refer to their documentation for details. There may also be some information on the [JMeter Wiki](https://cwiki.apache.org/confluence/display/JMETER/Home). ### 1.2.7 Libraries for ActiveMQ JMS You will need to add the jar `activemq-all-X.X.X.jar` to your classpath, e.g. by storing it in the `lib/` directory. See [ActiveMQ initial configuration page](http://activemq.apache.org/initial-configuration.html) for details. :::note See the [JMeter Classpath](#classpath) section for more details on installing additional jars. ::: ## 1.3 Installation We recommend that most users run the [latest release](http://jmeter.apache.org/download_jmeter.cgi). To install a release build, simply unzip the zip/tar file into the directory where you want JMeter to be installed. Provided that you have a JRE/JDK correctly installed and the `JAVA_HOME` environment variable set, there is nothing more for you to do. :::note There can be problems (especially with client-server mode) if the directory path contains any spaces. ::: The installation directory structure should look something like this (where `X.Y` is version number): ``` apache-jmeter-X.Y apache-jmeter-X.Y/bin apache-jmeter-X.Y/docs apache-jmeter-X.Y/extras apache-jmeter-X.Y/lib/ apache-jmeter-X.Y/lib/ext apache-jmeter-X.Y/lib/junit apache-jmeter-X.Y/licenses apache-jmeter-X.Y/docs ``` You can rename the parent directory (i.e. `apache-jmeter-X.Y`) if you want, but do not change any of the sub-directory names. ## 1.4 Running JMeter To run JMeter, run the `jmeter.bat` (for Windows) or `jmeter` (for Unix) file. These files are found in the `bin` directory. After a short time, the JMeter GUI should appear. :::note GUI mode should only be used for creating the test script, CLI mode (NON GUI) must be used for load testing ::: There are some additional scripts in the `bin` directory that you may find useful. Windows script files (the .CMD files require Win2K or later): **`jmeter.bat`** : run JMeter (in GUI mode by default) **`jmeterw.cmd`** : run JMeter without the windows shell console (in GUI mode by default) **`jmeter-n.cmd`** : drop a JMX file on this to run a CLI mode test **`jmeter-n-r.cmd`** : drop a JMX file on this to run a CLI mode test remotely **`jmeter-t.cmd`** : drop a JMX file on this to load it in GUI mode **`jmeter-server.bat`** : start JMeter in server mode **`mirror-server.cmd`** : runs the JMeter Mirror Server in CLI mode **`shutdown.cmd`** : Run the Shutdown client to stop a CLI mode instance gracefully **`stoptest.cmd`** : Run the Shutdown client to stop a CLI mode instance abruptly :::note The special name `LAST` can be used with `jmeter-n.cmd`, `jmeter-t.cmd` and `jmeter-n-r.cmd` and means the last test plan that was run interactively. ::: There are a few environment variables, that can be used to customize the JVM settings for JMeter. An easy way to set those is by creating a file named `setenv.bat` in the `bin` directory. Such a file could look like: ``` rem This is the content of bin\setenv.bat, rem it will be called by bin\jmeter.bat set JVM_ARGS=-Xms1024m -Xmx1024m -Dpropname=value ``` The `JVM_ARGS` can be used to override JVM settings in the `jmeter.bat` script and will get set when starting JMeter, e.g.: ``` jmeter -t test.jmx … ``` The following environment variables can be defined: **`DDRAW`** : JVM options to influence usage of direct draw, e.g. `-Dsun.java2d.ddscale=true`. Default is empty. **`GC_ALGO`** : JVM garbage collector options. Defaults to `-XX:+UseG1GC -XX:MaxGCPauseMillis=250 -XX:G1ReservePercent=20` **`HEAP`** : JVM memory settings used when starting JMeter. Defaults to `-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m` **`JMETER_BIN`** : JMeter bin directory (must end in `\`). Value will have been guessed, when `setenv.bat` is called. **`JMETER_COMPLETE_ARGS`** : If set indicates, that `JVM_ARGS` and `JMETER_OPTS` are to be used, only. All other options like `HEAP` and `GC_ALGO` will be ignored. Default is empty. **`JMETER_HOME`** : installation directory. Will be guessed from location of `jmeter.bat` **`JMETER_LANGUAGE`** : Java runtime options to specify used language. Defaults to: `-Duser.language="en" -Duser.region="EN"` **`JM_LAUNCH`** : Name of the java executable, like `java.exe` (default) or `javaw.exe` **`JVM_ARGS`** : Java options to be used when starting JMeter. These will be added last to the java command. Default is empty Un*x script files; should work on most Linux/Unix systems: **`jmeter`** : run JMeter (in GUI mode by default). Defines some JVM settings which may not work for all JVMs. **`jmeter-server`** : start JMeter in server mode (calls jmeter script with appropriate parameters) **`jmeter.sh`** : very basic JMeter script (You may need to adapt JVM options like memory settings). **`mirror-server.sh`** : runs the JMeter Mirror Server in CLI mode **`shutdown.sh`** : Run the Shutdown client to stop a CLI mode instance gracefully **`stoptest.sh`** : Run the Shutdown client to stop a CLI mode instance abruptly It may be necessary to set a few environment variables to configure the JVM used by JMeter. Those variables can be either set directly in the shell starting the `jmeter` script. For example setting the variable `JVM_ARGS` will override most pre-defined settings, for example ``` JVM_ARGS="-Xms1024m -Xmx1024m" jmeter -t test.jmx [etc.] ``` will override the HEAP settings in the script. To set those variables permanently, you can place them in a file called `setenv.sh` in the `bin` directory. This file will be sourced when running JMeter by calling the `jmeter` script. An example for `bin/setenv.sh` could look like: ```properties # This is the file bin/setenv.sh, # it will be sourced in by bin/jmeter # Use a bigger heap, but a smaller metaspace, than the default export HEAP="-Xms1G -Xmx1G -XX:MaxMetaspaceSize=192m" # Try to guess the locale from the OS. The space as value is on purpose! export JMETER_LANGUAGE=" " ``` The following environment variables can be defined: **`GC_ALGO`** : Java runtime options to specify JVM garbage collection algorithm. Defaults to `-XX:+UseG1GC -XX:MaxGCPauseMillis=250 -XX:G1ReservePercent=20` **`HEAP`** : Java runtime options for memory management used when JMeter is started. Defaults to `-Xms1g -Xmx1g -X:MaxMetaspaceSize=256m` **`JAVA_HOME`** : Must point at your Java Development Kit installation. Required to run the with the "`debug`" argument. On some OSes it JMeter will try its best to guess the location of the JVM. **`JMETER_COMPLETE_ARGS`** : If set indicates, that `JVM_ARGS` and `JMETER_OPTS` are to be used, only. All other options like `HEAP` and `GC_ALGO` will be ignored. Default is empty. **`JMETER_HOME`** : May point to your JMeter install dir. If empty it will be set relative to the `jmeter` script. **`JMETER_LANGUAGE`** : Java runtime options to specify used language. Defaults to `-Duser.language=en -Duser.region=EN` **`JMETER_OPTS`** : Java runtime options used when JMeter is started. Special options for operating systems might be added by JMeter. **`JRE_HOME`** : Must point at your Java Runtime installation. Defaults to `JAVA_HOME` if empty. If `JRE_HOME` and `JAVA_HOME` are both empty, JMeter will try to guess `JAVA_HOME`. If `JRE_HOME` and `JAVA_HOME` are both set, `JAVA_HOME` is used. **`JVM_ARGS`** : Java options to be used when starting JMeter. These will be added before `JMETER_OPTS` and after the other JVM options. Default is empty ### 1.4.1 JMeter's Classpath JMeter automatically finds classes from jars in the following directories: **`JMETER_HOME/lib`** : used for utility jars **`JMETER_HOME/lib/ext`** : used for JMeter components and plugins If you have developed new JMeter components, then you should jar them and copy the jar into JMeter's `lib/ext` directory. JMeter will automatically find JMeter components in any jars found here. Do not use `lib/ext` for utility jars or dependency jars used by the plugins; it is only intended for JMeter components and plugins. If you don't want to put JMeter plugin jars in the `lib/ext` directory, then define the property `search_paths` in `jmeter.properties`. Utility and dependency jars (libraries etc) can be placed in the `lib` directory. If you don't want to put such jars in the `lib` directory, then define the property `user.classpath` or `plugin_dependency_paths` in `jmeter.properties`. See below for an explanation of the differences. Other jars (such as JDBC, JMS implementations and any other support libraries needed by the JMeter code) should be placed in the `lib` directory - not the `lib/ext` directory, or added to `user.classpath`. :::note JMeter will only find `.jar` files, not `.zip`. ::: You can also install utility Jar files in `$JAVA_HOME/jre/lib/ext`, or you can set the property `user.classpath` in `jmeter.properties` Note that setting the `CLASSPATH` environment variable will have no effect. This is because JMeter is started with "`java -jar`", and the java command silently ignores the `CLASSPATH` variable, and the `-classpath`/`-cp` options when `-jar` is used. :::note This occurs with all Java programs, not just JMeter. ::: ### 1.4.2 Create Test Plan from Template You have the ability to create a new Test Plan from existing template. To do so you use the menu **File → Templates…** or Templates icon: ![Templates icon item](/images/screenshots/template_menu.png) _Templates icon item_ A popup appears, you can then choose a template among the list: ![Templates popup](/images/screenshots/template_wizard.png) _Templates popup_ Some templates may need parameters input from the user. For theses ones, after a click on the create button, a new window will appear as follow : ![Parameters window](/images/screenshots/templates/template_parameters.png) _Parameters window_ When you are done with parameters, click on the `Validate` button and the template will be created. A documentation for each template explains what to do once test plan is created from template. :::note You can create your own templates following documentation [here](/../creating-templates/) ::: ### 1.4.3 Using JMeter behind a proxy If you are testing from behind a firewall/proxy server, you may need to provide JMeter with the firewall/proxy server hostname and port number. To do so, run the `jmeter[.bat]` file from a command line with the following parameters: **`-E`** : [proxy scheme to use - optional - for non-http] **`-H`** : [proxy server hostname or ip address] **`-P`** : [proxy server port] **`-N`** : [nonproxy hosts] (e.g. `*.apache.org|localhost`) **`-u`** : [username for proxy authentication - if required] **`-a`** : [password for proxy authentication - if required] **Example**: ``` jmeter -E https -H my.proxy.server -P 8000 -u username -a password -N localhost ``` You can also use `--proxyScheme`, `--proxyHost`, `--proxyPort`, `--username`, and `--password` as parameter names :::note Parameters provided on a command-line may be visible to other users on the system. ::: If the proxy scheme is provided, then JMeter sets the following System properties: - `http.proxyScheme` If the proxy host and port are provided, then JMeter sets the following System properties: - `http.proxyHost` - `http.proxyPort` - `https.proxyHost` - `https.proxyPort` The user and password used for a proxy can be given by the System properties `http.proxyUser` and `http.proxyUser`. They will get overridden by the above arguments or values set in the HTTP Samplers. If a nonproxy host list is provided, then JMeter sets the following System properties: - `http.nonProxyHosts` - `https.nonProxyHosts` So if you don't wish to set both http and https proxies, you can define the relevant properties in `system.properties` instead of using the command-line parameters. Proxy Settings can also be defined in a Test Plan, using either the [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) configuration or the [HTTP Request](/user-manual/component-reference/#HTTP_Request) sampler elements. :::note JMeter also has its own in-built Proxy Server, the [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder). This is only used for recording HTTP or HTTPS browser sessions. This is not to be confused with the proxy settings described above, which are used when JMeter makes HTTP or HTTPS requests itself. ::: ### 1.4.4 CLI Mode (Command Line mode was called NON GUI mode) For load testing, you must run JMeter in this mode (Without the GUI) to get the optimal results from it. To do so, use the following command options: **`-n`** : This specifies JMeter is to run in cli mode **`-t`** : [name of JMX file that contains the Test Plan]. **`-l`** : [name of JTL file to log sample results to]. **`-j`** : [name of JMeter run log file]. **`-r`** : Run the test in the servers specified by the JMeter property "`remote_hosts`" **`-R`** : [list of remote servers] Run the test in the specified remote servers **`-g`** : [path to CSV file] generate report dashboard only **`-e`** : generate report dashboard after load test **`-o`** : output folder where to generate the report dashboard after load test. Folder must not exist or be empty The script also lets you specify the optional firewall/proxy server information: **`-H`** : [proxy server hostname or ip address] **`-P`** : [proxy server port] **Example** ``` jmeter -n -t my_test.jmx -l log.jtl -H my.proxy.server -P 8000 ``` If the property `jmeterengine.stopfail.system.exit` is set to `true` (default is `false`), then JMeter will invoke `System.exit(1)` if it cannot stop all threads. Normally this is not necessary. ### 1.4.5 Server Mode For [distributed testing](/user-manual/remote-test/), run JMeter in server mode on the remote node(s), and then control the server(s) from the GUI. You can also use CLI mode to run remote tests. To start the server(s), run `jmeter-server[.bat]` on each server host. The script also lets you specify the optional firewall/proxy server information: **`-H`** : [proxy server hostname or ip address] **`-P`** : [proxy server port] **Example**: ``` jmeter-server -H my.proxy.server -P 8000 ``` If you want the server to exit after a single test has been run, then define the JMeter property `server.exitaftertest=true`. To run the test from the client in CLI mode, use the following command: ``` jmeter -n -t testplan.jmx -r [-Gprop=val] [-Gglobal.properties] [-X] ``` where: **`-G`** : is used to define JMeter properties to be set in the servers **`-X`** : means exit the servers at the end of the test **`-Rserver1,server2`** : can be used instead of `-r` to provide a list of servers to start. Overrides `remote_hosts`, but does not define the property. If the property `jmeterengine.remote.system.exit` is set to `true` (default is `false`), then JMeter will invoke `System.exit(0)` after stopping RMI at the end of a test. Normally this is not necessary. ### 1.4.6 Overriding Properties Via The Command Line Java system properties and JMeter properties can be overridden directly on the command lin (instead of modifying `jmeter.properties`). To do so, use the following options: **`-D[prop_name]=`** : defines a java system property value. **`-J[prop_name]=`** : defines a local JMeter property. **`-q[propertyfile]`** : additional JMeter property file **`-G[prop_name]=`** : defines a JMeter property to be sent to all remote servers. **`-G[propertyfile]`** : defines a file containing JMeter properties to be sent to all remote servers. **`-L[category]=[priority]`** : overrides a logging setting, setting a particular category to the given priority level. The `-L` flag can also be used without the category name to set the root logging level. **Examples**: ``` jmeter -Duser.dir=/home/mstover/jmeter_stuff \ -Jremote_hosts=127.0.0.1 -Ljmeter.engine=DEBUG ``` ``` jmeter -LDEBUG ``` :::note The command line properties are processed early in startup, but after the logging system has been set up. ::: ### 1.4.7 Logging and error messages :::note Since 3.2, JMeter logging is not configured through properties file(s) such as `jmeter.properties` any more, but it is configured through a [Apache Log4j 2](http://logging.apache.org/log4j/2.x/) configuration file (`log4j2.xml` in the directory from which JMeter was launched, by default) instead. Also, every code including JMeter and plugins MUST use [SLF4J](https://www.slf4j.org/) library to leave logs since 3.2. ::: Here is an example `log4j2.xml` file which defines two log appenders and loggers for each category. ``` [object Object] ``` So, if you want to change the log level for `org.apache.http` category to debug level for instance, you can simply add (or uncomment) the following logger element in `log4j2.xml` file before launching JMeter. ``` [object Object] ``` For more detail on how to configure `log4j2.xml` file, please see [Apache Log4j 2 Configuration](http://logging.apache.org/log4j/2.x/manual/configuration.html) page. Log level for specific categories or root logger can be overridden directly on the command line (instead of modifying `log4j2.xml`) as well. To do so, use the following options: **`-L[category]=[priority]`** : Overrides a logging setting, setting a particular category to the given priority level. Since 3.2, it is recommended to use a full category name (e.g, `org.apache.jmeter` or `com.example.foo`), but if the category name starts with either `jmeter` or `jorphan`, `org.apache.` will be prepended internally to the category name input to construct a full category name (i.e, `org.apache.jmeter` or `org.apache.jorphan`) for backward compatibility. **Examples**: ``` jmeter -Ljmeter.engine=DEBUG ``` ``` jmeter -Lorg.apache.jmeter.engine=DEBUG ``` ``` jmeter -Lcom.example.foo=DEBUG ``` ``` jmeter -LDEBUG ``` **Differences in Logging : Old vs New Practices**: As JMeter uses SLF4J as logging API and Apache Log4j 2 as a logging framework since 3.2, not every log level used before 3.2 can match exactly with one of the new available log levels provided by SLF4J/Log4j2. Therefore, please keep the following differences and new suggested practices in mind if you need to migrate any existing logging configurations and logging code. | Category | Old Practices Before 3.2 | New Practices Since 3.2 | | --- | --- | --- | | Logger Reference | Logger reference through `LoggingManager`: ``` LoggingManager.getLoggerFor(String category); LoggingManager.getLoggerForClass(); ``` | Use SLF4J API with either category or explicit class: ``` LoggerFactory.getLogger(String category); LoggerFactory.getLogger(Foo.class); ``` | | Log Levels in Configuration or Command Line Arguments | Old Log Levels: - `DEBUG` - `INFO` - `WARN` - `ERROR` - `FATAL_ERROR` - `NONE` | Mapping to New Levels through SLF4J/Log4j2: - `DEBUG` - `INFO` - `WARN` - `ERROR` - `ERROR` - `OFF` :::note Since `FATAL_ERROR` is not supported by SLF4J API, it is treated as `ERROR` instead for existing code not to break. There is also the `FATAL` log level option. ::: :::note `TRACE` level, which is less specific than `DEBUG`, is supported additionally since 3.2. Look up SLF4J or Apache Log4J 2 documentations for details. ::: | :::note JMeter does not generally use pop-up dialog boxes for errors, as these would interfere with running tests. Nor does it report any error for a mis-spelt variable or function; instead the reference is just used as is. See [Functions and Variables for more information](/user-manual/functions/). ::: If JMeter detects an error during a test, a message will be written to the log file. The log file name is defined in the `log4j2.xml` file (or using the -j option, see below). It defaults to `jmeter.log`, and will be found in the directory from which JMeter was launched. The menu **Options → Log Viewer** displays the log file in a bottom pane on main JMeter window. In the GUI mode, the number of error/fatal messages logged in the log file is displayed at top-right. ![Error/fatal counter](/images/screenshots/log_errors_counter.png) _Error/fatal counter_ The command-line option `-j jmeterlogfile` allow to process after the initial properties file is read, and before any further properties are processed. It therefore allows the default of `jmeter.log` to be overridden. The jmeter scripts that take a test plan name as a parameter (e.g. `jmeter-n.cmd`) have been updated to define the log file using the test plan name, e.g. for the test plan `Test27.jmx` the log file is set to `Test27.log`. When running on Windows, the file may appear as just **jmeter** unless you have set Windows to show file extensions. [Which you should do anyway, to make it easier to detect viruses and other nasties that pretend to be text files …] As well as recording errors, the `jmeter.log` file records some information about the test run. For example: ``` 2017-03-01 12:19:20,314 INFO o.a.j.JMeter: Version 3.2.20170301 2017-03-01 12:19:45,314 INFO o.a.j.g.a.Load: Loading file: c:\mytestfiles\BSH.jmx 2017-03-01 12:19:52,328 INFO o.a.j.e.StandardJMeterEngine: Running the test! 2017-03-01 12:19:52,384 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group BSH. Ramp up = 1. 2017-03-01 12:19:52,485 INFO o.a.j.e.StandardJMeterEngine: Continue on error 2017-03-01 12:19:52,589 INFO o.a.j.t.JMeterThread: Thread BSH1-1 started 2017-03-01 12:19:52,590 INFO o.a.j.t.JMeterThread: Thread BSH1-1 is done 2017-03-01 12:19:52,691 INFO o.a.j.e.StandardJMeterEngine: Test has ended ``` The log file can be helpful in determining the cause of an error, as JMeter does not interrupt a test to display an error dialogue. ### 1.4.8 Full list of command-line options Invoking JMeter as "`jmeter -?`" will print a list of all the command-line options. These are shown below. ``` --? print command line options and exit -h, --help print usage information and exit -v, --version print the version information and exit -p, --propfile <argument> the jmeter property file to use -q, --addprop <argument> additional JMeter property file(s) -t, --testfile <argument> the jmeter test(.jmx) file to run -l, --logfile <argument> the file to log samples to -i, --jmeterlogconf <argument> jmeter logging configuration file (log4j2.xml) -j, --jmeterlogfile <argument> jmeter run log file (jmeter.log) -n, --nongui run JMeter in nongui mode -s, --server run the JMeter server -H, --proxyHost <argument> Set a proxy server for JMeter to use -P, --proxyPort <argument> Set proxy server port for JMeter to use -N, --nonProxyHosts <argument> Set nonproxy host list (e.g. *.apache.org|localhost) -u, --username <argument> Set username for proxy server that JMeter is to use -a, --password <argument> Set password for proxy server that JMeter is to use -J, --jmeterproperty <argument>=<value> Define additional JMeter properties -G, --globalproperty <argument>=<value> Define Global properties (sent to servers) e.g. -Gport=123 or -Gglobal.properties -D, --systemproperty <argument>=<value> Define additional system properties -S, --systemPropertyFile <argument> additional system property file(s) -f, --forceDeleteResultFile force delete existing results files and web report folder if present before starting the test -L, --loglevel <argument>=<value> [category=]level e.g. jorphan=INFO, jmeter.util=DEBUG or com.example.foo=WARN -r, --runremote Start remote servers (as defined in remote_hosts) -R, --remotestart <argument> Start these remote servers (overrides remote_hosts) -d, --homedir <argument> the jmeter home directory to use -X, --remoteexit Exit the remote servers at end of test (CLI mode) -g, --reportonly <argument> generate report dashboard only, from a test results file -e, --reportatendofloadtests generate report dashboard after load test -o, --reportoutputfolder <argument> output folder for report dashboard ``` Note: the JMeter log file name is formatted as a SimpleDateFormat (applied to the current date) if it contains paired single-quotes, .e.g. '`jmeter_'yyyyMMddHHmmss'.log`' If the special name `LAST` is used for the `-t`, `-j` or `-l` flags, then JMeter takes that to mean the last test plan that was run in interactive mode. ### 1.4.9 CLI mode shutdown Prior to version 2.5.1, JMeter invoked `System.exit()` when a CLI mode test completed. This caused problems for applications that invoke JMeter directly, so JMeter no longer invokes `System.exit()` for a normal test completion. [Some fatal errors may still invoke `System.exit()`] JMeter will exit all the non-daemon threads it starts, but it is possible that some non-daemon threads may still remain; these will prevent the JVM from exiting. To detect this situation, JMeter starts a new daemon thread just before it exits. This daemon thread waits a short while; if it returns from the wait, then clearly the JVM has not been able to exit, and the thread prints a message to say why. The property `jmeter.exit.check.pause` can be used to configure the delay before printing non-daemon threads. If set to `0` (default value), then JMeter does not print non-terminated threads at the end of the test. ## 1.5 Configuring JMeter If you wish to modify the properties with which JMeter runs you need to either modify the `user.properties` in the `/bin` directory or create your own copy of the `jmeter.properties` and specify it in the command line. :::note Note: You can define additional JMeter properties in the file defined by the JMeter property `user.properties` which has the default value `user.properties`. The file will be automatically loaded if it is found in the current directory or if it is found in the JMeter bin directory. Similarly, `system.properties` is used to update system properties. ::: | Name | Required | Description | |------|----------|-------------| | ssl.provider | No | You can specify the class for your SSL implementation if you don't want to use the built-in Java implementation. | | xml.parser | No | You can specify an implementation as your XML parser. | | remote_hosts | No | Comma-delimited list of remote JMeter hosts (or `host:port` if required). If you are running JMeter in a distributed environment, list the machines where you have JMeter remote servers running. This will allow you to control those servers from this machine's GUI | | not_in_menu | No | A list of components you do not want to see in JMeter's menus. As JMeter has more and more components added, you may wish to customize your JMeter to show only those components you are interested in. You may list their classname or their class label (the string that appears in JMeter's UI) here, and they will no longer appear in the menus. | | search_paths | No | List of paths (separated by `;`) that JMeter will search for JMeter plugin classes, for example additional samplers. A path item can either be a jar file or a directory. Any jar file in such a directory will be automatically included in `search_paths`, jar files in sub directories are ignored. The given value is in addition to any jars found in the `lib/ext` directory. | | user.classpath | No | List of paths that JMeter will search for utility and plugin dependency classes. Use your platform path separator to separate multiple paths. A path item can either be a jar file or a directory. Any jar file in such a directory will be automatically included in `user.classpath`, jar files in sub directories are ignored. The given value is in addition to any jars found in the lib directory. All entries will be added to the class path of the system class loader and also to the path of the JMeter internal loader. | | plugin_dependency_paths | No | List of paths (separated by `;`) that JMeter will search for utility and plugin dependency classes. A path item can either be a jar file or a directory. Any jar file in such a directory will be automatically included in `plugin_dependency_paths`, jar files in sub directories are ignored. The given value is in addition to any jars found in the `lib` directory or given by the `user.classpath` property. All entries will be added to the path of the JMeter internal loader only. For plugin dependencies using `plugin_dependency_paths` should be preferred over `user.classpath`. | | user.properties | No | Name of file containing additional JMeter properties. These are added after the initial property file, but before the `-q` and `-J` options are processed. | | system.properties | No | Name of file containing additional system properties. These are added before the `-S` and `-D` options are processed. | The command line options and properties files are processed in the following order: 1. `-p propfile` 2. `jmeter.properties` (or the file from the `-p` option) is then loaded 3. `-j logfile` 4. Logging is initialised 5. `user.properties` is loaded 6. `system.properties` is loaded 7. all other command-line options are processed **See also the comments in the `jmeter.properties`, `user.properties` and `system.properties` files for further information on other settings you can change.** {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Build your first test plan with the [Building a Test Plan](/user-manual/build-test-plan/) guide. - [Best Practices](/user-manual/best-practices/) - essential guidelines before running load tests - [Boss](/user-manual/boss/) - how to scope a performance testing effort - If JMeter fails to start, verify you have Java 17+ installed (`java -version`) - Use View Results Tree in Validate mode to debug before running full tests {/* CUSTOM-FOOTER:END */} --- Title: JMeter Error Playbooks URL: https://docs.jmeter.ai/topics/errors/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JMeter Error Playbooks A grounded, symptom-based directory of dedicated playbooks for every error, exception, and bottleneck encountered when running Apache JMeter. Each playbook follows an identical structure: 1. **Symptom & Exact Signature** - Real stack traces and messages from `jmeter.log`, View Results Tree, and JTL outputs. 2. **Quick Diagnosis (TL;DR)** - Direct 2-sentence summary for immediate triage. 3. **Common Causes** - Root cause breakdown explaining underlying network, JVM, or protocol behavior. 4. **Ordered Fixes** - Practical, copy-pasteable configuration snippets, CLI commands, and properties. 5. **Interactive Tools & Related Guides** - Direct bridges to calculators, cheat sheets, and manual sections. :::tip[Standard Triage Protocol] Before running large-scale tests, always debug with **1 thread and 1 loop** in GUI mode with **View Results Tree** enabled. Once the script succeeds cleanly, disable all visual listeners and run in CLI mode ([best practices](/user-manual/best-practices/)). ::: --- ## 1. Network, Connection & TLS Errors | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | `java.net.ConnectException` | Connection refused or TCP handshake timeout | [ConnectException](/topics/errors/connect-exception/) | | `java.net.SocketTimeoutException` | Server took too long to return data (`Read timed out`) | [SocketTimeoutException](/topics/errors/socket-timeout-exception/) | | `org.apache.http.NoHttpResponseException` | Server closed idle persistent Keep-Alive socket | [NoHttpResponseException](/topics/errors/no-http-response-exception/) | | `java.io.EOFException` | Premature EOF, unexpected end of file from server | [Premature EOF / Connection Aborted](/topics/errors/premature-eof-connection-abort/) | | `java.net.UnknownHostException` | Load injector DNS resolution failed | [UnknownHostException](/topics/errors/unknown-host-exception/) | | `java.net.BindException` | Ephemeral port exhaustion (`Address already in use`) | [BindException / Address in use](/topics/errors/bind-exception-address-in-use/) | | `javax.net.ssl.SSLHandshakeException` | PKIX path building failed, untrusted root CA | [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) | | `javax.net.ssl.SSLPeerUnverifiedException` | Certificate hostname / SAN mismatch | [SSLPeerUnverifiedException](/topics/errors/ssl-peer-unverified/) | | `java.net.SocketException` | Socket closed, connection reset by peer, broken pipe | [Socket closed / connection reset](/topics/errors/socket-closed-connection-reset/) | | `Non HTTP response code` | General client-side wrapper for network exceptions | [Non HTTP response code](/topics/errors/non-http-response-code/) | --- ## 2. HTTP Status Codes & API Request Errors | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | `HTTP 401 / 403` after recording | Missing dynamic CSRF, OAuth token, or session cookie | [401/403 after recording](/topics/errors/401-403-after-recording/) | | `HTTP 500 / 502 / 503 / 504` | Application crash, reverse proxy drop, or capacity overload | [HTTP 500, 502, 503, 504](/topics/errors/http-502-503-504/) | | `HTTP 415 / 400 Bad Request` | Missing `Content-Type: application/json` or bad payload | [HTTP 400 & 415 Errors](/topics/errors/http-415-400-bad-request/) | | `HTTP 429 / WAF 403 Block` | Cloudflare, AWS WAF, or rate limit threshold exceeded | [HTTP 429 & WAF Rate Limiting](/topics/errors/http-429-rate-limited/) | | `HTTP 407` | Proxy Authentication Required by a corporate forward proxy | [HTTP 407 Proxy Authentication](/topics/errors/http-407-proxy-authentication/) | --- ## 3. JVM, Memory & Thread Resource Exhaustion | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | `OutOfMemoryError: Java heap space` | Heap memory filled with listener data or buffers | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | | `OutOfMemoryError: unable to create new native thread` | OS `ulimit -u` or PID capacity exhausted | [Native thread limit](/topics/errors/outofmemory-unable-to-create-native-thread/) | | `OutOfMemoryError: Metaspace & GC Overhead` | Groovy dynamic classloader leak or GC thrashing | [Metaspace & GC Overhead](/topics/errors/metaspace-gc-overhead-limit/) | | `SocketException: Too many open files` | OS file descriptor limit hit at high concurrency | [Too Many Open Files (ulimit)](/topics/errors/too-many-open-files-ulimit/) | | Throughput stuck / collapsing | Concurrency bottleneck or unpaced arrival rates | [Throughput stuck](/topics/errors/throughput-stuck/) | | JMeter Freezing & 100% CPU | GUI listener overhead or CLI hanging on test end | [Freezing, CPU & CLI Hangs](/topics/errors/jmeter-freeze-high-cpu-hanging/) | --- ## 4. Scripting, Dependencies & Correlation | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | `javax.script.ScriptException` | JSR223 Groovy syntax, MissingProperty, or null pointer | [JSR223 Groovy Errors](/topics/errors/jsr223-groovy-script-errors/) | | `ClassNotFoundException` | Missing JAR file in `lib/` (drivers) or `lib/ext/` (plugins) | [ClassNotFound & Missing JARs](/topics/errors/class-not-found-noclassdeffound/) | | `Error loading test plan` | Corrupt JMX, merge conflict markers, or version mismatch | [JMX Won't Load / Corrupt Plan](/topics/errors/jmx-wont-load-corrupt-plan/) | | JSON/Regex returns `NOT_FOUND` | Extractor scoping, JSONPath syntax, or correlation bug | [Extractor Default Value](/topics/errors/extractor-not-found-default-value/) | | `CSV: File not found` & Sharing issues | Relative path resolution or duplicate data reading | [CSV Data Set & Sharing](/topics/errors/csv-data-set-file-not-found-sharing/) | --- ## 5. Distributed Testing, Databases & Reporting | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | `RMI Connection refused to host: 127.0.0.1` | Remote worker loopback binding or SSL keystore error | [Distributed RMI Errors](/topics/errors/rmi-connection-refused-remote-testing/) | | `Cannot create PoolableConnectionFactory` | JDBC database unreachable or connection pool exhausted | [JDBC Connection Pool Errors](/topics/errors/jdbc-connection-pool-errors/) | | Script works in GUI, fails in CLI | Path discrepancies, missing properties, or headless modes | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | | `Cannot generate HTML report` | Non-empty folder, clock skew, or timestamp corruption | [HTML Dashboard Errors](/topics/errors/html-dashboard-generation-errors/) | --- ## 6. Startup & Test Execution Behavior | Error Signature | Symptom / Description | Playbook | |-----------------|-----------------------|----------| | JMeter window flashes and closes | Startup crash from Java, heap, or installation problems | [JMeter Won't Start / Crash on Launch](/topics/errors/jmeter-wont-start-crash-on-launch/) | | Works in browser, fails in JMeter | Missing headers, cookies, redirects, or correlation gaps | [Works in Browser, Fails in JMeter](/topics/errors/works-in-browser-fails-in-jmeter/) | | Test stops early or unexpectedly | Scheduler duration, sampler error action, or JVM crash | [Test Stops Early / Unexpectedly](/topics/errors/test-stops-early-unexpectedly/) | --- ## Interactive Diagnostic Tools Use these interactive web tools on docs.jmeter.ai alongside the error playbooks: - [Heap & Memory Estimator](/tools/heap-estimator/) - Calculate optimal `-Xms`, `-Xmx`, and Metaspace parameters based on thread counts. - [Thread & Throughput Calculator](/tools/thread-calculator/) - Apply Little's Law to calculate target concurrency from desired RPS and response time. - [CLI Command Builder](/tools/cli-builder/) - Generate production-ready non-GUI command lines with logging and property flags. - [Regex Extractor Builder](/tools/regex-tester/) - Validate regular expressions against response data without starting JMeter. - [Properties Cheat Sheet](/tools/properties-cheatsheet/) - Searchable catalog of all `jmeter.properties` and `user.properties`. Select the playbook matching your error message or exception above to view root causes and ordered fixes. - [Troubleshooting overview](/topics/troubleshooting/) - [Best practices](/user-manual/best-practices/) - [API load testing](/topics/api-load-testing/) - [Distributed testing](/topics/distributed-testing/) --- Title: JMeter java.net.ConnectException URL: https://docs.jmeter.ai/topics/errors/connect-exception/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # java.net.ConnectException in JMeter ## Symptom In View Results Tree, the JTL, or dashboard error tables you see messages such as: - `java.net.ConnectException: Connection refused` - `java.net.ConnectException: Connection timed out` - `Non HTTP response code: java.net.ConnectException` - Sample marked failed with **no** normal HTTP status (not 200/404/500) Often every thread fails immediately, or failures start when the system under test (SUT) or network path is wrong. ## Common causes | Cause | Why it happens | |-------|----------------| | Wrong host, port, or protocol | HTTP Request Defaults / sampler still point at lab host or `http` vs `https` | | Property not applied | Plan uses `\${__P(host,)}` but CLI omitted `-Jhost=...` ([functions](/topics/functions-and-variables/)) | | SUT not listening | Process down, wrong interface, or container port not published | | Firewall / security group | Injector cannot reach SUT (common in CI and [Kubernetes](/topics/docker-kubernetes/)) | | Connect timeout too short | Network latency or cold start exceeds HTTP Request connect timeout | | Distributed workers differ | Workers lack DNS/route the controller has ([distributed testing](/topics/distributed-testing/)) | ## Fix (ordered) 1. **Copy the exact error** from the first failed sample (code + message). 2. **From the same machine that runs JMeter**, test reachability (`curl`, `Test-NetConnection`, browser). If curl fails, it is not a JMeter sampler bug. 3. Open **HTTP Request Defaults** and the failing sampler: protocol, server name, port, path. Prefer one defaults element so hosts stay consistent ([web test plan](/user-manual/build-web-test-plan/)). 4. If the plan uses properties, print the effective command: ```bash jmeter -n -t plan.jmx -Jhost=staging.example.com -Jport=443 -l out.jtl -j jmeter.log ``` Confirm `\${__P(host,localhost)}` (or similar) is what you intend. 5. Raise **connect** and **response** timeouts only after host/port are correct. 6. On CI/K8s: check NetworkPolicy, egress, private DNS, and that the job runs in a network that can see the SUT ([CI/CD](/topics/ci-cd-load-testing/)). 7. Distributed: reproduce **on a worker** shell; fix worker networking and data, not only the controller ([remote testing](/user-manual/remote-test/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [Non HTTP response code](/topics/errors/non-http-response-code/) | Broader non-HTTP failures | | [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) | Connect works but TLS fails | | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | Host only wrong under CLI | | [Docker / Kubernetes](/topics/docker-kubernetes/) | Container networking | | [Troubleshooting overview](/topics/troubleshooting/) | Full triage tree | ## Frequently asked questions ### Is ConnectException an HTTP 500? No. It usually means JMeter never completed a normal HTTP exchange. The failure is at the TCP/connect layer (or is wrapped as a non-HTTP sample error). ### Why does it work on my laptop but fail in CI? CI runners often cannot reach private staging hosts, or `-Jhost` / secrets differ. Test connectivity from the runner image first. ### Should I increase threads to fix Connection refused? No. Connection refused means nothing accepted the socket. Fix host, port, process, or firewall first. From the injector host, curl the same URL JMeter uses; only then adjust the sampler or `\${__P(host)}`. - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Distributed testing](/topics/distributed-testing/) --- Title: JMeter java.net.SocketTimeoutException URL: https://docs.jmeter.ai/topics/errors/socket-timeout-exception/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # java.net.SocketTimeoutException in JMeter ## Symptom In the **View Results Tree** listener, `jmeter.log`, or JTL output, a sampler fails with: ```text Response code: Non HTTP response code: java.net.SocketTimeoutException Response message: Non HTTP response message: Read timed out ``` Or during the initial TCP connection phase: ```text Response code: Non HTTP response code: java.net.SocketTimeoutException Response message: Non HTTP response message: connect timed out ``` The sample is marked as failed without a standard HTTP status code (such as 200, 500, or 504). ## Quick diagnosis (TL;DR) `SocketTimeoutException: Read timed out` means JMeter connected successfully to the server, sent the request, but the server failed to transmit response bytes within the configured **Response Timeout**. `connect timed out` means the initial TCP 3-way handshake did not finish within the **Connect Timeout**. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | Slow server processing | `Read timed out` | Database locks, CPU saturation, or heavy downstream microservice calls delay response generation beyond client timeout | | Full GC pause on server | `Read timed out` | Stop-the-world garbage collection pauses the application worker threads, causing all in-flight sockets to stall | | Connect timeout too aggressive | `connect timed out` | Network latency, TLS negotiation overhead, or SYN queue backlog exceeds a short Connect Timeout (e.g. 500ms) | | Missing timeout configuration | Hangs indefinitely | When timeouts are blank (default `0`), JMeter threads wait indefinitely for dead TCP connections until the OS socket timeout triggers | | Load balancer / proxy silent drop | `Read timed out` | Intermediate firewall or load balancer drops the idle connection without sending a TCP RST or FIN packet | ## Fix (ordered) ### 1. Differentiate Connect vs Read Timeout - If the message is **`connect timed out`**: The failure is on the network or firewall layer before the server processed anything. Check host reachability, firewall rules, and ingress controller SYN queues. - If the message is **`Read timed out`**: The server received the request but took too long to answer. The bottleneck is inside the application or database layer. ### 2. Configure Explicit Timeouts in HTTP Request Defaults Never leave timeouts empty (`0` means infinite in Java sockets). Add explicit thresholds in **HTTP Request Defaults** under the **Timeouts (milliseconds)** section: ```text Connect: 10000 (10 seconds) Response: 60000 (60 seconds) ``` You can parameterize timeouts with properties for dynamic CLI overrides: ```text Connect: ${__P(connect.timeout,10000)} Response: ${__P(response.timeout,60000)} ``` ```bash # Override timeouts dynamically via CLI properties jmeter -n -t testplan.jmx -Jconnect.timeout=5000 -Jresponse.timeout=30000 -l results.jtl -j jmeter.log ``` ### 3. Inspect Server-Side APM & Slow Query Logs When `Read timed out` spikes under load: 1. Check server CPU, memory, and JVM garbage collection metrics. 2. Check database connection pool utilization (HikariCP, Tomcat JDBC) and active slow queries. 3. Check downstream third-party API dependencies and external HTTP calls. ### 4. Verify Keep-Alive & Connection Pooling Settings If long-running requests drop intermittently, verify keep-alive behavior in `user.properties`: ```properties # Validate idle connections before reuse (milliseconds) httpclient4.validate_after_inactivity=2000 # Connection time to live in milliseconds httpclient4.time_to_live=60000 ``` ### 5. Tune OS TCP Socket Keepalive (Load Injector) For long soak tests on Linux load generators: ```bash # Check current TCP keepalive settings sysctl net.ipv4.tcp_keepalive_time sysctl net.ipv4.tcp_keepalive_intvl sysctl net.ipv4.tcp_keepalive_probes ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [Non HTTP response code](/topics/errors/non-http-response-code/) | Understanding generic client-side sample failures | | [NoHttpResponseException](/topics/errors/no-http-response-exception/) | Server closes socket before sending any bytes | | [HTTP 502/503/504](/topics/errors/http-502-503-504/) | Gateway timeouts returned by reverse proxies | | [Thread Calculator](/tools/thread-calculator/) | Calibrating concurrency against server response times | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Interactive reference for JMeter core properties | ## Frequently asked questions ### Is SocketTimeoutException a client error or server error? `connect timed out` is typically a network routing, DNS, or firewall issue. `Read timed out` is almost always a server-side performance bottleneck where the application takes longer to calculate the response than JMeter is configured to wait. ### Why does SocketTimeoutException only appear at higher concurrency? Under light load, the server responds in 200ms. Under heavy concurrency, thread contention, database connection pool exhaustion, and CPU saturation cause response times to exceed the timeout threshold (e.g. 5000ms). ### Does increasing response timeout in JMeter fix the root problem? No. Raising the timeout merely prevents JMeter from failing the sample early. If response times breach your service level agreement (SLA), you must optimize the server code, queries, or server capacity. Add explicit connect and response timeouts to HTTP Request Defaults, then check server-side APM logs during the next test run. - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Distributed testing](/topics/distributed-testing/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter org.apache.http.NoHttpResponseException URL: https://docs.jmeter.ai/topics/errors/no-http-response-exception/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # org.apache.http.NoHttpResponseException in JMeter ## Symptom In View Results Tree, JTL results, or `jmeter.log`, HTTP samplers fail intermittently with: ```text Response code: Non HTTP response code: org.apache.http.NoHttpResponseException Response message: Non HTTP response message: The target server failed to respond ``` The error typically appears intermittently during tests with think time, between loop iterations, or when reusing pooled connections over HTTP Keep-Alive. ## Quick diagnosis (TL;DR) `NoHttpResponseException` occurs when JMeter sends an HTTP request over an established persistent (Keep-Alive) TCP socket that the server or intermediate proxy has already closed due to an idle timeout. When JMeter transmits bytes on the stale connection, the server drops or resets the socket without returning an HTTP response line. ## Common causes | Cause | Why it happens | |-------|----------------| | Keep-Alive race condition | Server idle timeout (e.g. 5s) is shorter than JMeter's connection reuse interval / think time | | Server connection backlog full | Target server or load balancer terminates idle client connections under heavy memory or socket pressure | | Intermediate proxy / NAT timeout | Firewalls (AWS ALB, Nginx, Cloudflare) close idle TCP connections silently without TCP FIN packets | | Stale connection checking disabled | JMeter uses pooled sockets without validating whether the connection is still alive before sending data | | Thread iteration state | Previous thread loop left an open TCP connection in a state that the server subsequently closed | ## Fix (ordered) ### 1. Validate Idle Connections Before Reuse in `user.properties` Configure JMeter's underlying Apache HttpComponents HttpClient to check whether a connection is stale before transmitting a new request. Add the following to `bin/user.properties`: ```properties # Validate idle persistent connections if inactive for more than 2000ms httpclient4.validate_after_inactivity=2000 # Set maximum connection Time-To-Live (in milliseconds) httpclient4.time_to_live=60000 # Set idle connection timeout (in milliseconds) httpclient4.idletimeout=10000 ``` ### 2. Reset HTTP State on Thread Group Iteration Ensure each iteration starts with a clean connection state if your virtual users simulate independent sessions: 1. Open your **Thread Group**. 2. Check **Same user on each iteration** if simulating sticky browser sessions, or **uncheck** it if each iteration represents a distinct new user. 3. In **HTTP Request Defaults**, ensure the implementation is set to **`HttpClient4`** (the default and recommended client). ### 3. Match JMeter Keep-Alive Timeout with Server Keep-Alive Check your web server / reverse proxy Keep-Alive configuration: - **Nginx**: `keepalive_timeout 65;` (ensure JMeter `httpclient4.idletimeout` is lower than this value, e.g. `60000`). - **Apache HTTPD**: `KeepAliveTimeout 5`. - **AWS ALB**: Default idle timeout is 60 seconds. If JMeter holds connections longer than the upstream timeout, JMeter will attempt to send requests over dead sockets. ### 4. Enable Automatic Connection Retry Strategy By default, JMeter's `HttpClient4` does not automatically retry non-idempotent requests (like `POST` or `PUT`) if a socket drops. You can configure retry behavior in `user.properties`: ```properties # Number of retries on connection reset (default: 0 in modern JMeter) httpclient4.retrycount=1 # Whether to retry request sent failure httpclient4.request_sent_retry_enabled=true ``` :::caution[Idempotency Warning] Only enable `request_sent_retry_enabled=true` if your test endpoints are idempotent or if simulating real-world browser retry behavior. Retrying non-idempotent `POST` requests may generate duplicate orders or payments. ::: ## Related tools and topics | Resource | Use when | |----------|----------| | [Socket closed / connection reset](/topics/errors/socket-closed-connection-reset/) | Server abruptly resets active TCP connection | | [SocketTimeoutException](/topics/errors/socket-timeout-exception/) | Server receives request but response is too slow | | [HTTP 502/503/504](/topics/errors/http-502-503-504/) | Proxy responses when backends fail to respond | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Quick lookup for `httpclient4.*` properties | ## Frequently asked questions ### Why does NoHttpResponseException happen mostly during think times? When threads pause for Timers (e.g. 10 seconds), the pooled TCP connection sits idle. If the server idle timeout is 5 seconds, the server closes the connection during the think time. When JMeter resumes, it tries to use the dead connection. ### Is NoHttpResponseException a bug in JMeter? No. It is a standard TCP/HTTP Keep-Alive timing condition. Setting `httpclient4.validate_after_inactivity=2000` prevents JMeter from writing to closed sockets. ### Should I disable Keep-Alive in HTTP Request Defaults? Only if your target application architecture does not support Keep-Alive. Disabling Keep-Alive forces a fresh TCP and TLS handshake for every single request, which creates CPU overhead and can cause [ephemeral port exhaustion](/topics/errors/bind-exception-address-in-use/). Add `httpclient4.validate_after_inactivity=2000` to `user.properties` and verify that the error disappears on the next test execution. - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter Premature EOF / Unexpected End of File URL: https://docs.jmeter.ai/topics/errors/premature-eof-connection-abort/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Premature EOF / Unexpected End of File in JMeter ## Symptom Samplers fail while reading the response body, in the **View Results Tree** listener or `jmeter.log`: ```text Response code: Non HTTP response code: java.io.EOFException Response message: Non HTTP response message: Premature EOF ``` Or when the connection dies before any response bytes arrive: ```text Response code: Non HTTP response code: java.io.IOException Response message: Non HTTP response message: Unexpected end of file from server ``` The failures are usually intermittent and increase with test duration or concurrency. ## Quick diagnosis (TL;DR) The server, or a load balancer in front of it, closed the connection while JMeter was still using it: mid-response, or between a pooled connection's reuse. The fix is to align client connection lifetimes with server-side timeouts, and to rule out servers that abort responses under load. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | Server or LB idle timeout shorter than client reuse window | `Unexpected end of file from server` | The server closes idle keep-alive sockets (AWS ALB defaults to 60s) and JMeter reuses one that is already dead | | Server aborts mid-response under load | `Premature EOF` | Worker crashes, OOM kills, or request cancellations cut the response stream | | Truncated gzip or deflate stream | `EOFException` while decompressing | The compressed body ends before its terminator; some applications signal stream end early | | Proxy or CDN cuts long responses | `Premature EOF` on large downloads | An intermediate hop applies its own response size or time limit | | Missing Content-Length with Connection: close | Ambiguous body end | HTTP/1.0-style responses rely on connection close, which races with pooled reuse | ## Fix (ordered) ### 1. Align client connection lifetime with server timeouts Cap how long JMeter reuses a connection, and validate idle connections before use, in `user.properties`: ```properties # Absolute connection lifetime in milliseconds: retire connections before the server does httpclient4.time_to_live=30000 # Check idle connections before reuse (milliseconds) httpclient4.validate_after_inactivity=2000 ``` Set `time_to_live` below the smallest idle timeout in the path (load balancer, reverse proxy, application server). Full tuning guidance is in [NoHttpResponseException](/topics/errors/no-http-response-exception/), which shares this root cause. ### 2. Check load balancer and reverse proxy idle timeouts If the stack includes AWS ALB/CLB, nginx, HAProxy, or a CDN: 1. Find the idle or keep-alive timeout on each hop (ALB default is 60 seconds). 2. Either raise the LB timeout above the client's `time_to_live`, or lower `time_to_live` below the LB timeout. 3. Enable client-side keepalive probes only if the LB supports them; otherwise the lifetime cap is the reliable control. ### 3. Rule out server-side aborts under load If `Premature EOF` appears only at high concurrency, the response stream is being cut by the server itself: 1. Check application logs and OS logs (`dmesg` for OOM kills) at the failure timestamps. 2. Watch server CPU, worker pool saturation, and JVM GC pauses. 3. Confirm the failing endpoint returns complete bodies at low concurrency with the same JMeter script. ### 4. Handle truncated compressed streams When a known-buggy application ends gzip or deflate streams early, JMeter can tolerate it: ```properties # Ignore EOFException on early-ended compressed streams httpclient4.gzip_relax_mode=true httpclient4.deflate_relax_mode=true ``` Use these only after verifying the response content is actually complete: relaxed mode hides real truncation as readily as it hides harmless stream-end signaling. ### 5. Verify the fix Re-run the soak or high-concurrency scenario and confirm the EOF samples disappear. Compare total sample counts and error rates before and after; a correct fix removes the errors without changing response times in any meaningful way. ## Related tools and topics | Resource | Use when | |----------|----------| | [NoHttpResponseException](/topics/errors/no-http-response-exception/) | The sibling keep-alive race with no response bytes at all | | [Socket closed / connection reset](/topics/errors/socket-closed-connection-reset/) | TCP RST variants of the same connection-lifetime family | | [HTTP 502/503/504](/topics/errors/http-502-503-504/) | The proxy reports the failure instead of dropping the connection | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Interactive lookup for `httpclient4.*` tuning properties | ## Frequently asked questions ### What does Premature EOF mean in JMeter? The response stream ended before the complete body arrived. JMeter was still reading when the connection closed, so the sample fails instead of returning a full response. ### Is Premature EOF a JMeter bug? No. The connection was closed on the server side, by the application, a load balancer, or a proxy. JMeter only reports the cut stream; the fix lives in timeout alignment or server capacity. ### When should I enable httpclient4.gzip_relax_mode? Only after confirming that a specific application sends complete bodies with early-ended gzip streams. Relaxed mode also masks genuine truncation, so treat it as a targeted workaround, not a default. ### Why does the error appear only in long-running tests? Pooled connections accumulate idle time in soak tests. Once a connection sits idle longer than the server's keep-alive timeout, the next reuse hits a dead socket, which is exactly what `time_to_live` and `validate_after_inactivity` prevent. Set httpclient4.time_to_live below the smallest idle timeout in the path, enable validate_after_inactivity, then re-run the failing scenario. - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Distributed testing](/topics/distributed-testing/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter java.net.UnknownHostException URL: https://docs.jmeter.ai/topics/errors/unknown-host-exception/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # java.net.UnknownHostException in JMeter ## Symptom In View Results Tree, `jmeter.log`, or JTL execution results, all or specific requests fail immediately with: ```text Response code: Non HTTP response code: java.net.UnknownHostException Response message: Non HTTP response message: staging-api.internal.corp ``` The sample fails within 0–5 milliseconds without transmitting any network packets to the destination server. ## Quick diagnosis (TL;DR) `UnknownHostException` means the Java Virtual Machine running JMeter could not resolve the specified hostname or domain into an IP address using the operating system's DNS resolvers or JMeter's **DNS Cache Manager**. ## Common causes | Cause | Why it happens | |-------|----------------| | Protocol / Path in Server Name field | Entering `https://api.example.com` or `api.example.com/v1` in the "Server Name or IP" field instead of just `api.example.com` | | Unresolved property variable | Using `\${__P(host)}` without supplying `-Jhost=api.example.com` on the command line | | Private / Internal DNS inaccessible | Running load tests in CI/CD (GitHub Actions, GitLab CI) or Docker where private enterprise DNS is not reachable | | Trailing whitespace in server name | Copy-pasting hostname with invisible leading/trailing whitespace into HTTP Request Defaults | | Missing DNS Cache Manager | High-concurrency tests overwhelming local OS DNS cache with repeated lookups | | Docker / Kubernetes CoreDNS | Containerized JMeter workers unable to resolve cluster services (`service.namespace.svc.cluster.local`) | ## Fix (ordered) ### 1. Clean the "Server Name or IP" Field In **HTTP Request Defaults** and individual **HTTP Request** samplers: - **Protocol**: `https` (do **not** put `https://` in Server Name) - **Server Name or IP**: `api.example.com` (no `http://`, no trailing `/`, no `/path`) - **Port Number**: `443` (or leave blank if standard 80/443) - **Path**: `/v1/users` ```xml api.example.com 443 https /v1/users ``` ### 2. Verify Property Defaults in Command Line Runs If using JMeter properties for dynamic environment switching: ```bash # If using ${__P(hostname,)} in the JMX, always provide -Jhostname jmeter -n -t test.jmx -Jhostname=staging.example.com -l results.jtl -j jmeter.log ``` In your JMX, always supply a fallback default: ```text ${__P(hostname,api.example.com)} ``` ### 3. Add and Configure the DNS Cache Manager To simulate real browser DNS caching behavior or use custom DNS servers: 1. Right-click **Thread Group** -> **Add** -> **Config Element** -> **DNS Cache Manager**. 2. Select **Use System DNS** or **Use Custom DNS**. 3. If testing internal staging environments, add static host mappings directly in the table: | Host | Hostname | IP Address | |------|----------|------------| | `api.staging.internal` | `api.staging.internal` | `10.0.4.15` | ### 4. Test DNS Resolution from Injector Terminal Verify that the host machine running JMeter can resolve the target name: ```bash # Linux / macOS nslookup api.example.com dig api.example.com # Windows PowerShell Resolve-DnsName api.example.com Test-NetConnection -ComputerName api.example.com -Port 443 ``` ### 5. Fix Docker & Kubernetes Container DNS If running JMeter inside Docker or Kubernetes pods: ```yaml # Kubernetes Pod spec DNS config spec: dnsPolicy: "ClusterFirst" hostAliases: - ip: "10.240.0.1" hostnames: - "auth.staging.internal" - "api.staging.internal" ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [ConnectException](/topics/errors/connect-exception/) | DNS resolves but connection is refused or timed out | | [Non HTTP response code](/topics/errors/non-http-response-code/) | Overview of all non-HTTP sample errors | | [Docker & Kubernetes](/topics/docker-kubernetes/) | Containerized JMeter networking configuration | | [CLI Command Builder](/tools/cli-builder/) | Generate CLI commands with `-Jhostname` properties | ## Frequently asked questions ### Why does it work in a browser on my laptop but fail in JMeter? Your browser may use DoH (DNS-over-HTTPS) or an active VPN profile that Java's network stack does not inherit, or the browser proxy configuration is not replicated inside JMeter. ### Can DNS resolution failures cause high response times in JMeter? Yes. If DNS queries timeout before failing over, sample elapsed time includes the multi-second DNS lookup delay. Adding a **DNS Cache Manager** eliminates repeated DNS queries per thread iteration. ### How do I point JMeter to a specific IP without changing DNS? Add a **DNS Cache Manager** to your Test Plan, choose "Use Custom DNS", and add a static entry mapping the hostname to the target IP address. Check the Server Name field in HTTP Request Defaults to ensure protocol (`https://`) and paths are separated. - [API load testing](/topics/api-load-testing/) - [Docker / Kubernetes](/topics/docker-kubernetes/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter java.net.BindException: Address already in use URL: https://docs.jmeter.ai/topics/errors/bind-exception-address-in-use/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # java.net.BindException: Address already in use in JMeter ## Symptom During high-concurrency load tests or high-throughput API benchmarks, JMeter samplers suddenly start failing en masse with: ```text Response code: Non HTTP response code: java.net.BindException Response message: Non HTTP response message: Address already in use: connect ``` On Linux or macOS load generators, you may also see: ```text java.net.BindException: Cannot assign requested address (connect failed) ``` The error typically starts after running at high request rates (e.g. 500+ requests per second per injector) for several minutes. ## Quick diagnosis (TL;DR) `BindException: Address already in use: connect` occurs when the operating system running JMeter runs out of available outbound **ephemeral ports** (temporary client-side TCP ports). When connections are opened and closed rapidly without Keep-Alive, thousands of sockets remain locked in the `TIME_WAIT` state for 1–4 minutes, blocking new outbound connections. ## Common causes | Cause | Why it happens | |-------|----------------| | HTTP Keep-Alive disabled | Disabling "Use KeepAlive" forces JMeter to open a fresh TCP socket for every single request | | High request throughput on single IP | Exceeding available ephemeral port capacity (default ~16,000–28,000 ports) on the load generator | | OS `TIME_WAIT` duration too long | Default TCP `TIME_WAIT` delay is 60–240 seconds per closed socket before the OS reclaims the port | | Limited local port range | OS default `ip_local_port_range` or Windows `MaxUserPort` is constrained | | High thread count with short loops | Hundreds of threads executing fast iterations without connection pooling | ## Fix (ordered) ### 1. Ensure "Use KeepAlive" is Checked The primary prevention for port exhaustion is TCP connection reuse: 1. Open **HTTP Request Defaults**. 2. Check **Use KeepAlive** (enabled by default in modern JMeter). 3. Ensure the target server supports and honors HTTP Keep-Alive headers. ### 2. Tune OS Ephemeral Ports & TCP Timeouts (Linux) Apply sysctl tuning on all Linux JMeter load generator machines: ```bash # 1. Expand the available ephemeral port range (provides ~64,500 ports) sudo sysctl -w net.ipv4.ip_local_port_range="1024 65535" # 2. Enable fast recycling of TIME_WAIT sockets for outgoing connections sudo sysctl -w net.ipv4.tcp_tw_reuse=1 # 3. Reduce TCP FIN timeout from 60s to 15s sudo sysctl -w net.ipv4.tcp_fin_timeout=15 # 4. Increase maximum file descriptors and socket backlog sudo sysctl -w fs.file-max=2097152 ``` To make these permanent across reboots, add them to `/etc/sysctl.conf` and run `sudo sysctl -p`. ### 3. Tune Windows Ephemeral Ports and `TcpTimedWaitDelay` On Windows load generator machines: 1. Open PowerShell as Administrator. 2. Expand dynamic port range: ```powershell # Set TCP dynamic port range to start at 1024 with 64511 ports netsh int ipv4 set dynamicport tcp start=1024 num=64511 ``` 3. Open `regedit` and navigate to `HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters`: - Add `DWORD (32-bit)`: **`TcpTimedWaitDelay`** = `30` (Decimal, reduces TIME_WAIT from 240s to 30s). - Add `DWORD (32-bit)`: **`MaxUserPort`** = `65534` (Decimal). 4. Restart Windows. ### 4. Distribute Load Across Multiple IP Addresses (IP Spoofing) If a single IP cannot sustain the required connection rate, configure multiple local IP addresses on the load generator network interface and assign them to JMeter samplers: 1. Add secondary IP addresses (e.g. `192.168.1.101`, `192.168.1.102`) to the network adapter. 2. In JMeter **HTTP Request** or **HTTP Request Defaults**, scroll to **Source address (IP/Hostname)**: - Use a CSV variable: `\${client_ip}` - Select **Source Type: IP/Hostname**. ### 5. Scale Out to Distributed Load Testing When a single injector reaches its network card or kernel socket capacity, scale horizontally across multiple worker nodes rather than overloading a single instance ([distributed testing guide](/topics/distributed-testing/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [ConnectException](/topics/errors/connect-exception/) | Connection refused on target host | | [Socket closed / connection reset](/topics/errors/socket-closed-connection-reset/) | Remote server resets connection | | [Distributed testing](/topics/distributed-testing/) | Scaling load across multiple load injectors | | [Thread Calculator](/tools/thread-calculator/) | Estimating required concurrency and throughput | ## Frequently asked questions ### How can I check how many sockets are currently in TIME_WAIT? Run `netstat -an | grep TIME_WAIT | wc -l` on Linux or `(Get-NetTCPConnection -State TimeWait).Count` in Windows PowerShell. ### Does adding more JMeter threads fix this? No. Adding more threads increases the rate of socket creation, which accelerates ephemeral port exhaustion. You must enable Keep-Alive or tune OS TCP parameters. ### Is BindException caused by the target server or JMeter? `Address already in use: connect` is strictly a **client-side (load generator)** operating system limit. The target server never received the connection attempt because the client OS had no available port to initiate the TCP SYN. Enable "Use KeepAlive" in HTTP Request Defaults and apply `net.ipv4.ip_local_port_range` OS tuning on your load injector. - [Distributed testing](/topics/distributed-testing/) - [Best practices](/user-manual/best-practices/) - [Docker / Kubernetes](/topics/docker-kubernetes/) --- Title: JMeter SSLHandshakeException URL: https://docs.jmeter.ai/topics/errors/ssl-handshake-exception/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # SSLHandshakeException in JMeter ## Symptom Samples fail with TLS-related messages, often wrapped as Non HTTP response errors: - `javax.net.ssl.SSLHandshakeException` - `PKIX path building failed` / unable to find valid certification path - `Received fatal alert: handshake_failure` - `javax.net.ssl.SSLException: Unsupported or unrecognized SSL message` (TLS aimed at a port that answers with plain HTTP) - During **recording**: browser `unknown_ca` or HTTPS pages never record cleanly ([recorder best practices](/user-manual/best-practices/)) HTTP may work in a browser that already trusts the corporate CA, while JMeter’s JVM does not. ## Common causes | Cause | Notes | |-------|------| | Untrusted server certificate | Lab/self-signed or private PKI not in the **JVM truststore** JMeter uses | | Hostname / SNI mismatch | Certificate CN/SAN does not match the server name in the sampler | | TLS version or cipher mismatch | Server requires TLS 1.2+; client restricted by JVM or properties | | TLS aimed at a plain HTTP port | `Unsupported or unrecognized SSL message`; the server's plain HTTP reply cannot be parsed as a TLS handshake | | Client certificate required | Mutual TLS; keystore not configured on the HTTP Request / system properties | | Recorder without JMeter CA | HTTPS recording needs `ApacheJMeterTemporaryRootCA` trusted ([proxy tutorial](/user-manual/jmeter-proxy-step-by-step/)) | | RMI SSL between engines | Distributed mode since JMeter 4.0 defaults to SSL for RMI ([remote testing](/user-manual/remote-test/)) - different from HTTP TLS | ## Fix (ordered) ### Load against HTTPS APIs 1. Confirm the URL works in a browser **and** with curl using the same hostname. 2. Ensure the sampler uses `https` and the correct port (usually 443). 3. Import the issuing CA (or server cert, if appropriate for your org policy) into the truststore used by the **same Java** that launches JMeter. 4. Restart JMeter after truststore changes. 5. Align system clock (skew breaks cert validity). 6. For mTLS, configure client keystore settings on the HTTP Request / related SSL properties ([properties reference](/user-manual/properties-reference/)). 7. Avoid disabling certificate verification outside isolated labs - it hides real misconfiguration. ### Unsupported or unrecognized SSL message This variant is a protocol/port mismatch, not a certificate problem: 1. Check the sampler's protocol and port. `https` against a port that serves plain HTTP triggers this error, because the server answers with HTTP text the TLS layer cannot parse. 2. Confirm which protocol the port actually serves: `curl -v http://host:port/` versus `curl -vk https://host:port/`. 3. Fix the sampler, or HTTP Request Defaults, to match: `http` for plain HTTP ports, `https` for TLS ports (usually 443). 4. Behind load balancers that terminate TLS, target the frontend address with `https`; the backend ports behind it are usually plain HTTP and reject TLS. ### Recording HTTPS 1. Start the [HTTP(S) Test Script Recorder](/topics/http-recorder/). 2. Install `ApacheJMeterTemporaryRootCA.crt` from the JMeter launch directory into the browser trust store. 3. If certs are stale, regenerate per component reference (delete `proxyserver.jks` when documented). 4. Best practices: `unknown_ca` usually means the browser has not accepted the JMeter proxy certificate. ### Distributed RMI SSL 1. Run `create-rmi-keystore` scripts and distribute `rmi_keystore.jks` to controller and workers. 2. Do not confuse RMI SSL failures with HTTP `SSLHandshakeException` against the SUT - check whether the error is on `jmeter-server` startup or on an HTTP sampler. ## Related tools and topics | Resource | Use when | |----------|----------| | [HTTP recorder](/topics/http-recorder/) | Recording HTTPS | | [Properties cheat sheet](/tools/properties-cheatsheet/) | SSL-related properties | | [Remote testing](/user-manual/remote-test/) | RMI SSL keystores | | [Non HTTP response code](/topics/errors/non-http-response-code/) | How JMeter wraps SSL errors | ## Frequently asked questions ### Why does the browser work but JMeter fails SSL? Browsers use the OS trust store. JMeter uses the JVM trust store unless configured otherwise. Corporate CAs often exist in one but not the other. ### Is unknown_ca the same as SSLHandshakeException? Related family: `unknown_ca` during recording means the browser rejected the JMeter MITM CA. Load-test `SSLHandshakeException` usually means JMeter rejected the **server** certificate (or mTLS failed). ### Can I ignore SSL errors for performance tests? Only in controlled non-production labs, and document it. Production-like tests should use proper trust material so TLS cost and failures are realistic. ### What does Unsupported or unrecognized SSL message mean in JMeter? It means JMeter tried to speak TLS to a port that answers with something else, usually plain HTTP. The server's reply cannot be parsed as a TLS handshake. Check the sampler's protocol and port, and use https only against ports that actually serve TLS. Identify whether the failure is HTTP sampler TLS, recorder CA, or distributed RMI SSL, then apply the matching section above. - [HTTP recorder](/topics/http-recorder/) - [Remote testing](/user-manual/remote-test/) - [Properties reference](/user-manual/properties-reference/) --- Title: JMeter javax.net.ssl.SSLPeerUnverifiedException URL: https://docs.jmeter.ai/topics/errors/ssl-peer-unverified/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # javax.net.ssl.SSLPeerUnverifiedException in JMeter ## Symptom When sending HTTPS requests in View Results Tree, JTL results, or `jmeter.log`, samplers fail with: ```text Response code: Non HTTP response code: javax.net.ssl.SSLPeerUnverifiedException Response message: Non HTTP response message: Hostname api.internal.corp not verified: certificate: sha256/... DN: CN=*.prod.example.com subjectAltNames: [*.prod.example.com, prod.example.com] ``` Or when hitting an HTTPS IP address directly: ```text javax.net.ssl.SSLPeerUnverifiedException: Certificate for <192.168.1.50> doesn't match any of the subject alternative names: [api.example.com] ``` The TLS handshake fails before any HTTP request headers or body payload are sent. ## Quick diagnosis (TL;DR) `SSLPeerUnverifiedException` occurs when the server presents an SSL/TLS certificate whose Subject Common Name (`CN`) or Subject Alternative Names (`SAN`) do not match the hostname configured in JMeter's **HTTP Request** sampler, or when SNI (Server Name Indication) is omitted. ## Common causes | Cause | Why it happens | |-------|----------------| | Direct IP addressing over HTTPS | HTTP Sampler points to `10.0.1.5` instead of `api.example.com`, but the TLS cert only contains the domain name | | Wildcard certificate mismatch | Domain has multiple subdomains (e.g. `a.b.example.com`) but the cert is only valid for single-level `*.example.com` | | SNI (Server Name Indication) missing | Server hosts multiple virtual hosts on one IP; TLS handshake receives the default certificate instead of the target domain cert | | Incomplete certificate chain | Server does not send intermediate CA certificates during TLS negotiation | | Cached SSL context reuse | JMeter shares an outdated or incorrect SSL context across multiple iterations | ## Fix (ordered) ### 1. Use the Real Domain Name in HTTP Samplers If testing staging environments, do **not** enter the raw IP address into the "Server Name or IP" field of the sampler if the server presents a certificate for `staging.example.com`. Use the actual domain name in the sampler and route it via the **DNS Cache Manager** or local `/etc/hosts` file: ```text # Add to DNS Cache Manager -> Custom DNS: Host: staging.example.com IP: 10.0.1.5 ``` ### 2. Configure SSL Context Properties in `system.properties` To manage SSL/TLS trust and hostname verification behavior, add these properties to `bin/system.properties` or pass them via CLI: ```properties # Enable Server Name Indication (SNI) for modern TLS hosts jsse.enableSNIExtension=true # Force specific TLS protocol version if server rejects TLS 1.3 https.protocols=TLSv1.2,TLSv1.3 ``` ### 3. Reset SSL Context on Each Thread Iteration When testing applications with client certificates or multiple domains, ensure SSL state is cleared between iterations in `user.properties`: ```properties # Reset SSL context per iteration (useful for client certs and dynamic TLS) https.use.cached.ssl.context=false ``` ### 4. Provide a Custom TrustStore with the Root/Intermediate CA If using internal private CAs or self-signed certificates: ```bash # Launch JMeter with explicit truststore containing the internal CA jmeter -n -t test.jmx \ -Djavax.net.ssl.trustStore=/path/to/truststore.jks \ -Djavax.net.ssl.trustStorePassword=changeit \ -l results.jtl -j jmeter.log ``` ### 5. Validate Certificate SANs with OpenSSL Verify what domains the target certificate actually supports: ```bash openssl s_client -connect api.example.com:443 -servername api.example.com /dev/null \ | openssl x509 -noout -text | grep -A1 "Subject Alternative Name" ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) | PKIX path building and untrusted CA failures | | [ConnectException](/topics/errors/connect-exception/) | Port 443 closed or unreachable | | [Non HTTP response code](/topics/errors/non-http-response-code/) | General client-side exception triage | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Full reference for SSL and TLS system properties | ## Frequently asked questions ### Can I completely disable SSL hostname verification in JMeter? While JMeter provides trust-all behavior for self-signed certificates in some samplers, modern Java and `HttpClient4` strictly enforce SAN hostname matching for HTTPS security. The cleanest and most realistic approach is to map the hostname to the target IP using a **DNS Cache Manager**. ### Why does this error occur in CI/CD pipelines but not on local machines? Local machines often have corporate root certificates installed in the OS keychain or local hosts mapped in `/etc/hosts`, while clean CI/CD container runners lack those custom configurations. Use the DNS Cache Manager to map the certificate's valid domain name to the target IP address instead of using the raw IP in HTTP samplers. - [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Socket Closed Connection Reset URL: https://docs.jmeter.ai/topics/errors/socket-closed-connection-reset/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Socket closed / connection reset in JMeter ## Symptom Samples fail mid-run or under higher concurrency with messages such as: - `Connection reset` / `Connection reset by peer` - `Socket closed` / `SocketException` - `Broken pipe` - Often shown as [Non HTTP response code](/topics/errors/non-http-response-code/) Unlike pure **connection refused**, some samples may succeed first; failures increase with load or longer tests. ## Common causes | Cause | Detail | |-------|--------| | Server or load balancer limits | Max connections, rate limits, or worker exhaustion | | Idle timeouts | LB/proxy closes keep-alive connections JMeter tries to reuse | | Injector ephemeral port / file descriptor exhaustion | Many short connections from one host | | TLS session / middlebox interference | Intermittent handshake or reset under load | | SUT crash or restart | Bursts of resets when the app dies | | Aggressive timeouts | Client gives up; appears as socket errors depending on stack | | Network path instability | VPN, NAT, or multi-hop firewalls | ## Fix (ordered) 1. Capture **error rate vs active threads** on the [dashboard](/user-manual/generating-dashboard/) and SUT metrics (connections, 5xx, restarts). 2. Reproduce with **moderate** threads; note whether failures are immediate or after idle. 3. Align **keep-alive** behaviour with the environment (HTTP client settings / connection reuse). If a proxy closes idle sockets quickly, reduce reuse or match idle timeouts. 4. Check SUT and LB **max connections** and **idle timeout** documentation for your stack. 5. On the injector: watch open files, TIME_WAIT, and CPU; split load across engines if the client is saturated ([distributed testing](/topics/distributed-testing/), [Thread Calculator](/tools/thread-calculator/)). 6. Distinguish from **ConnectException** (never connected) vs reset (peer closed an established or half-open connection). 7. Review TLS separately if resets cluster around HTTPS only ([SSLHandshakeException](/topics/errors/ssl-handshake-exception/)). 8. Ensure you are not melting the SUT with zero think time and huge threads ([best practices](/user-manual/best-practices/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [Throughput stuck](/topics/errors/throughput-stuck/) | Resets plus flat RPS | | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | Injector death causing drops | | [Coordinated Omission](/tools/coordinated-omission/) | Throughput below target while latency looks fine | | [Grafana / Backend Listener](/topics/grafana-influx-backend-listener/) | Live error charts | ## Frequently asked questions ### Is connection reset always a JMeter bug? Rarely. It usually means something on the path or server closed the TCP connection. Validate with server and load-balancer metrics. ### Why only under load? Connection pools and OS limits appear only when many sockets are open. One-thread tests often hide them. ### Should I disable keep-alive? Sometimes as a diagnostic. Prefer fixing idle timeouts and server capacity; disabling keep-alive increases handshakes and can worsen injector load. Correlate JMeter error timestamps with SUT connection counts and load-balancer idle timeout settings. - [Non HTTP response code](/topics/errors/non-http-response-code/) - [Best practices](/user-manual/best-practices/) - [Distributed testing](/topics/distributed-testing/) --- Title: JMeter Non HTTP response code URL: https://docs.jmeter.ai/topics/errors/non-http-response-code/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Non HTTP response code in JMeter ## Symptom View Results Tree or the results file shows: - **Response code:** `Non HTTP response code: java.net.…` (or similar) - **Response message:** `Non HTTP response message: …` There is **no** standard HTTP status such as 200, 401, or 503. The sample is failed because the HTTP client threw an exception before a normal status line was available. Common nested types: - `java.net.ConnectException` - `java.net.SocketException` / connection reset - `javax.net.ssl.SSLHandshakeException` - `java.net.SocketTimeoutException` - `java.net.UnknownHostException` ## Common causes | Cause | Typical nested message | |-------|------------------------| | Cannot connect | ConnectException, connection refused/timed out | | DNS failure | UnknownHostException | | TLS trust / handshake | SSLHandshakeException, PKIX path building failed | | Peer closed socket | Connection reset, SocketException, socket closed | | Read/connect timeout | SocketTimeoutException | | Wrong proxy settings | Connect or tunnel failures when a proxy is required | Official debugging still starts with **one thread** and View Results Tree ([best practices](/user-manual/best-practices/) recommend Tree only while scripting). ## Fix (ordered) 1. **Read the full message** after `Non HTTP response code:` / `message:` - treat the Java exception as the real error. 2. Route to the dedicated playbook: - [ConnectException](/topics/errors/connect-exception/) - [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) - [Socket closed / connection reset](/topics/errors/socket-closed-connection-reset/) 3. Confirm **protocol/host/port** via HTTP Request Defaults. 4. Check **connect and response timeouts** on the HTTP Request sampler. 5. Disable corporate proxy surprises: if the OS proxy is set but the SUT is internal, configure JMeter proxy fields deliberately or clear them. 6. Re-run CLI with logging: ```bash jmeter -n -t plan.jmx -l results.jtl -j jmeter.log ``` 7. After connect works, add **assertions** so HTTP 5xx pages are not mistaken for success ([API guide](/topics/api-load-testing/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [ConnectException](/topics/errors/connect-exception/) | Refused / timed out connect | | [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) | Certificate and TLS failures | | [Dashboard report](/user-manual/generating-dashboard/) | Aggregate error rates after CLI | | [Troubleshooting overview](/topics/troubleshooting/) | Broader checklist | ## Frequently asked questions ### Is Non HTTP response code a real HTTP status? No. It is JMeter’s way of saying the sampler failed with a client-side exception instead of an HTTP status line. ### Can Non HTTP errors appear only under load? Yes. Connection limits, TLS session issues, or server overload can surface as resets and timeouts only at higher concurrency. Still fix connectivity for one thread first. ### Do these count in error percentage? Yes. Failed samples increase error % on the [HTML dashboard](/user-manual/generating-dashboard/) and in listeners. Copy the nested Java exception from the sample and open the matching playbook in this error section. - [ConnectException](/topics/errors/connect-exception/) - [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter 401 403 After Recording URL: https://docs.jmeter.ai/topics/errors/401-403-after-recording/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # 401 / 403 after recording ## Symptom - Recording in the browser works and samplers appear under the Recording Controller - Replay in JMeter returns **401 Unauthorized** or **403 Forbidden** on login-protected steps - First sampler may work; later calls fail - Or all calls fail after the recorded session cookie/token expires This is one of the most common post-recorder failures ([HTTP recorder](/topics/http-recorder/), [best practices](/user-manual/best-practices/)). ## Common causes | Cause | Detail | |-------|--------| | Missing Cookie Manager | Session cookies from `Set-Cookie` not stored per thread ([web test plan](/user-manual/build-web-test-plan/)) | | Hard-coded CSRF / viewstate / nonce | Values from the recording are stale ([correlation](/topics/correlation-dynamic-values/)) | | Hard-coded Bearer / session token | JWT expired; need extract + Header Manager ([JWT/OAuth](/topics/jwt-oauth-sso/)) | | Header Manager scope wrong | Authorization not applied to the failing sampler | | Same user / concurrency rules | App rejects parallel sessions for one account | | Include/exclude left noise out | Login API calls never recorded | | HTTPS recorder cert issues during capture | Incomplete journey recorded (`unknown_ca` per best practices) | ## Fix (ordered) 1. Replay with **1 thread**, View Results Tree on; find the **first** 401/403. 2. Add an [HTTP Cookie Manager](/user-manual/component-reference/) at Test Plan or Thread Group level. 3. Compare the failing request to the **previous** response: look for tokens in HTML/JSON/headers. 4. Add JSON or Regular Expression Extractor; replace hard-coded values with `\${var}` ([correlation guide](/topics/correlation-dynamic-values/), [Regex Extractor Builder](/tools/regex-tester/)). 5. For APIs: extract `access_token`, set header `Authorization` to ``Bearer `\${accessToken}` `` ([JWT/OAuth](/topics/jwt-oauth-sso/)). 6. Use **CSV Data Set** for unique users when the app requires it (best practices multi-user pattern). 7. Assert login success (status + body) so silent auth failure does not flood later steps. 8. Disable Tree, run CLI, confirm error % on the [dashboard](/user-manual/generating-dashboard/). ## Related tools and topics | Resource | Use when | |----------|----------| | [Correlation](/topics/correlation-dynamic-values/) | Extract dynamic fields | | [Regex Extractor Builder](/tools/regex-tester/) | Draft regex from a response body | | [HTTP recorder](/topics/http-recorder/) | Capture and cleanup | | [JWT / OAuth / SSO](/topics/jwt-oauth-sso/) | Token APIs | | [API load testing](/topics/api-load-testing/) | Assertions and headers | ## Frequently asked questions ### Why did recording work if replay returns 401? Recording used your live browser session. Replay is a new session unless cookies and tokens are correlated for each virtual user. ### Do I need extractors if I only use Cookie Manager? Cookies often cover classic server sessions. CSRF tokens, hidden fields, and Bearer tokens still need extractors. ### Can 403 be a WAF or CSRF failure? Yes. Correlate anti-forgery tokens and required headers; match the browser’s security headers when they are mandatory. Add Cookie Manager, re-run one thread, and correlate the first dynamic token on the response before the first 401. - [Correlation](/topics/correlation-dynamic-values/) - [HTTP recorder](/topics/http-recorder/) - [Regex Extractor Builder](/tools/regex-tester/) --- Title: Site Works in Browser but Fails in JMeter URL: https://docs.jmeter.ai/topics/errors/works-in-browser-fails-in-jmeter/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Site Works in Browser but Fails in JMeter ## Symptom The application works perfectly in a browser, but the same requests in JMeter fail with: ```text Response code: 401 / 403 / 404 / 500 ``` empty response bodies, redirects that never land, or assertion failures. Recorded scripts replay once and then fail on every subsequent run. ## Quick diagnosis (TL;DR) Browsers do far more than send the URL: they attach a full header set, manage cookies, follow redirects, execute JavaScript that fires extra requests, and carry fresh dynamic tokens. A replayed JMeter script does none of that automatically. Find which of these the failing request depends on and add it explicitly. ## Common causes | Cause | Typical Error | Why it happens | |-------|---------------|----------------| | Missing request headers | `403` or `400` | The server or WAF checks `User-Agent`, `Accept`, `Origin`, or custom headers the browser sends but the script omits | | No Cookie Manager | `401` or lost session | Sessions ride cookies; without a Cookie Manager each request arrives stateless | | Uncorrelated dynamic values | `401`, `403`, `400` | CSRF tokens, session IDs, or bearer tokens from the recording are stale | | Redirect handling mismatch | Redirect loops or `302` chains | `Follow Redirects` and `Redirect Automatically` behave differently, and one is often disabled | | JavaScript-driven flows | Missing requests entirely | SPAs fire API calls from JavaScript, which JMeter never executes | | URL encoding differences | `400` or `404` | Special characters in parameters encode differently between browser and sampler | ## Fix (ordered) ### 1. Compare the failing request with browser DevTools Open the browser's Network tab, perform the action manually, and inspect the successful request. Compare, field by field against the JMeter sampler: 1. Request headers (especially `User-Agent`, `Accept`, `Content-Type`, `Origin`, and any custom security headers). 2. Cookies sent with the request. 3. Query and body parameters, including tokens. 4. The exact URL and encoding. Add the missing pieces to the sampler, then re-run one thread. ### 2. Add missing headers with an HTTP Header Manager Add an **HTTP Header Manager** at the test plan or thread group level for global headers, or under a single sampler for request-specific ones. Replicate only what the server actually inspects; there is no need to copy every browser header. ### 3. Add an HTTP Cookie Manager Sessions break without one. Add an **HTTP Cookie Manager** to each thread group. Keep the default "clear cookies each iteration" behavior unless the scenario explicitly models a returning user with a persistent session. ### 4. Correlate dynamic values Extract tokens from the response that provides them and pass them into the next request: 1. Locate the token in the login or page-load response (CSRF field, session ID, bearer token). 2. Add a **Regular Expression Extractor** or **JSON Extractor** for it. 3. Reference the variable in the failing request. The [Correlation & Dynamic Values](/topics/correlation-dynamic-values/) guide covers the patterns in depth, and [HTTP 401/403 after recording](/topics/errors/401-403-after-recording/) covers the auth-specific variants. ### 5. Check redirect settings In the sampler, **Follow Redirects** (HttpClient implementation) hands redirects to JMeter's logic and records the final response, while **Redirect Automatically** replays them at the protocol level with fewer hooks. Enable exactly one per sampler, never both, and inspect the redirect chain in DevTools to know how many hops to expect. ### 6. Script what JavaScript would have done JMeter does not execute JavaScript. For SPA flows: 1. Watch the Network tab while the page runs and list the real API calls behind the UI action. 2. Script those calls directly as HTTP Requests in the right order. 3. Replace browser-only behavior (token refresh, polling) with its HTTP equivalent. [API Load Testing](/topics/api-load-testing/) shows how to structure these protocol-level tests. ## Related tools and topics | Resource | Use when | |----------|----------| | [HTTP 401/403 after recording](/topics/errors/401-403-after-recording/) | Auth failures dominate the replay | | [Correlation & Dynamic Values](/topics/correlation-dynamic-values/) | Tokens and session IDs need extraction | | [HTTP Recorder](/topics/http-recorder/) | Capturing browser traffic cleanly in the first place | | [Extractor Default Value](/topics/errors/extractor-not-found-default-value/) | Extractors return NOT_FOUND during correlation | ## Frequently asked questions ### Why does JMeter not execute JavaScript like a browser? JMeter is a protocol-level tool: it sends and receives HTTP requests without rendering pages or running scripts. Any request a browser fires from JavaScript must be discovered in DevTools and scripted as an explicit HTTP Request. ### Which browser headers does JMeter actually need? Only the ones the server or WAF inspects. Start with `User-Agent`, `Accept`, `Content-Type`, and any custom security or anti-bot headers visible in DevTools, then add more only while failures persist. ### Why does my recorded script fail on the second run? Recording captures tokens and cookies that expire after the first use. Add a Cookie Manager and correlate CSRF tokens, session IDs, and bearer values so each virtual user gets fresh ones. ### Can JMeter test a single-page application? Yes, but at the API level. Identify the HTTP calls the SPA makes behind its UI, script them in order, and treat the browser as a reference for the request sequence rather than as something to emulate. Diff the failing sampler against the browser's DevTools request, add the missing headers and Cookie Manager, then correlate any stale tokens before replaying with one thread. - [API load testing](/topics/api-load-testing/) - [Correlation & dynamic values](/topics/correlation-dynamic-values/) - [HTTP Recorder](/topics/http-recorder/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter HTTP 400 Bad Request & 415 Unsupported Media Type URL: https://docs.jmeter.ai/topics/errors/http-415-400-bad-request/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # HTTP 400 Bad Request & 415 Unsupported Media Type in JMeter ## Symptom When executing REST API requests in View Results Tree or JTL results, samplers return client-side HTTP 4xx error codes: ```text Response code: 415 (Unsupported Media Type) Response message: Unsupported Media Type ``` Or for payload validation issues: ```text Response code: 400 (Bad Request) Response message: Bad Request ``` The response body typically explains that the server cannot parse the incoming payload or that the `Content-Type` header is missing or unexpected. ## Quick diagnosis (TL;DR) - **HTTP 415**: The API endpoint requires `Content-Type: application/json` (or `application/xml`), but JMeter sent the request without a `Content-Type` header (or sent default `text/plain`). Add an **HTTP Header Manager**. - **HTTP 400**: The payload syntax is malformed (e.g. unescaped quotes in JSON strings, missing required parameters, or invalid variable interpolation like `{"name": \${var}}` without quotes). ## Common causes | Cause | Status | Why it happens | |-------|--------|----------------| | Missing `Content-Type` header | 415 | JMeter HTTP Request does not include `Content-Type` by default without an HTTP Header Manager | | Wrong Header Manager scope | 415 | HTTP Header Manager placed under a different Thread Group or sampler, leaving child samplers without headers | | Unquoted variable in JSON | 400 | Writing `{"id": \${userId}}` where `userId` is a string value, resulting in invalid JSON `{"id": abc}` | | Multipart form data checkbox | 415 / 400 | Checking "Use multipart/form-data" for standard raw JSON body payloads | | Malformed JSON quotes / newlines | 400 | CSV variables containing unescaped double quotes (`"`) or literal newlines breaking JSON schema validation | ## Fix (ordered) ### 1. Add HTTP Header Manager at the Test Plan or Thread Group Level To ensure every REST API request transmits the proper headers: 1. Right-click your **Thread Group** -> **Add** -> **Config Element** -> **HTTP Header Manager**. 2. Add the standard REST API headers: | Name | Value | |------|-------| | `Content-Type` | `application/json; charset=UTF-8` | | `Accept` | `application/json` | ```xml Content-Type application/json Accept application/json ``` ### 2. Configure the "Body Data" Tab (Do Not Mix with Parameters) In your **HTTP Request** sampler: 1. Select the **Body Data** tab (not the **Parameters** tab). 2. Uncheck **Use multipart/form-data** (unless performing actual file uploads). 3. Ensure strings inside JSON payloads are wrapped in quotes: ```json { "username": "${username}", "email": "${email}", "age": ${age} } ``` ### 3. Handle Escaped JSON Strings with `__groovy()` If CSV data contains special characters, quotes, or newlines, use Groovy's `JsonOutput.toJson()` to safely escape strings: ```text ${__groovy(groovy.json.JsonOutput.toJson(vars.get('csv_text_column')))} ``` ### 4. Inspect Request Headers in View Results Tree To verify what headers JMeter actually sent over the wire: 1. Run with 1 thread in GUI. 2. Select the failed sampler in **View Results Tree**. 3. Open the **Request** tab -> **Request Headers** sub-tab. 4. Verify that `Content-Type: application/json` is present and matches API documentation. ## Related tools and topics | Resource | Use when | |----------|----------| | [401/403 after recording](/topics/errors/401-403-after-recording/) | Authentication and authorization header issues | | [API load testing](/topics/api-load-testing/) | Full end-to-end API load testing tutorial | | [Correlation & dynamic values](/topics/correlation-dynamic-values/) | Extracting and passing dynamic tokens in headers | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Quick lookup of JMeter configuration elements | ## Frequently asked questions ### Can I set different Content-Type headers for different samplers? Yes. Place an HTTP Header Manager directly as a child of a specific HTTP Request sampler to override the parent Thread Group's headers for that individual request. ### Why does JMeter change my JSON payload into form parameters? If you add rows to the "Parameters" tab of an HTTP Request, JMeter switches to `application/x-www-form-urlencoded`. Always clear the Parameters tab when using the "Body Data" tab for raw JSON payloads. Add an HTTP Header Manager with `Content-Type: application/json` to your Thread Group and verify the Body Data tab in your samplers. - [API load testing](/topics/api-load-testing/) - [401/403 after recording](/topics/errors/401-403-after-recording/) - [Functions & variables](/topics/functions-and-variables/) --- Title: JMeter HTTP 429 Too Many Requests & WAF Blocks URL: https://docs.jmeter.ai/topics/errors/http-429-rate-limited/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # HTTP 429 Too Many Requests & WAF Rate Limiting in JMeter ## Symptom During load ramp-up or sustained concurrency, requests suddenly start returning HTTP 429 or 403 status codes with security challenge HTML or JSON errors: ```text Response code: 429 (Too Many Requests) Response message: Rate limit exceeded. Try again in 60 seconds. ``` Or when blocked by a Web Application Firewall (Cloudflare, AWS WAF, Akamai, Datadog): ```text Response code: 403 (Forbidden) Response message: Cloudflare Ray ID: ... / Access Denied by WAF ``` Samplers pass during low-concurrency runs (1 thread) but fail consistently when concurrency or request rate scales up. ## Quick diagnosis (TL;DR) `HTTP 429` means the target API rate limiter has capped your request frequency (e.g. 100 req/min per IP or API token). `HTTP 403 WAF Block` means an automated security rule detected JMeter's default User-Agent signature, rapid connection patterns, or missing browser fingerprinting attributes. ## Common causes | Cause | Status | Why it happens | |-------|--------|----------------| | IP-based API rate limiting | 429 | Hundreds of virtual users share a single injector IP address, triggering per-IP throttles (e.g. Nginx `limit_req`, Redis token buckets) | | User / Token rate limiting | 429 | All threads use the same API key or Bearer token instead of parameterized test accounts | | WAF bot detection | 403 | Cloudflare, Akamai, or AWS WAF blocks default `Apache-HttpClient` User-Agent string | | Cloudflare Turnstile / CAPTCHA | 403 | Bot mitigation returns JS challenges or CAPTCHAs that headless HTTP samplers cannot compute | | Aggressive burst rates | 429 | Lack of pacing timers generates unnatural millisecond bursts upon thread group start | ## Fix (ordered) ### 1. Set Realistic Browser User-Agent & Headers By default, JMeter sends `User-Agent: Apache-HttpClient/...`. Many WAFs block this header instantly. Add an **HTTP Header Manager** to your Test Plan with standard browser headers: ```text User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Accept-Language: en-US,en;q=0.9 Accept-Encoding: gzip, deflate, br ``` ### 2. Coordinate Testing IP Whitelisting & WAF Bypass Rules For performance testing in pre-production or staging environments: 1. Request that DevOps / SecOps whitelist the public IP addresses of your JMeter load injectors. 2. Provide a custom secret bypass header (supported by AWS WAF, Cloudflare Custom Rules, and Kong Gateway): ```text X-Load-Test-Bypass: secret-token-from-devops ``` 3. In pre-prod environments, request that security teams temporarily disable or elevate rate limits for the duration of the test window. ### 3. Parameterize API Keys & User Accounts If testing authenticated APIs with per-user rate limits: 1. Add a **CSV Data Set Config** with hundreds of unique test credentials or API keys. 2. Parameterize authorization headers: ```text Authorization: Bearer ${user_token} ``` 3. Set **Sharing Mode** to **All threads** so each virtual user operates with independent rate quotas. ### 4. Implement Request Pacing with Timers Avoid burst spikes that trigger rate limiters by smoothing traffic distribution: - **Constant Throughput Timer**: Controls overall target samples per minute. - **Precise Throughput Timer**: Schedules Poisson-distributed request arrivals to model natural user traffic without simultaneous synchronized bursts. - **Uniform Random Timer**: Adds jitter and realistic think time between consecutive requests. ```xml 50.0 1 300 ``` ### 5. Distribute Load Across Multiple Injector IPs If per-IP rate limiting is a business requirement under test: - Use **Distributed Testing** ([distributed guide](/topics/distributed-testing/)) with multiple worker machines in different subnets. - Use multiple local network interfaces with IP spoofing (`Source IP` field in HTTP Request Defaults). ## Related tools and topics | Resource | Use when | |----------|----------| | [401/403 after recording](/topics/errors/401-403-after-recording/) | Session tokens and credentials issues | | [Throughput stuck](/topics/errors/throughput-stuck/) | Virtual users blocked from reaching target RPS | | [Distributed testing](/topics/distributed-testing/) | Scaling load across multiple distinct IP addresses | | [Thread Calculator](/tools/thread-calculator/) | Calculating required pacing and thread numbers | ## Frequently asked questions ### Should I test through a WAF or bypass it during performance testing? Best practice is to test **both**: first, test the application directly (bypassing the WAF) to measure pure backend capacity and find application bottlenecks. Second, test through the WAF (with elevated rate limit rules) to measure WAF latency overhead and rule evaluation limits. ### Can JMeter solve Cloudflare CAPTCHAs or Turnstile challenges? No. Standard JMeter HTTP samplers only parse network protocols, not client-side JavaScript execution. In staging environments, Cloudflare Turnstile should be disabled for test IPs or set to pass-through mode. Coordinate with your infrastructure team to obtain a test-bypass header or whitelist your load generator IP addresses. - [API load testing](/topics/api-load-testing/) - [Distributed testing](/topics/distributed-testing/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter HTTP 500, 502, 503, 504 Server Errors URL: https://docs.jmeter.ai/topics/errors/http-502-503-504/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # HTTP 500, 502, 503, 504 Errors in JMeter ## Symptom During load testing, JMeter samples turn red in View Results Tree, the HTML dashboard reports elevated error rates, and samplers return HTTP 5xx status codes: - `Response code: 500 (Internal Server Error)` - `Response code: 502 (Bad Gateway)` - `Response code: 503 (Service Unavailable)` - `Response code: 504 (Gateway Timeout)` Unlike `Non HTTP response code` errors (which indicate client or TCP failures), HTTP 5xx codes are valid HTTP responses returned by the backend application, reverse proxy, or API gateway. ## Quick diagnosis (TL;DR) - **HTTP 500**: Unhandled exception, null pointer, or DB query error inside the application code. - **HTTP 502**: The reverse proxy (Nginx, ALB, Cloudflare) could not establish a connection to the upstream app pod/process or the app crashed mid-request. - **HTTP 503**: The server thread pool, connection backlog, or queue is completely full and rejecting new requests. - **HTTP 504**: The upstream application server took longer to calculate the response than the reverse proxy's gateway timeout threshold. ## 5xx Triage Matrix | Status Code | Layer | Root Cause | |-------------|-------|------------| | **500 Internal Server Error** | Application / DB | Code exceptions, database connection deadlocks, unhandled edge-case payload | | **502 Bad Gateway** | Ingress / Proxy / Envoy | Upstream app crashed (OOM), closed socket prematurely, or pod restarted during test | | **503 Service Unavailable** | Gateway / Rate Limiter | Server overload, connection pool backlog saturated, circuit breaker open | | **504 Gateway Timeout** | Reverse Proxy / Load Balancer | Application took longer than proxy timeout (e.g. Nginx `proxy_read_timeout 60s`) | ## Fix (ordered) ### 1. Extract the Full Response Body in View Results Tree HTTP 5xx responses usually contain informative JSON or HTML error payloads explaining the failure. In JMeter GUI (during single-thread validation): 1. Add **View Results Tree** listener under the failing sampler. 2. Inspect the **Response data** tab for stack traces, error codes, or database constraint violations. 3. In CLI mode, configure JTL logging to save response data for failed samples: ```properties # Add to user.properties for debugging runs jmeter.save.saveservice.response_data.on_error=true ``` ### 2. Isolate 502 Bad Gateway (Upstream Crash or OOM) If seeing bursts of 502 errors at high concurrency: 1. Check if the application crashed with an OutOfMemoryError: ```bash # Kubernetes pod status kubectl get pods -n production -w # Look for OOMKilled or Restarts > 0 ``` 2. Check reverse proxy upstream error logs: - Nginx: `connect() failed (111: Connection refused) while connecting to upstream` - AWS ALB: `HTTP 502: TargetConnectionError` ### 3. Diagnose 503 Service Unavailable (Capacity Limits) When 503 errors occur: 1. Check the application server thread pool (e.g. Tomcat `maxThreads`, Node.js cluster, Puma/Unicorn workers). 2. Check database connection pool sizing (HikariCP `maximumPoolSize`). If the pool is exhausted, requests queue up until timeout. 3. Check rate limiters and API gateway throttling rules. ### 4. Resolve 504 Gateway Timeout (Proxy Timeout vs App Latency) If 504 errors spike: 1. Check backend database slow query logs and external service latency. 2. If long operations (e.g. PDF generation, heavy reporting) are expected, increase the proxy timeout: ```nginx # Nginx proxy timeout tuning proxy_connect_timeout 120s; proxy_send_timeout 120s; proxy_read_timeout 120s; ``` 3. In JMeter, verify that the **Response Timeout** in HTTP Request Defaults is larger than the expected server processing window. ### 5. Use Response Assertions to Validate Business Logic Do not assume HTTP 200 is always a success; some flawed APIs return HTTP 200 with an embedded `{"error": "Internal database error"}` payload. Add **Response Assertions** checking for expected JSON fields or status strings ([API guide](/topics/api-load-testing/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [SocketTimeoutException](/topics/errors/socket-timeout-exception/) | Client-side timeout before receiving any bytes | | [Throughput stuck](/topics/errors/throughput-stuck/) | Requests queuing and throughput collapsing under load | | [Coordinated Omission](/tools/coordinated-omission/) | Measuring true user impact when servers stall | | [Generating Dashboard](/user-manual/generating-dashboard/) | Viewing Top 5 Errors table in HTML report | ## Frequently asked questions ### Can JMeter cause HTTP 500 errors on its own? No. An HTTP 500 is generated strictly by the server application. However, JMeter may trigger it if your test sends invalid JSON data, missing headers, or unexpected concurrency that exposes race conditions in the server code. ### How do I ignore expected HTTP 500 errors in a negative test? Add a **Response Assertion** under the sampler, check **Ignore Status**, and add `500` to the patterns to test. Inspect the response body of failed 5xx samples in View Results Tree and check server-side APM/Kubernetes restart logs. - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Dashboard report](/user-manual/generating-dashboard/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter HTTP 407 Proxy Authentication Required URL: https://docs.jmeter.ai/topics/errors/http-407-proxy-authentication/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # HTTP 407 Proxy Authentication Required in JMeter ## Symptom Samplers fail with: ```text Response code: 407 Response message: Proxy Authentication Required ``` The same requests usually work when the load generator bypasses the proxy, or fail only inside the office or CI network. ## Quick diagnosis (TL;DR) A 407 is not returned by your application. An intermediate proxy between JMeter and the target demands credentials before it forwards anything. Supply the proxy username and password through HTTP Request Defaults, the `http.proxyUser`/`http.proxyPass` properties, or an explicit `Proxy-Authorization` header. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | Corporate forward proxy requires authentication | `407` on every request | Office networks route outbound traffic through an authenticating proxy | | Credentials missing from the test plan | `407` immediately | Proxy host and port are set, but no username and password | | Expired or rotated credentials | Worked before, now `407` | Domain password changed since the test was recorded | | NTLM or Kerberos domain proxy | `407` despite correct password | Challenge-response schemes need the right credential format and JVM support | | Proxy set at JVM level without credentials | `407` in CI only | Environment proxy variables route traffic, but nothing authenticates | ## Fix (ordered) ### 1. Set proxy credentials in HTTP Request Defaults The proxy section of **HTTP Request Defaults** (and of each **HTTP Request** sampler) accepts credentials, and defaults apply to every sampler beneath them: 1. Add **HTTP Request Defaults** to the test plan. 2. Open the **Advanced** tab and find the **Proxy Server** section. 3. Fill in **Server (proxy)**, **Port**, **Username**, and **Password**. Note that the password is stored unencrypted in the test plan file, which matters when the JMX is committed to version control. ### 2. Pass credentials through properties instead To keep credentials out of the JMX, use the `http.proxyUser` and `http.proxyPass` properties. Put them in `user.properties`: ```properties http.proxyUser=loadtest-user http.proxyPass=change-me ``` Or inject them per run without touching any file: ```bash jmeter -n -t testplan.jmx -Jhttp.proxyUser=loadtest-user -Jhttp.proxyPass=change-me -l results.jtl ``` This is the right approach in CI, where secrets can come from the pipeline's secret store. ### 3. Fallback: send a Proxy-Authorization header If a proxy ignores the sampler's proxy configuration, add an **HTTP Header Manager** with an explicit header, where the value is `Basic` plus the Base64 encoding of `username:password`: ```text Proxy-Authorization: Basic ${__base64Encode(loadtest-user:change-me)} ``` `${__base64Encode()}` is evaluated at runtime, so the plain credential does not appear in the header value itself. ### 4. NTLM and Kerberos environments Domain proxies that answer with NTLM or SPNEGO challenges need the credential in `DOMAIN\username` form in the proxy Username field. If authentication still fails: 1. Confirm with the network team which scheme the proxy enforces. 2. Run the load generator on a host that is domain-joined when Kerberos tickets are required. 3. As a clean alternative, ask for a proxy bypass or a dedicated non-authenticating route for the load generators, which also removes credentials from test plans entirely. ### 5. Verify the fix Run one thread against the target and confirm the sampler returns the application's real status code instead of 407. Then remove the proxy settings temporarily and confirm the request fails differently (connection refused or timeout): that proves traffic really travels through the proxy. ## Related tools and topics | Resource | Use when | |----------|----------| | [HTTP 401/403 after recording](/topics/errors/401-403-after-recording/) | The application itself rejects the request, not a proxy | | [HTTP Recorder](/topics/http-recorder/) | Recording through an authenticating corporate proxy | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Looking up `http.proxyUser` and other proxy properties | | [CI/CD Load Testing](/topics/ci-cd-load-testing/) | Injecting proxy secrets from pipeline secret stores | ## Frequently asked questions ### What is HTTP 407 in JMeter? It means an intermediate proxy, not the target application, rejected the request because the proxy credentials are missing or wrong. JMeter must authenticate to the proxy before the request is forwarded. ### What is the difference between 401 and 407? A 401 comes from the target server and means the application wants authentication. A 407 comes from a proxy in front of the target and means the proxy itself wants authentication. The fix targets a different credential in each case. ### How do I pass proxy credentials without storing them in the test plan? Use `-Jhttp.proxyUser` and `-Jhttp.proxyPass` on the command line, or set the properties in a user.properties file that stays out of version control. In CI pipelines, source the values from the secret store. ### Why does the test pass at home but fail at the office? The office network routes outbound traffic through an authenticating forward proxy that home connections do not use. Configure the proxy and its credentials in HTTP Request Defaults, or ask for a bypass for the load generator. Add the proxy server, port, username, and password to HTTP Request Defaults, then run one thread to confirm the 407 is gone before scaling up. - [API load testing](/topics/api-load-testing/) - [CI/CD load testing](/topics/ci-cd-load-testing/) - [HTTP Recorder](/topics/http-recorder/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter OutOfMemoryError Java heap space URL: https://docs.jmeter.ai/topics/errors/out-of-memory-heap/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # OutOfMemoryError: Java heap space in JMeter ## Symptom - JMeter exits or freezes with `java.lang.OutOfMemoryError: Java heap space` - Long GC pauses, injector becomes unresponsive - In containers: pod/container **OOMKilled** even without a clear Java stack - Often appears when increasing **threads**, enabling **View Results Tree**, or saving **full responses** ## Common causes Official [best practices](/user-manual/best-practices/) stress lean injectors: | Cause | Detail | |-------|--------| | Heap too small for threads | Roughly more concurrent threads → more live objects; default heap may be too low | | View Results Tree / heavy listeners | Keep detailed sample data in memory - **debug only** | | Too many threads on one JVM | Need more engines ([distributed](/topics/distributed-testing/)) or lower concurrency | | Saving too much | XML results, response data, large bodies | | Heavy scripts | BeanShell/JavaScript on hot paths; prefer JSR223 Groovy with compile cache | | Container limit below `-Xmx` | cgroup kills the process ([Docker/K8s](/topics/docker-kubernetes/)) | ## Fix (ordered) 1. **Switch to non-GUI for load** ```bash jmeter -n -t plan.jmx -l results.jtl -e -o report/ ``` 2. **Disable** View Results Tree, View Results in Table, and other heavy listeners for the load run (best practices). 3. **Size heap** for the injector using the [Heap Estimator](/tools/heap-estimator/) as a starting point; set `HEAP` / `JVM_ARGS` (for example `-Xms512m -Xmx2048m`) per your launch scripts, then restart JMeter. 4. **Reduce threads per engine**; scale out with multiple CLI instances or remote workers rather than one huge JVM. 5. Prefer **CSV** result files and only the saveservice fields you need ([dashboard requirements](/user-manual/generating-dashboard/)). 6. Replace expensive scripting with **JSR223 + Groovy**, cache compiled scripts, use `vars.get("x")` not embedded `\${x}` in cached scripts (best practices). 7. In Docker/K8s: set memory **limits above** `-Xmx` plus native overhead. 8. Re-test with a pilot; watch GC logs if problems continue. ## Related tools and topics | Resource | Use when | |----------|----------| | [Heap Estimator](/tools/heap-estimator/) | Starting `-Xmx` guess | | [Thread Calculator](/tools/thread-calculator/) | Fewer threads if RPS allows | | [Distributed testing](/topics/distributed-testing/) | Spread load across engines | | [Docker / Kubernetes](/topics/docker-kubernetes/) | cgroup OOM | | [Best practices](/user-manual/best-practices/) | Lean plan rules | ## Frequently asked questions ### Is OutOfMemoryError a server problem? Often it is the **JMeter injector**. Confirm with injector GC/heap metrics before blaming the SUT. ### Why does GUI mode OOM faster? GUI rendering plus listeners keep more objects alive. Official guidance: use GUI to build, CLI for load. ### How much heap do I need? It depends on threads, response sizes, scripting, and listeners. Start from the Heap Estimator, then validate under a pilot run. Disable View Results Tree, set a larger HEAP for a pilot CLI run, and re-check with the Heap Estimator if you still OOM. - [Heap Estimator](/tools/heap-estimator/) - [Best practices](/user-manual/best-practices/) - [CI/CD load testing](/topics/ci-cd-load-testing/) --- Title: JMeter OutOfMemoryError: unable to create new native thread URL: https://docs.jmeter.ai/topics/errors/outofmemory-unable-to-create-native-thread/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # java.lang.OutOfMemoryError: unable to create new native thread in JMeter ## Symptom When ramping up to hundreds or thousands of threads in a JMeter test plan, the test suddenly halts or crashes with an unrecoverable JVM fatal error in the console or `jmeter.log`: ```text java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:717) at org.apache.jmeter.threads.ThreadGroup.start(ThreadGroup.java:310) at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:490) ``` New virtual users fail to spawn, and the JMeter process may become unresponsive or terminate immediately. ## Quick diagnosis (TL;DR) This error is **not** caused by running out of Java Heap memory (`-Xmx`). It occurs when the Java Virtual Machine requests the underlying operating system kernel to allocate a new OS-level native thread, and the OS denies the request because the OS user process limit (`ulimit -u`), system PID limit (`kernel.pid_max`), or available native RAM for thread call stacks has been exhausted. ## Common causes | Cause | Layer | Why it happens | |-------|-------|----------------| | Linux user process limit (`ulimit -u`) | OS | Default `nproc` limit (often 1024 or 4096) reached by Java and background OS tasks | | Kernel PID limit | OS | System-wide `/proc/sys/kernel/pid_max` or `/proc/sys/vm/max_map_count` cap reached | | Large JVM thread stack size (`-Xss`) | JVM | Default stack size (1MB per thread) consumes all physical native RAM outside heap | | Oversized single-instance thread count | JMeter Plan | Attempting to spawn 5,000+ threads on a single load injector machine | | Thread leaks in plugins or Groovy | Custom Code | Third-party plugins or scripts spawning unmanaged `new Thread()` instances | ## Fix (ordered) ### 1. Increase Linux OS User Process & File Descriptor Limits On Linux load injector machines, edit `/etc/security/limits.conf`: ```text # Add at the bottom of /etc/security/limits.conf * soft nproc 65535 * hard nproc 65535 * soft nofile 65535 * hard nofile 65535 root soft nproc 65535 root hard nproc 65535 ``` Verify active limits in your current terminal session: ```bash ulimit -u # max user processes (should show 65535) ulimit -n # max open files (should show 65535) ``` ### 2. Increase System PID and Memory Map Limits Configure Linux kernel sysctl parameters: ```bash # Check current PID capacity sysctl kernel.pid_max sysctl vm.max_map_count # Temporarily increase limits sudo sysctl -w kernel.pid_max=4194304 sudo sysctl -w vm.max_map_count=262144 # Make permanent in /etc/sysctl.conf echo "kernel.pid_max = 4194304" | sudo tee -a /etc/sysctl.conf echo "vm.max_map_count = 262144" | sudo tee -a /etc/sysctl.conf sudo sysctl -p ``` ### 3. Tune JVM Thread Stack Size (`-Xss`) In Java, each thread receives a dedicated native memory stack outside the heap. By default, 64-bit JVMs allocate **1MB** per thread stack. If you run 2,000 threads, thread stacks alone consume 2GB of native RAM. Reduce thread stack size in your JMeter launch environment: ```bash # Set -Xss to 256k or 512k in bin/jmeter or environment variables export JVM_ARGS="-Xms4g -Xmx4g -Xss256k" jmeter -n -t test.jmx -l results.jtl -j jmeter.log ``` On Windows, edit `bin/jmeter.bat` or pass: ```bat set JVM_ARGS=-Xms4g -Xmx4g -Xss256k jmeter.bat -n -t test.jmx -l results.jtl ``` ### 4. Optimize Thread Sizing (Little's Law) Before scaling to thousands of threads, check if high thread counts are truly necessary. Many engineers add threads because responses are slow: ```text Threads = Target RPS × Average Response Time (seconds) ``` If your target is 500 RPS and the server responds in 100ms (0.1s), you only need **50 threads**, not 2,000. Use the [Thread Calculator](/tools/thread-calculator/) to calculate optimal concurrency. ### 5. Scale Out Horizontally with Distributed Testing When a single machine reaches hardware or kernel limitations (typically ~1,500–2,500 threads per modern server depending on test complexity), distribute the load across multiple JMeter server instances ([distributed testing guide](/topics/distributed-testing/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | Java heap space exhaustion | | [Metaspace & GC overhead](/topics/errors/metaspace-gc-overhead-limit/) | ClassLoader and Metaspace memory leaks | | [Thread Calculator](/tools/thread-calculator/) | Calculate required thread count from throughput targets | | [Heap Estimator](/tools/heap-estimator/) | Sizing JVM heap and native memory | | [Distributed testing](/topics/distributed-testing/) | Setting up multi-node remote load generators | ## Frequently asked questions ### Will increasing `-Xmx` (heap size) fix this error? **No.** In fact, increasing `-Xmx` can make this error happen *faster* on machines with limited RAM, because the JVM heap reserves more physical memory, leaving less native unmanaged RAM for OS thread stacks. ### How many threads can one JMeter instance safely run? On modern 64-bit Linux servers with properly tuned `ulimit` and `-Xss256k`, a single CLI instance can typically run between 1,000 and 3,000 threads for standard HTTP APIs. Complex scripts with heavy Groovy processing or large payload buffers should stay under 1,000 threads per injector. Adjust `ulimit -u` in `/etc/security/limits.conf` and set `JVM_ARGS="-Xss256k"` before your next high-concurrency run. - [Distributed testing](/topics/distributed-testing/) - [Best practices](/user-manual/best-practices/) - [Docker / Kubernetes](/topics/docker-kubernetes/) --- Title: JMeter OutOfMemoryError: Metaspace & GC overhead limit exceeded URL: https://docs.jmeter.ai/topics/errors/metaspace-gc-overhead-limit/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # OutOfMemoryError: Metaspace & GC overhead limit in JMeter ## Symptom During execution or extended soak tests, JMeter crashes with one of these JVM OutOfMemory errors in `jmeter.log` or console: ```text java.lang.OutOfMemoryError: Metaspace at java.lang.ClassLoader.defineClass1(Native Method) at groovy.lang.GroovyClassLoader.createSubClass(GroovyClassLoader.java:940) ``` Or when garbage collection takes up nearly 100% of CPU time with minimal memory recovered: ```text java.lang.OutOfMemoryError: GC overhead limit exceeded at org.apache.jmeter.threads.JMeterVariables.put(JMeterVariables.java:95) ``` Throughput drops to near zero, response times spike dramatically, and the load generator CPU spikes to 100% due to continuous full garbage collection cycles. ## Quick diagnosis (TL;DR) - **`OutOfMemoryError: Metaspace`**: The JVM class metadata area is exhausted. The most common cause is embedding `\${var}` variable interpolation inside JSR223 Groovy scripts, forcing the Groovy runtime to compile a brand-new Java class on every execution. - **`GC overhead limit exceeded`**: Java spent more than 98% of its total CPU time performing garbage collection and recovered less than 2% of the heap. ## Common causes | Cause | Error | Why it happens | |-------|-------|----------------| | In-script string interpolation (`\${var}`) | Metaspace | Using `vars.get("x")` vs `"Hello ${x}"` avoids generating millions of temporary dynamic classes that fill Metaspace | | Unchecked "Cache compiled script" | Metaspace / CPU | JSR223 elements re-parse and compile script source on every single sample execution | | Small default Metaspace cap | Metaspace | JVM default `-XX:MaxMetaspaceSize` is too constrained for large test plans with many plugins | | Heavy listener memory retention | GC Overhead | Listeners (View Results Tree, Graph Results) retaining millions of SampleResult objects in heap | | Large in-memory file buffers | GC Overhead | Reading large CSV files or response bodies entirely into Groovy script memory variables | ## Fix (ordered) ### 1. Fix Groovy Variable Interpolation (The #1 Metaspace Culprit) Never embed `\${variable_name}` directly inside JSR223 Groovy code. Groovy treats the script text as a template and generates a new class file every time the variable changes: ```groovy // ❌ WRONG: Leaks Metaspace and exhausts compilation cache! String token = "${auth_token}"; log.info("Processing user ${user_id}"); // ✅ CORRECT: Reuses compiled class, zero Metaspace growth String token = vars.get("auth_token"); log.info("Processing user " + vars.get("user_id")); ``` ### 2. Enable "Cache compiled script if available" In every **JSR223 PreProcessor**, **JSR223 PostProcessor**, **JSR223 Sampler**, and **JSR223 Assertion**: 1. Set **Language** to `groovy (Groovy ... / Groovy Scripting Engine)`. 2. Ensure the checkbox **Cache compiled script if available** is **checked**. 3. Always supply a unique **Compilation Key** if using script files. ```xml groovy true String id = vars.get("userId"); vars.put("processedId", id.toUpperCase()); ``` ### 3. Increase JVM Metaspace and Heap Configuration Set explicit Metaspace and Heap sizing in your launch environment: ```bash # Linux / macOS environment variables export JVM_ARGS="-Xms4g -Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC" jmeter -n -t test.jmx -l results.jtl -j jmeter.log ``` ```bat @REM Windows bin/jmeter.bat or set in terminal set JVM_ARGS=-Xms4g -Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC jmeter.bat -n -t test.jmx -l results.jtl ``` ### 4. Remove Memory-Heavy Listeners in CLI Mode During load tests, disable all visual listeners: - **Delete or disable**: View Results Tree, Summary Report, Aggregate Graph, View Results in Table. - Use only command-line logging (`-l results.jtl`) and generate the HTML dashboard after the test completes ([dashboard guide](/user-manual/generating-dashboard/)). ### 5. Tune Modern G1 Garbage Collector Ensure modern G1GC settings are configured for low pause times: ```properties # Recommended JVM arguments for high-throughput JMeter testing -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=45 ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | Standard Java heap memory troubleshooting | | [JSR223 Groovy script errors](/topics/errors/jsr223-groovy-script-errors/) | Resolving Groovy scripting exceptions | | [Heap Estimator](/tools/heap-estimator/) | Sizing JVM heap and Metaspace memory | | [Best practices](/user-manual/best-practices/) | Official performance tuning guidelines | ## Frequently asked questions ### Why does Metaspace keep growing even when heap is healthy? Metaspace lives in native memory outside the Java heap. If Groovy compiles new classes dynamically (due to `\${var}` string interpolation), these classes are loaded into Metaspace and are rarely garbage collected unless classloaders are completely unloaded. ### What is the difference between Heap OOM and Metaspace OOM? Heap OOM means Java objects (byte arrays, strings, collections) filled `-Xmx`. Metaspace OOM means loaded class metadata filled `-XX:MaxMetaspaceSize`. Audit all JSR223 elements to replace `\${var}` interpolation with `vars.get("var")` and verify that script caching is enabled. - [JSR223 Groovy errors](/topics/errors/jsr223-groovy-script-errors/) - [Heap Estimator](/tools/heap-estimator/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Too Many Open Files (ulimit) URL: https://docs.jmeter.ai/topics/errors/too-many-open-files-ulimit/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Too Many Open Files in JMeter ## Symptom At high thread counts, samplers fail in the **View Results Tree** listener or `jmeter.log` with: ```text Response code: Non HTTP response code: java.net.SocketException Response message: Non HTTP response message: Too many open files ``` CSV reading or log writing can fail with the same root cause: ```text java.io.IOException: Too many open files ``` The test usually passes with fewer threads and fails only once concurrency crosses a threshold. ## Quick diagnosis (TL;DR) Every open TCP connection, CSV file, and log handle consumes one operating system file descriptor. When the count exceeds the per-process limit (often 1024 on Linux, 256 on macOS), the JVM cannot open another socket and the sampler fails. Raise the limit in the shell that starts JMeter, or reduce how many descriptors each thread needs. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | High concurrency with short-lived connections | `SocketException: Too many open files` | Each request opens a new socket, and descriptors pile up faster than the OS reclaims them | | Low default descriptor limit | Same error near 1024 or 256 active connections | Many Linux distributions default to a 1024 soft limit; macOS defaults to 256 | | Keep-Alive disabled | Socket count grows with thread count | Without connection reuse, one thread can hold many sockets across embedded resources | | Listeners and CSV files in large plans | `IOException: Too many open files` | Open result files and data sets add to the descriptor count | | Limit raised in the wrong shell | Error persists after `ulimit -n` | The new limit applies only to processes started from that shell session | ## Fix (ordered) ### 1. Confirm the current limit and usage Check the soft limit of the shell you start JMeter from: ```bash ulimit -n ``` For a running JMeter process, inspect the actual ceiling and current usage: ```bash # Linux: hard and soft limits of the JVM process cat /proc//limits | grep "open files" # Count currently open descriptors lsof -p | wc -l ``` If the open count sits at the limit when failures start, this diagnosis is confirmed. ### 2. Raise the limit in the launching shell File descriptor limits are inherited at process start, so raise the limit first and launch JMeter from the same shell: ```bash ulimit -n 65536 ./jmeter ``` A value of 65536 comfortably covers large single-machine tests. Setting the limit only in a different terminal, or after JMeter started, has no effect on the running JVM. ### 3. Make the limit persistent (Linux) Shell changes vanish on logout. For a permanent limit, edit `/etc/security/limits.conf` (requires root): ```text * soft nofile 65536 * hard nofile 65536 ``` If JMeter runs as a systemd service, set the limit in the unit file instead: ```ini [Service] LimitNOFILE=65536 ``` ### 4. Make the limit persistent (macOS) ```bash # Session limit ulimit -n 65536 # System-wide (survives reboot) sudo launchctl limit maxfiles 65536 200000 ``` ### 5. Reduce descriptors per thread Raising the limit treats the symptom; connection reuse lowers the demand: - Enable **Use KeepAlive** in **HTTP Request Defaults** so threads reuse connections instead of opening one per request. - Run in CLI mode (`-n`) with no GUI listeners; visual listeners hold extra file handles. - Close CSV Data Sets that are no longer needed, and avoid opening a fresh file per iteration. ### 6. Verify under load Re-run the test at the failing concurrency and watch descriptor usage during the run: ```bash watch -n 5 "lsof -p | wc -l" ``` Usage should now plateau well below the limit. If it grows without bound, keep-alive is not taking effect; re-check that the server actually honors persistent connections. ## Related tools and topics | Resource | Use when | |----------|----------| | [BindException / Address in use](/topics/errors/bind-exception-address-in-use/) | The related ephemeral port exhaustion error | | [Thread Calculator](/tools/thread-calculator/) | Estimating how much concurrency the generator should produce | | [Best practices](/user-manual/best-practices/) | Listener and CLI-mode guidance for large tests | | [Docker / Kubernetes](/topics/docker-kubernetes/) | Container runtimes apply their own descriptor limits | ## Frequently asked questions ### What does Too many open files mean in JMeter? The JVM tried to open a socket or file but the operating system refused because the process reached its file descriptor limit. It is an OS resource limit error, not a JMeter bug. ### How do I check how many file descriptors JMeter is using? On Linux, count them with `lsof -p | wc -l` and compare against `cat /proc//limits`. On macOS, use `lsof -p ` the same way. ### Why does raising ulimit in another terminal not fix JMeter? Limits are inherited when a process starts. The shell where you run `ulimit -n` must be the same shell that launches JMeter, and the change does not reach processes that are already running. ### Should I set the limit to unlimited? Prefer an explicit large value such as 65536. An unlimited setting can mask descriptor leaks, and the real fix is usually keep-alive plus a sane limit, not no limit at all. Raise the descriptor limit in the launching shell, enable Use KeepAlive, then re-run the test and watch the open descriptor count stay below the ceiling. - [Distributed testing](/topics/distributed-testing/) - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter Throughput Stuck Below Target RPS URL: https://docs.jmeter.ai/topics/errors/throughput-stuck/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Throughput stuck / not reaching target RPS ## Symptom - You aimed for a target **requests per second** (or “users”) but the [dashboard](/user-manual/generating-dashboard/) **hits/s** or throughput plateaus lower - Active threads may be high while throughput stays flat - Latency percentiles rise as you add threads - Results can look “too good” if you under-issue load relative to the schedule ([coordinated omission](/user-manual/best-practices/)) ## Common causes | Cause | What to check | |-------|----------------| | Not enough threads for target RPS | Little’s Law style sizing: threads ≈ RPS × response time (seconds) when busy ([Thread Calculator](/tools/thread-calculator/)) | | Response time grew under load | Server saturation; each thread completes fewer iterations | | View Results Tree / heavy listeners | Injector CPU burned on UI I/O ([best practices](/user-manual/best-practices/)) | | Think time / timers | By design lower RPS; expected for paced users | | Assertions and scripting cost | Too many expensive checks/scripts per sample | | Injector CPU, NIC, or heap pressure | One machine cannot generate the offered load | | SUT throttling | Rate limits, pool exhaustion, 429/503 | | Ramp still running | Steady-state not reached yet | Official best practices: incorrect thread sizing contributes to **coordinated omission** and inaccurate results. Use CLI for real load: `jmeter -n -t plan.jmx -l results.jtl`. ## Fix (ordered) 1. Measure **average response time** with a small pilot under CLI. 2. Estimate threads with the [Thread Calculator](/tools/thread-calculator/); add ramp-up (avoid 0-second ramp to huge threads). 3. Disable heavy listeners; write results with `-l` only. 4. Run long enough to leave ramp and warm-up. 5. Compare **achieved hits/s** to target; if RT rose, recompute threads or lower target. 6. Use the [Coordinated Omission](/tools/coordinated-omission/) helper when actual RPS is below target RPS to quantify skew. 7. Check injector CPU and GC; raise heap only if needed ([Heap Estimator](/tools/heap-estimator/)), or split engines ([distributed testing](/topics/distributed-testing/)). 8. Inspect SUT metrics (CPU, DB pools, rate limits) before adding infinite threads. 9. Gate CI on error % and percentiles, not only “threads configured” ([CI/CD](/topics/ci-cd-load-testing/), [APDEX/SLOs](/topics/apdex-slo-percentiles/)). ## Related tools and topics | Resource | Use when | |----------|----------| | [Thread Calculator](/tools/thread-calculator/) | Initial concurrency | | [Coordinated Omission](/tools/coordinated-omission/) | Actual RPS below target | | [Best practices](/user-manual/best-practices/) | Lean load generation | | [Socket closed / reset](/topics/errors/socket-closed-connection-reset/) | Errors cap throughput | ## Frequently asked questions ### Does more threads always mean more RPS? No. After the server saturates, extra threads mostly increase queueing and response time, not useful throughput. ### Why is calculated RPS higher than the dashboard? Calculators assume stable service time and little think time. Under load, service time rises and timers reduce rate. ### Is flat throughput with rising errors a success? No. Prefer healthy throughput with low error % and controlled percentiles ([glossary](/user-manual/glossary/)). Run a CLI pilot, capture average RT, size threads with the Thread Calculator, then compare achieved hits/s on the HTML dashboard. - [Thread Calculator](/tools/thread-calculator/) - [Coordinated Omission](/tools/coordinated-omission/) - [APDEX SLOs percentiles](/topics/apdex-slo-percentiles/) --- Title: JMeter Freezing, 100% CPU Usage & CLI Hanging at End URL: https://docs.jmeter.ai/topics/errors/jmeter-freeze-high-cpu-hanging/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JMeter Freezing, 100% CPU Usage & CLI Hanging ## Symptom You encounter one of the following performance bottlenecks on the load generator machine: 1. **JMeter GUI completely freezes / becomes unresponsive**: The window grays out or locks up during a test run. 2. **100% CPU saturation on the load injector**: JMeter consumes all CPU cores on the testing host, causing request times to distort and throughput to plateau. 3. **CLI execution hangs at the end of a test**: The test duration finishes, but the terminal command prompt never returns, and the process remains stuck indefinitely. ## Quick diagnosis (TL;DR) - **GUI Freeze**: Running tests with active listeners (e.g. View Results Tree) in GUI mode consumes memory and blocks the Swing event dispatch thread. - **100% CPU on Injector**: Caused by CPU-intensive JSR223 Groovy parsing (missing cache), catastrophic regex backtracking, full GC loops, or excessive disk logging. - **CLI Hang**: Non-daemon background threads (unclosed DB connections, async listeners, or alive RMI engines) preventing the JVM from exiting. ## Common causes | Symptom | Primary Cause | Why it happens | |---------|---------------|----------------| | GUI Freeze | Listeners in GUI | View Results Tree stores full XML/JSON response payloads in RAM, blocking UI threads | | 100% CPU | Inefficient RegEx / Groovy | Complex regex patterns with catastrophic backtracking, or recompiling Groovy scripts | | 100% CPU | Continuous Garbage Collection | Java Heap nearly full, triggering back-to-back Full GC pauses | | CLI Hang | Non-daemon active threads | Custom plugins, Backend Listeners (InfluxDB/Kafka), or open JDBC pools blocking process exit | | CLI Hang | Remote RMI engines | Distributed testing controller waiting for unresponsive worker nodes | ## Fix (ordered) ### 1. Always Run Load Tests in Non-GUI (CLI) Mode Never use the JMeter GUI for actual load generation. Use GUI strictly for test plan creation and debugging with 1–2 virtual users: ```bash # Standard Non-GUI execution command jmeter -n -t testplan.jmx -l results.jtl -j jmeter.log ``` ### 2. Diagnose Active Threads with a JVM Thread Dump When a CLI test hangs or freezes, take a thread dump to identify the exact blocking thread: ```bash # 1. Find the JMeter process ID jps -v | grep ApacheJMeter # 2. Capture the stack trace of all running threads jstack > thread_dump.txt ``` Look for threads in the `RUNNABLE` or `BLOCKED` state: - `BackendListener` or `InfluxDBRawData`: Waiting for remote metrics flush. - `StandardJMeterEngine`: Waiting for lingering worker threads to exit. - `HikariPool` / `JDBC`: Open database connection pool connections. ### 3. Force CLI Process Exit on Test Completion If a third-party plugin or listener leaves background non-daemon threads open, configure JMeter to force JVM exit when the test finishes: Add to `bin/user.properties` or pass via CLI: ```properties # Force JVM exit (System.exit(0)) when engine finishes test jmeterengine.force.system.exit=true # Maximum time (in milliseconds) to wait for threads to stop on shutdown jmeterengine.threadstop.wait=5000 ``` ### 4. Optimize Regex and JSR223 CPU Overhead - Replace complex Regular Expression Extractors with **Boundary Extractor** (significantly faster, zero CPU regex overhead). - Ensure all JSR223 elements use **Groovy** with **"Cache compiled script if available"** checked. - Never use BeanShell (BeanShell is 10–20x slower and CPU-heavy compared to Groovy). ### 5. Check Disk I/O Bottlenecks and Log Levels Writing verbose debug logs during a 1,000 RPS test saturates disk I/O and locks CPU threads: 1. Ensure `jmeter.log` level is set to `INFO` or `WARN` in `bin/log4j2.xml`. 2. Save only required fields in `results.jtl`: ```properties # Keep JTL output minimal for maximum throughput jmeter.save.saveservice.output_format=csv jmeter.save.saveservice.response_data=false jmeter.save.saveservice.samplerData=false jmeter.save.saveservice.requestHeaders=false jmeter.save.saveservice.url=true jmeter.save.saveservice.response_code=true ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | Differences between GUI and CLI execution | | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | Heap memory exhaustion troubleshooting | | [CLI Command Builder](/tools/cli-builder/) | Generate clean CLI commands with proper flags | | [Best practices](/user-manual/best-practices/) | Official tuning guidelines | ## Frequently asked questions ### Why does JMeter hang at the end when using InfluxDB Backend Listener? The Backend Listener buffers metrics and attempts to flush remaining data to InfluxDB over HTTP. If the InfluxDB server is slow or unreachable, the listener blocks until timeout. Set `summaryOnly=true` or lower the client timeout. ### How do I stop a hung JMeter CLI test safely? Run `./bin/stoptest.sh` (or `stoptest.bat` on Windows) from a separate terminal. This instructs JMeter to gracefully terminate thread groups. If it remains stuck, use `./bin/shutdown.sh`. Run your test in CLI mode with `jmeter -n -t plan.jmx -l results.jtl` and verify that `jmeterengine.force.system.exit=true` is set. - [CLI Command Builder](/tools/cli-builder/) - [Best practices](/user-manual/best-practices/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter Won't Start or Crashes on Launch URL: https://docs.jmeter.ai/topics/errors/jmeter-wont-start-crash-on-launch/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JMeter Won't Start or Crashes on Launch ## Symptom Double-clicking `jmeter.bat` (Windows) or `jmeter.sh` (Linux/macOS) produces one of these behaviors: ```text The window appears for a fraction of a second, then closes by itself. ``` Or the terminal shows one of these errors: ```text 'java' is not recognized as an internal or external command ``` ```text java.lang.UnsupportedClassVersionError: org/apache/jmeter/NewDriver ``` ```text Error occurred during initialization of VM Could not reserve enough space for object heap ``` ```text Error: Could not find or load main class org.apache.jmeter.NewDriver ``` ## Quick diagnosis (TL;DR) JMeter is a Java application, so startup failures almost always come from the JVM environment, not from the test plan: Java is missing from the PATH, the installed Java version is unsupported, or the requested heap is larger than the machine's memory. Launch JMeter from a terminal instead of double-clicking, because the terminal shows the real error that the GUI hides. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | Java not installed or not on PATH | `'java' is not recognized` | No JDK/JRE installed, or `JAVA_HOME`/`PATH` not set | | Java version too old | `UnsupportedClassVersionError` | JMeter 5.x requires Java 8 or newer; an older runtime cannot load the classes | | Heap larger than available memory | `Could not reserve enough space for object heap` | `JVM_ARGS` or `HEAP` requests more RAM than the machine has | | Incomplete or corrupt installation | `Could not find or load main class org.apache.jmeter.NewDriver` | Missing files from a partial unzip or a broken copy | | macOS Gatekeeper block | "cannot be opened because the developer cannot be verified" | The downloaded archive carries a quarantine attribute | ## Fix (ordered) ### 1. Launch from a terminal to see the real error The GUI swallows startup errors. Open a terminal in the JMeter `bin/` directory and run: ```bash # Linux / macOS cd /path/to/jmeter/bin ./jmeter # Windows (cmd.exe) cd C:\path\to\jmeter\bin jmeter.bat ``` The stack trace printed here tells you which of the fixes below applies. ### 2. Verify the Java version JMeter 5.6 requires Java 8 or newer; a current LTS JDK such as 17 or 21 is recommended for load generators. ```bash java -version ``` If the command is not found, install a JDK (for example Eclipse Temurin) and open a new terminal so the PATH update takes effect. If the version is older than 8, upgrade: the `UnsupportedClassVersionError` disappears once a supported runtime starts JMeter. ### 3. Fix the JVM heap reservation The startup scripts default to `-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m`, which is read from the `JVM_ARGS` (Linux/macOS) or `HEAP` (Windows) environment variables. If someone raised these beyond the machine's physical memory, the JVM refuses to start. Start JMeter with a sane heap: ```bash # Linux / macOS: heap for this launch only JVM_ARGS="-Xms1g -Xmx2g" ./jmeter # Windows (cmd.exe) set HEAP=-Xms1g -Xmx2g jmeter.bat ``` Keep `-Xmx` below the machine's free physical RAM. For heap sizing on real load tests, use the [Heap & Memory Estimator](/tools/heap-estimator/). ### 4. Reinstall cleanly `Could not find or load main class org.apache.jmeter.NewDriver` means files are missing. Download the full archive from [jmeter.apache.org](https://jmeter.apache.org/), extract it completely, and confirm that `bin/ApacheJMeter.jar` exists. Avoid extracting into folders synced or locked by security software. ### 5. macOS: clear the quarantine attribute If macOS refuses to open JMeter after download: ```bash xattr -d com.apple.quarantine /path/to/jmeter chmod +x /path/to/jmeter/bin/jmeter.sh ``` Alternatively, right-click the launcher and choose Open, then confirm the prompt once. ### 6. Docker and CI containers In containers the same JVM rules apply, plus two extras: set `JAVA_HOME` explicitly in the image, and pass the heap through the container's environment rather than editing the scripts: ```bash docker run -e JVM_ARGS="-Xms1g -Xmx2g" -v $(pwd):/jmx jmeter -n -t /jmx/plan.jmx -l /jmx/results.jtl ``` A container killed at startup with exit code 137 was OOM-killed by the orchestrator: raise the container memory limit or lower `-Xmx`. See [Docker / Kubernetes](/topics/docker-kubernetes/) for full setup. ## Related tools and topics | Resource | Use when | |----------|----------| | [Download JMeter](/reference/download-jmeter/) | Getting a clean, current installation | | [Heap & Memory Estimator](/tools/heap-estimator/) | Calculating `-Xms`, `-Xmx`, and Metaspace for real load | | [CLI Command Builder](/tools/cli-builder/) | Building correct non-GUI launch commands | | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | JMeter starts but dies during the test | | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | Startup is fine but the CLI run behaves differently | ## Frequently asked questions ### Why does the JMeter window flash and close immediately? The GUI hides console errors, so a failed startup looks like a window that closes itself. Launch `jmeter.bat` or `./jmeter` from a terminal: the printed stack trace names the actual cause, usually Java, heap, or a broken installation. ### Which Java version does JMeter need? JMeter 5.x requires Java 8 or newer, and a current LTS JDK such as 17 or 21 is recommended for load generators. Verify with `java -version` and install a JDK if the command is missing. ### How do I give JMeter more memory if it won't start? The startup scripts read `-Xms1g -Xmx1g` defaults from the `JVM_ARGS` (Linux/macOS) or `HEAP` (Windows) environment variables. Set them to values your machine actually has before launching, for example `JVM_ARGS="-Xms1g -Xmx2g" ./jmeter`. ### Can a corrupt test plan stop JMeter from starting? No. Test plans load after startup, so a broken JMX cannot prevent the GUI from opening. If JMeter itself does not open, the cause is the Java runtime, the heap, or the installation, not the plan. Run JMeter from a terminal, note the exact error, then apply the matching fix above before retrying the GUI. - [JMeter for beginners](/topics/jmeter-for-beginners/) - [Docker / Kubernetes](/topics/docker-kubernetes/) - [CI/CD load testing](/topics/ci-cd-load-testing/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter Test Stops Early or Unexpectedly URL: https://docs.jmeter.ai/topics/errors/test-stops-early-unexpectedly/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JMeter Test Stops Early or Unexpectedly ## Symptom A test ends well before its intended duration or loop count: ```text The CLI summary prints far fewer samples than expected, and the run exits. ``` `jmeter.log` may contain lines such as: ```text INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test ``` and the results file simply stops at some timestamp. ## Quick diagnosis (TL;DR) JMeter ends a test for a small number of reasons: a configured duration expired, a sampler or assertion failure triggered a stop action, a controller finished the flow, or the JVM crashed. Check the Thread Group scheduler and the "Action to be taken after a Sampler error" setting first, then look for the failing sample. ## Common causes | Cause | Where to look | Why it happens | |-------|---------------|----------------| | Scheduler duration set | Thread Group, **Specify Thread lifetime** | **Duration (seconds)** ends the test after that many seconds, regardless of loops | | Sampler error action is Stop Test | Thread Group bottom panel | The first failed sample or failed assertion ends the whole run | | Assertion failures count as errors | Any assertion in scope | A failing Response Assertion marks the sample failed, which feeds the stop action | | Loop or While Controller condition | Controller logic | The condition evaluates false and the flow exits sooner than expected | | JVM crash | OS logs, no clean shutdown | Out of memory or a killed process ends the run without JMeter's own log lines | | Manual or remote stop | Run menu, remote engines | Someone stopped the test, or a remote engine disconnected | ## Fix (ordered) ### 1. Check the Thread Group scheduler Open the Thread Group and look at the **Specify Thread lifetime** checkbox: 1. If it is checked, **Duration (seconds)** caps the run. Raise it or uncheck the box so loop count controls the length. 2. **Startup delay (seconds)** only postpones the start; it does not extend the run. ### 2. Review the sampler error action The Thread Group's **Action to be taken after a Sampler error** decides what a failed sample does. The five options: - `Continue` - ignore the error and continue with the test - `Start next thread loop` - skip the rest of the current iteration and restart the loop - `Stop Thread` - the current thread exits - `Stop Test` - the entire test stops at the end of any current samples - `Stop Test Now` - the entire test stops abruptly, interrupting current samplers During debugging and in most load tests, use `Continue`. Reserve `Stop Test` for smoke tests where a failure invalidates the whole run. ### 3. Find the sample that triggered the stop With `Continue` in place, re-run with one thread in the GUI with a **View Results Tree** listener, or inspect the results of the failed run: 1. Look for the first red sample before the run ended. 2. Check its assertions: a failing assertion marks the sample failed even when the HTTP status was 200. 3. Fix the underlying request or loosen the assertion, depending on which is wrong. ### 4. Rule out a JVM crash If `jmeter.log` has no clean end-of-test lines and the process simply vanished: 1. Check OS logs (`dmesg` on Linux, Event Viewer on Windows) for an OOM kill. 2. Check heap sizing with the [Heap & Memory Estimator](/tools/heap-estimator/). 3. Follow [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) or [Freezing, CPU & CLI Hangs](/topics/errors/jmeter-freeze-high-cpu-hanging/) depending on what the logs show. ### 5. Check controller conditions A **Loop Controller** with a lower count than expected, a **While Controller** whose condition flips early, or a **Throughput Controller** percentage can all end a thread's work before the Thread Group's own loop count finishes. Trace the flow with one thread and confirm each controller executes as often as intended. ## Related tools and topics | Resource | Use when | |----------|----------| | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | The run died from memory pressure | | [Freezing, CPU & CLI Hangs](/topics/errors/jmeter-freeze-high-cpu-hanging/) | The run hangs instead of stopping cleanly | | [Thread Calculator](/tools/thread-calculator/) | Recomputing realistic durations and concurrency | | [Building a Test Plan](/user-manual/build-test-plan/) | Thread Group scheduler fundamentals | ## Frequently asked questions ### Why did my JMeter test stop after only a few seconds? Usually the Thread Group scheduler: **Specify Thread lifetime** is checked with a short **Duration (seconds)**. The other common cause is a sampler error action set to `Stop Test` combined with an early failing sample. ### Where do I see why JMeter stopped the test? Check `jmeter.log` for end-of-test messages, then the results file for the last samples. A clean stop shows listener notifications; a crash leaves no end-of-test lines at all, which points to the JVM dying. ### Should I use Stop Test on sampler error for load tests? Usually not. Load tests expect some failures under pressure, and `Continue` keeps the measurement going. Use `Stop Test` only for smoke tests where any failure makes the rest of the run meaningless. ### Can a failing assertion stop the whole test? Yes. A failed assertion marks its sample as failed, and the Thread Group's sampler error action then applies to it exactly like a transport error. Fix the assertion or change the action to `Continue`. Check the Thread Group scheduler duration and set the sampler error action to Continue, then re-run with one thread to see which sample, if any, was failing. - [Building a Test Plan](/user-manual/build-test-plan/) - [Best practices](/user-manual/best-practices/) - [CI/CD load testing](/topics/ci-cd-load-testing/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter JSR223 Groovy Script Errors & Exceptions URL: https://docs.jmeter.ai/topics/errors/jsr223-groovy-script-errors/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JSR223 Groovy Script Errors in JMeter ## Symptom When executing JSR223 Samplers, PreProcessors, PostProcessors, or Assertions, samples turn red or errors appear in `jmeter.log`: ```text 2026-08-18 10:15:32,410 ERROR o.a.j.m.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: token for class: Script1 at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:324) ``` Or for null pointers when accessing variables: ```text java.lang.NullPointerException: Cannot invoke method split() on null object at Script1.run(Script1.groovy:4) ``` The error causes the sampler to fail and logs a stack trace for every virtual user thread execution. ## Quick diagnosis (TL;DR) - **`MissingPropertyException`**: You referenced an undeclared variable directly (e.g. `println token`) instead of accessing it via the JMeter variables object (`vars.get("token")`). - **`NullPointerException`**: `vars.get("name")` returned `null` because the variable was never created or an upstream extractor failed to find a match. - **`Compilation Cache Full` / High CPU**: Script text contains `\${var}` string interpolation instead of using `vars.get("var")`. ## Essential JSR223 Implicit Objects Reference JMeter automatically injects predefined context objects into Groovy scripts: | Object | Class | Scope & Purpose | |--------|-------|-----------------| | `vars` | `JMeterVariables` | Thread-scoped read/write (`vars.get("k")`, `vars.put("k", "v")`, `vars.putObject("k", obj)`) | | `props` | `JMeterProperties` | Global cross-thread properties (`props.get("p")`, `props.put("p", "v")`) | | `prev` | `SampleResult` | Previous sampler result (`prev.getResponseDataAsString()`, `prev.setSuccessful(false)`) | | `sampler` | `Sampler` | Current sampler object (`sampler.setName("New Name")`) | | `ctx` | `JMeterContext` | Engine context (`ctx.getThreadNum()`, `ctx.getPreviousResult()`) | | `log` | `Logger` | Log4j2 logger (`log.info("msg")`, `log.error("err", exception)`) | ## Fix (ordered) ### 1. Always Use `vars.get()` and `vars.put()` (Never Direct Variables) In Groovy, JMeter variables are **not** global script variables. Always access them via the `vars` object: ```groovy // ❌ WRONG: Throws MissingPropertyException if not declared in script String myId = userId; // ❌ WRONG: String interpolation breaks compilation caching and leaks Metaspace! String myId = "${userId}"; // ✅ CORRECT: Safe retrieval with null checking String myId = vars.get("userId"); if (myId != null) { vars.put("processedUserId", myId.trim().toUpperCase()); } else { log.warn("Variable 'userId' was null! Upstream extractor may have failed."); } ``` ### 2. Defensively Handle Null Values If an upstream JSON Extractor or Regex Extractor fails, `vars.get()` returns `null`. Add safe navigation (`?.`) or explicit null guards: ```groovy // Using Groovy safe navigation operator String rawResponse = prev?.getResponseDataAsString(); String authToken = vars.get("authToken"); if (!authToken) { // Fail the sample deliberately with a clear error message prev.setSuccessful(false); prev.setResponseMessage("Missing required authToken from previous step"); prev.setResponseCode("500"); return; } ``` ### 3. Share Data Between Different Thread Groups with `props` `vars` are strictly isolated per thread. If Thread Group A extracts a token needed by Thread Group B, use `props`: ```groovy // In Thread Group A (Writer) props.put("GLOBAL_AUTH_TOKEN", vars.get("authToken")); // In Thread Group B (Reader) String globalToken = props.get("GLOBAL_AUTH_TOKEN"); vars.put("localToken", globalToken); ``` ### 4. Enable Script Caching In every JSR223 component: 1. Ensure **Language** is set to `groovy`. 2. Check **Cache compiled script if available**. 3. Do **not** put dynamic values in the script body; use `vars.get()` or script **Parameters**: - Parameters: `\${__threadNum} \${userId}` - Script access: `String p0 = args[0];` ### 5. Parse JSON and XML Safely with Groovy Builders Use built-in Groovy parsers instead of manual regex string manipulation: ```groovy import groovy.json.JsonSlurper import groovy.json.JsonOutput try { def json = new JsonSlurper().parseText(prev.getResponseDataAsString()) String itemId = json.data.items[0].id vars.put("firstItemId", itemId) } catch (Exception e) { log.error("Failed to parse JSON response: " + e.getMessage(), e) prev.setSuccessful(false) } ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [Metaspace & GC overhead](/topics/errors/metaspace-gc-overhead-limit/) | Fixing Metaspace leaks caused by Groovy scripts | | [Functions and variables](/topics/functions-and-variables/) | Built-in JMeter functions guide | | [Correlation & dynamic values](/topics/correlation-dynamic-values/) | Extracting and passing dynamic values | | [Best practices](/user-manual/best-practices/) | Scripting language performance recommendations | ## Frequently asked questions ### Should I use BeanShell or Groovy for scripting in JMeter? Always use **Groovy (JSR223)**. Groovy compiles down to native Java bytecode and supports script compilation caching, making it 10x to 50x faster than BeanShell. BeanShell is deprecated for high-load testing. ### Why do my changes to `vars` not appear in other threads? `vars` (`JMeterVariables`) are local to the current thread. To pass data across threads, use `props.put("key", value)` and `props.get("key")`. Audit your JSR223 Groovy scripts to replace `\${var}` interpolation with `vars.get("var")` and verify `null` checks. - [Functions and variables](/topics/functions-and-variables/) - [Correlation & dynamic values](/topics/correlation-dynamic-values/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter ClassNotFoundException & NoClassDefFoundError URL: https://docs.jmeter.ai/topics/errors/class-not-found-noclassdeffound/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # ClassNotFoundException & NoClassDefFoundError in JMeter ## Symptom When starting JMeter, opening a JMX file, or running a test involving JDBC, custom plugins, or Groovy libraries, an error occurs in the console or `jmeter.log`: ```text java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ``` Or when opening a Test Plan that depends on an uninstalled plugin: ```text 2026-08-18 11:20:01 ERROR o.a.j.g.a.Load: Unexpected error java.lang.NoClassDefFoundError: kg/apc/jmeter/vizualizers/CorrectedResultCollector ``` The test fails to start, or samplers throw runtime exceptions during execution. ## Quick diagnosis (TL;DR) `ClassNotFoundException` and `NoClassDefFoundError` occur when JMeter's Java ClassLoader cannot find a required `.jar` file on its classpath. The fix is placing the missing JAR file into the correct directory (`lib/` for drivers/libraries vs `lib/ext/` for JMeter plugins) and **restarting JMeter**. ## JMeter Classpath Architecture: `lib/` vs `lib/ext/` JMeter uses a hierarchical classloader structure: | Directory | What belongs here | Examples | |-----------|-------------------|----------| | `JMETER_HOME/lib/` | Utility JARs, 3rd-party dependencies, JDBC database drivers, messaging client JARs | `mysql-connector-j-8.x.jar`, `postgresql-42.x.jar`, `ojdbc8.jar`, `kafka-clients.jar` | | `JMETER_HOME/lib/ext/` | JMeter GUI components, visualizers, samplers, and official plugin bundles | `jmeter-plugins-cmn-jmeter.jar`, `jmeter-plugins-webdriver.jar` | | `JMETER_HOME/lib/junit/` | JUnit test classes if using the JUnit Sampler | Custom compiled JUnit test JARs | :::important[Always Restart JMeter] Java cannot dynamically reload JAR files dropped into `lib/` or `lib/ext/` while JMeter is running. You must restart JMeter (or re-run the CLI command) for new JARs to take effect. ::: ## Fix (ordered) ### 1. Fix Missing Database JDBC Drivers For database testing (JDBC Connection Configuration), download the JDBC driver `.jar` and place it into `JMETER_HOME/lib/`: - **MySQL**: `mysql-connector-j-8.x.jar` -> `lib/` - **PostgreSQL**: `postgresql-42.x.jar` -> `lib/` - **Oracle**: `ojdbc8.jar` -> `lib/` - **Microsoft SQL Server**: `mssql-jdbc-xx.jar` -> `lib/` ```bash # Example: Copying PostgreSQL driver to JMeter lib directory cp postgresql-42.7.3.jar /opt/apache-jmeter/lib/ ``` ### 2. Install Missing Plugins via JMeter Plugins Manager If a `.jmx` script contains elements prefixed with `kg.apc.jmeter` (Custom Thread Groups, Dummy Sampler, Throughput Shaping Timer): 1. Download **`jmeter-plugins-manager.jar`** from [jmeter-plugins.org](https://jmeter-plugins.org). 2. Place it into `JMETER_HOME/lib/ext/`. 3. Start JMeter GUI -> **Options** -> **Plugins Manager**. 4. The Plugins Manager will detect any missing plugins in the loaded test plan and offer to install them automatically with one click. ### 3. Add Custom JARs via `user.properties` (Without Copying Files) If you maintain a shared repository of corporate JARs or CI/CD dependencies, add them to `user.properties` without moving files: ```properties # Add custom directory or individual JAR paths (comma or semicolon separated) user.classpath=/opt/shared/jars/custom-crypto.jar;/opt/shared/drivers/ plugin_dependency_paths=/opt/jmeter/plugins/ ``` ### 4. Provide Dynamic Classpath in CLI Runs When running in CI/CD pipelines (GitHub Actions / Jenkins / Docker): ```bash # Pass user.classpath dynamically via command line jmeter -n -t plan.jmx -Juser.classpath=/libs/mysql.jar -l results.jtl -j jmeter.log ``` ### 5. Verify Distributed Testing Worker Nodes In distributed testing, every remote worker node (`jmeter-server`) **must have identical JAR files** installed in their respective `lib/` and `lib/ext/` folders. The controller does not transmit JAR files to workers over RMI. ## Related tools and topics | Resource | Use when | |----------|----------| | [JDBC Connection Pool errors](/topics/errors/jdbc-connection-pool-errors/) | Resolving database connection errors | | [Plugins Essentials](/topics/plugins-essentials/) | Installing and managing JMeter plugins | | [CLI Command Builder](/tools/cli-builder/) | Building CLI commands with custom property flags | | [Distributed testing](/topics/distributed-testing/) | Syncing dependencies across worker nodes | ## Frequently asked questions ### Can I put JDBC drivers into `lib/ext/`? Putting JDBC drivers in `lib/ext/` can cause classloader conflicts or failure to register with Java's `DriverManager`. Always place utility libraries and database drivers in `lib/`, and place JMeter GUI plugins in `lib/ext/`. ### Why does the script fail in CI/CD when it worked on my laptop? Your local JMeter installation has plugins or JDBC drivers in `lib/` or `lib/ext/` that were not packaged into the CI/CD Docker image or runner environment. Place the missing JAR file into `JMETER_HOME/lib/` (or `lib/ext/` for plugins) and restart JMeter. - [JDBC Connection Pool errors](/topics/errors/jdbc-connection-pool-errors/) - [Plugins Essentials](/topics/plugins-essentials/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Won't Open a Test Plan (JMX Load Errors) URL: https://docs.jmeter.ai/topics/errors/jmx-wont-load-corrupt-plan/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JMeter Won't Open a Test Plan (JMX Load Errors) ## Symptom Opening a `.jmx` file shows a dialog or log entry such as: ```text Error loading test plan ``` with an XML parse detail like: ```text org.xml.sax.SAXParseException: The element type "HTTPSamplerProxy" must be terminated by the matching end-tag "". ``` Other variants open the GUI but show an empty or partially built test plan, or log unknown-element warnings during load. ## Quick diagnosis (TL;DR) A JMX file is XML, so load errors mean either the XML is malformed (interrupted save, manual edit, or git merge conflict markers) or JMeter cannot construct an element it finds (missing plugin JARs or a newer JMeter version). Repair the XML first, then check plugins and versions. ## Common causes | Cause | Specific Error | Why it happens | |-------|----------------|----------------| | Interrupted save | Truncated file, abrupt `SAXParseException` | A crash or full disk stopped the write mid-file | | Git merge conflict markers | Parse error at `<<<<<<<` | Merging left conflict markers inside the XML | | Manual hand edit | Tag mismatch errors | A text edit broke tag nesting or escaping | | Missing plugin JARs | Unknown element warnings, missing samplers | The plan references elements whose classes are not installed | | Version mismatch | Plan loads partially or with warnings | A newer JMeter wrote features an older JMeter does not know | ## Fix (ordered) ### 1. Find the exact error location Open `jmeter.log` after the failed load. The `SAXParseException` carries a line and column number, which points straight at the broken region of the file. ### 2. Inspect the XML Open the JMX in a text editor and check: 1. Merge conflict markers: search for `<<<<<<<`, `=======`, and `>>>>>>>`. Remove them and keep the correct element. 2. The file ending: a complete plan ends with ``. If it stops mid-tag, the save was interrupted. 3. Tag nesting around the reported line: every opened element needs its matching close tag, and special characters in attribute values must stay escaped. ### 3. Restore from version control or backup If the file is truncated or badly mangled, restoration beats hand repair: ```bash # Compare against the last committed version git diff HEAD -- path/to/plan.jmx # Restore the committed copy git checkout HEAD -- path/to/plan.jmx ``` Keep test plans in git going forward; JMeter has no built-in autosave, so version control is the recovery mechanism. ### 4. Check plugins and element availability If the XML is valid but elements are missing after load: 1. Look for unknown-element or class warnings in `jmeter.log`. 2. Install the matching plugin JARs into `lib/ext/`, following [ClassNotFound & Missing JARs](/topics/errors/class-not-found-noclassdeffound/). 3. Reopen the plan and confirm every element appears in the tree. ### 5. Match JMeter versions The JMX header records which version wrote it: ```xml ``` If the `jmeter` attribute is newer than your installation, open the plan with that version (or newer) and re-save it, or upgrade your installation. Newer JMeter reads older plans without trouble; the reverse direction is where load errors appear. ## Related tools and topics | Resource | Use when | |----------|----------| | [ClassNotFound & Missing JARs](/topics/errors/class-not-found-noclassdeffound/) | Elements fail to construct because plugin JARs are missing | | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | The plan loads but the CLI run misbehaves | | [Building a Test Plan](/user-manual/build-test-plan/) | Saving and organizing plans safely | | [Hints and Tips](/user-manual/hints-and-tips/) | General test plan hygiene | ## Frequently asked questions ### Can a corrupted JMX file be repaired? Often, yes. If the damage is a truncated tail or merge conflict markers, fixing the XML by hand restores the plan. When whole sections are missing, restoring from git or a backup is faster and safer than reconstruction. ### Why does my JMX open on a colleague's machine but not mine? Version or plugin differences. Check the `jmeter` attribute in the JMX header against your installed version, and compare the contents of `lib/ext/` for plugin JARs the plan depends on. ### Where does JMeter report the exact XML error? In `jmeter.log`. The `SAXParseException` line names the problem and includes line and column numbers, which map directly to a position in the JMX file. ### How do I prevent JMX corruption? Save before large edits, keep plans in git so merges are visible and reversible, and avoid hand-editing the XML without an editor that validates well-formedness. Committing after each meaningful change keeps the last-good version close. Read the SAXParseException line number from jmeter.log, inspect that region of the JMX, and restore from git if more than a few lines are damaged. - [Building a Test Plan](/user-manual/build-test-plan/) - [JMeter for beginners](/topics/jmeter-for-beginners/) - [Plugins essentials](/topics/plugins-essentials/) - [Troubleshooting overview](/topics/troubleshooting/) --- Title: JMeter JSON & Regex Extractor Returns Default Value (NOT_FOUND) URL: https://docs.jmeter.ai/topics/errors/extractor-not-found-default-value/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JSON & Regex Extractor Returns Default Value in JMeter ## Symptom When extracting dynamic values (such as OAuth tokens, session IDs, or transaction IDs) to use in subsequent requests, downstream requests fail with HTTP 401, 403, or 400, and Debug Sampler shows: ```text token_var=NOT_FOUND # Or the variable is not replaced at all in the outgoing request: Authorization: Bearer ${token_var} ``` The Extractor failed to capture the target value and fell back to the configured **Default Value** (or left the variable undefined). ## Quick diagnosis (TL;DR) Extractors fail when: 1. **Wrong Scope**: The Extractor is checking **Main sample only**, but the target token is inside a redirected **Sub-sample** (or embedded resource). 2. **Incorrect Execution Order / Parent Placement**: The Extractor is placed as a sibling or above the target sampler instead of as a child element. 3. **Invalid JSONPath / Regex Syntax**: The expression does not match the actual response structure (e.g. `$.token` instead of `$.data.token`). ## Common causes | Cause | Component | Why it happens | |-------|-----------|----------------| | Scoping set to "Main sample only" | JSON / Regex | Target response came from a redirect (HTTP 302 -> 200) located in a sub-sample | | Wrong Field to check | Regex / Boundary | Extractor is checking "Body" when the token is inside "Response Headers" (e.g. `Set-Cookie`, `Location`) | | Unescaped regex characters | Regex Extractor | Special characters (`.`, `[`, `]`, `?`, `$`) not escaped in regex template | | Array indexing in JSONPath | JSON Extractor | Querying `$.items.id` on an array instead of `$.items[0].id` or `$.items[*].id` | | Variable name typos | Downstream | Extractor created variable `authToken`, but downstream sampler calls `\${authtoken}` (case-sensitive) | ## Fix (ordered) ### 1. Test Expressions Directly in View Results Tree Tester Never guess regex or JSONPath queries in your head. Use JMeter's built-in interactive testers: 1. Add a **View Results Tree** listener under the target request. 2. Run the test with 1 thread. 3. Select the sampler in the left tree. 4. In the response pane dropdown, change **Text** to: - **JSON Path Tester** (for JSON Extractors) - **RegExp Tester** (for Regular Expression Extractors) - **Boundary Extractor Tester** 5. Enter your expression (e.g. `$.data.user.jwtToken`) and click **Test**. JMeter will highlight the exact matches and match counts. ### 2. Verify PostProcessor Scoping (Main sample vs Sub-samples) If your request performs HTTP redirects (302/301) or downloads embedded resources: - Open your Extractor. - Under **Apply to**, choose: - **Main sample and sub-samples** (if the token may appear on either). - **Sub-samples only** (if returned by the redirect target). ### 3. Check the Correct "Field to check" - If extracting a `Set-Cookie` or `Location` header, select **Response Headers** (not **Body**). - If extracting from the redirect URL, select **URL**. - If extracting from standard JSON/HTML, select **Body**. ### 4. Ensure Correct Hierarchical Placement in Test Tree In JMeter, PostProcessors execute **only after their parent or preceding sampler finishes**: ```text ✅ CORRECT (Scoped to Sampler A only): - HTTP Request (Sampler A) └─ JSON Extractor (Extracts token from Sampler A) - HTTP Request (Sampler B - uses ${token}) ❌ WRONG (Scoped to all samplers, may overwrite variable with empty match): - JSON Extractor - HTTP Request (Sampler A) - HTTP Request (Sampler B) ``` ### 5. Debug Live Variables with the Debug Sampler To verify what variables exist at each point in execution: 1. Add **Debug Sampler** immediately after the sampler with the Extractor. 2. Set `JMeter Variables: true`. 3. In **View Results Tree**, click on **Debug Sampler** -> **Response data** -> **Response Body**. 4. Confirm whether your variable name and value are listed. ## Related tools and topics | Resource | Use when | |----------|----------| | [Regex Extractor Builder](/tools/regex-tester/) | Interactive browser-based regex pattern builder | | [Correlation & dynamic values](/topics/correlation-dynamic-values/) | Complete guide to CSRF and token extraction | | [401/403 after recording](/topics/errors/401-403-after-recording/) | Handling authentication failures | | [Functions and variables](/topics/functions-and-variables/) | Variable syntax and built-in functions | ## Frequently asked questions ### What does "Match No. (0 for Random)" mean in JSON Extractor? - `0`: Random match from all matching results. - `1`: First match. - `-1`: Extract all matches into an array (`var_1`, `var_2`, ... and `var_matchNr`). ### Why is my variable showing literally as `\${my_var}`? JMeter only replaces `\${my_var}` if a variable with that exact name exists. If the variable was never created or has a typo, JMeter sends the literal text `\${my_var}` in the HTTP request. Open View Results Tree, switch the dropdown to JSON Path Tester, and verify your query against the actual response body. - [Correlation & dynamic values](/topics/correlation-dynamic-values/) - [Regex Extractor Builder](/tools/regex-tester/) - [API load testing](/topics/api-load-testing/) --- Title: JMeter CSV Data Set Config: File not found & Sharing Mode URL: https://docs.jmeter.ai/topics/errors/csv-data-set-file-not-found-sharing/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # CSV Data Set Config: File not found & Sharing Issues ## Symptom When executing a test in CLI mode, CI/CD pipelines, or distributed testing, one of the following errors occurs in `jmeter.log`: ```text 2026-08-18 14:02:11,551 ERROR o.a.j.c.CSVDataSet: java.io.FileNotFoundException: users.csv (The system cannot find the file specified) at java.io.FileInputStream.open0(Native Method) ``` Or a test data logic error occurs: - All concurrent virtual user threads read the exact same row of data simultaneously. - The test terminates unexpectedly early because of an unexpected End of File (EOF). - Dynamic CSV variables appear literally as `\${username}` in HTTP requests. ## Quick diagnosis (TL;DR) - **`FileNotFoundException` in CLI/CI**: JMeter resolves relative CSV paths relative to the current working directory from which the `jmeter` command was executed, **not** necessarily the directory containing the `.jmx` file. - **Duplicate Data Read**: The CSV Data Set Config is placed inside a loop or child controller, resetting file pointers on each iteration, or **Sharing Mode** is misconfigured. ## Common causes | Issue | Cause | Fix | |-------|-------|-----| | CLI `FileNotFoundException` | Invoked `jmeter` from a folder other than the test plan folder | Use `\${__P(testdata.path)}` or FileServer basedir | | Distributed testing `FileNotFoundException` | CSV file exists on controller machine but was not copied to remote worker nodes | Copy the CSV file to the exact same file path on all remote worker machines | | All threads reading same line | CSV Data Set Config placed as child of a Loop Controller | Move CSV Data Set Config to the root of the **Thread Group** | | Test stops prematurely | "Stop thread on EOF" set to `true` on a small CSV file | Set "Recycle on EOF" to `true` and "Stop thread on EOF" to `false` | | Variables not assigned | "Variable Names" blank and CSV has no header row | Provide comma-separated variable names in configuration | ## Fix (ordered) ### 1. Use Robust Relative Path Resolution To make `.jmx` test plans fully portable across local GUI, CLI, and CI/CD runners regardless of current working directory: In **CSV Data Set Config** -> **Filename**, use the `FileServer` basedir function: ```text ${__groovy(org.apache.jmeter.services.FileServer.getFileServer().getBaseDir())}/users.csv ``` Or configure a dynamic property with a default fallback: ```text ${__P(data.dir,${__groovy(org.apache.jmeter.services.FileServer.getFileServer().getBaseDir())})}/users.csv ``` Now you can override data paths dynamically in CI/CD: ```bash jmeter -n -t /plans/checkout.jmx -Jdata.dir=/ci-data/ -l results.jtl ``` ### 2. Configure Sharing Mode for Concurrent Threads The **Sharing Mode** setting controls how file pointers advance across virtual users: | Sharing Mode | Behavior | Best for | |--------------|----------|----------| | **All threads** (Default) | Single global file pointer shared across all thread groups. Each thread reads the next unique line | Unique user logins, single-use promo codes | | **Current thread group** | Each Thread Group maintains its own independent file pointer | Separate scenarios that need the same test data set | | **Current thread** | Each individual virtual user reads the entire CSV file from line 1 independently | Iterating through a fixed list of product IDs per user | ### 3. Handle End of File (EOF) Behavior In **CSV Data Set Config**: - **Recycle on EOF?**: Set to **`True`** if you want threads to loop back to line 1 when the file ends. - **Stop thread on EOF?**: Set to **`False`** to allow tests to run for their scheduled duration. Set to **`True`** only if the test must stop immediately after exhausting the data file. ### 4. Fix CSV Distribution in Distributed / Remote Testing In distributed mode (`jmeter -r`): 1. JMeter **does NOT send CSV files** over RMI to worker nodes. 2. You must place the CSV file on **every remote worker machine** at the exact same path. 3. If using shared network storage (NFS/EFS), ensure all worker pods mount the share at the identical mount path. ## Related tools and topics | Resource | Use when | |----------|----------| | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | File path and working directory differences | | [Functions and variables](/topics/functions-and-variables/) | Built-in functions like `__CSVRead` | | [Distributed testing](/topics/distributed-testing/) | Managing test data across remote workers | | [CLI Command Builder](/tools/cli-builder/) | Generate CLI commands with dynamic data properties | ## Frequently asked questions ### Should I use CSV Data Set Config or `__CSVRead()` function? Always prefer **CSV Data Set Config**. It is significantly faster, thread-safe, supports multi-threaded sharing modes, and handles quotes and delimiter parsing properly. ### How do I split one CSV file across multiple worker nodes? Split the CSV file into chunks before the test run (e.g. `split -l 1000 users.csv worker_`) and copy chunk 1 to Worker 1, chunk 2 to Worker 2. Use `\${__groovy(org.apache.jmeter.services.FileServer.getFileServer().getBaseDir())}/file.csv` in the CSV Filename field for bulletproof path resolution. - [Functions and variables](/topics/functions-and-variables/) - [Distributed testing](/topics/distributed-testing/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Distributed Testing RMI Connection Refused & Port Errors URL: https://docs.jmeter.ai/topics/errors/rmi-connection-refused-remote-testing/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Distributed Testing RMI Connection Refused in JMeter ## Symptom When launching a distributed load test from the controller machine (`jmeter -r` or `jmeter -R 10.0.0.2,10.0.0.3`), the test fails immediately with: ```text 2026-08-18 15:30:10 ERROR o.a.j.e.ClientJMeterEngine: Error in rsystem java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused ``` Or when starting the remote worker daemon (`jmeter-server`): ```text Server failed to start: java.rmi.server.ExportException: Listen failed on port: 1099 ``` Or later, when the controller invokes an engine on a worker that published the wrong address: ```text java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.ConnectException: Connection refused to host: 127.0.0.1 ``` Or an SSL certificate handshake failure: ```text java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory) ``` The master/controller cannot initialize the remote engines, and the test halts. ## Quick diagnosis (TL;DR) - **`Connection refused to host: 127.0.0.1`**: The remote worker bound its RMI stub to the local loopback interface (`127.0.0.1`) instead of its routable LAN/VPC IP address. The controller is trying to connect to its own localhost instead of the worker. - **`Listen failed on port: 1099`**: Port 1099 is already in use by another instance or blocked by a firewall. - **`rmi_keystore.jks missing`**: JMeter requires RMI over SSL by default since JMeter 4.0. You must either generate the keystore or explicitly disable RMI SSL. ## Common causes | Error Message | Root Cause | Fix | |---------------|------------|-----| | `Connection refused to host: 127.0.0.1` | Remote worker did not publish its external IP | Set `java.rmi.server.hostname=WORKER_IP` | | `Listen failed on port: 1099` | Port collision or another `jmeter-server` running | Kill existing process or set `server_port=1099` | | `FileNotFoundException: rmi_keystore.jks` | Missing SSL keystore in `JMETER_HOME/bin/` | Run `create-rmi-keystore.sh` or set `server.rmi.ssl.disable=true` | | Controller hangs after `Starting the test` | Worker firewall blocking dynamic RMI response port | Fix `client.rmi.localport` and `server.rmi.localport` | | Plugin mismatch / ClassNotFound | Worker nodes lack plugins installed on controller | Sync `lib/` and `lib/ext/` across all workers | ## Fix (ordered) ### 1. Fix the RMI Hostname on Every Worker Node When starting `jmeter-server` on remote worker machines, always supply the worker's routable network IP address: ```bash # On Remote Worker 1 (IP: 10.0.0.15) ./bin/jmeter-server -Djava.rmi.server.hostname=10.0.0.15 # On Remote Worker 2 (IP: 10.0.0.16) ./bin/jmeter-server -Djava.rmi.server.hostname=10.0.0.16 ``` ### 2. Configure RMI SSL (or Explicitly Disable for Private VPCs) Since JMeter 4.0, RMI over SSL is mandatory by default: **Option A: Generate a Shared Keystore (Recommended for Security)** 1. On the controller, run `./bin/create-rmi-keystore.sh` (or `create-rmi-keystore.bat`). 2. Copy the resulting `bin/rmi_keystore.jks` to the `bin/` folder of **every worker machine**. **Option B: Disable RMI SSL (For Isolated Private VPCs/Labs)** Add to `bin/user.properties` on **both controller and all worker machines**: ```properties server.rmi.ssl.disable=true ``` ### 3. Fix Dynamic RMI Firewall Ports (Prevent Controller Hangs) By default, Java RMI uses random ephemeral ports for two-way communication after the initial port 1099 handshake. If your cloud firewall only opens port 1099, the test will hang. Lock all RMI communication to fixed ports in `user.properties`: ```properties # Port used by jmeter-server registry server_port=1099 # Fixed local port for RMI engine on worker server.rmi.localport=50000 # Fixed local port for RMI response on controller client.rmi.localport=50001 ``` Now configure your cloud Security Group / Firewall to allow TCP traffic on ports **`1099`**, **`50000`**, and **`50001`**. ### 4. Verify End-to-End Connectivity with Netcat From the controller machine, verify that the worker port is open: ```bash nc -zv 10.0.0.15 1099 nc -zv 10.0.0.15 50000 ``` ### 5. Launch the Distributed Run from Controller ```bash # Execute distributed test against multiple workers in non-GUI mode jmeter -n -t testplan.jmx \ -R 10.0.0.15,10.0.0.16 \ -Gserver.rmi.ssl.disable=true \ -l results.jtl -j jmeter.log ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [Distributed testing guide](/topics/distributed-testing/) | Full architectural walkthrough of remote testing | | [Docker & Kubernetes](/topics/docker-kubernetes/) | Setting up distributed JMeter in Kubernetes clusters | | [CLI Command Builder](/tools/cli-builder/) | Generate CLI commands with `-R` and `-G` properties | | [Remote testing user manual](/user-manual/remote-test/) | Official remote testing documentation | ## Frequently asked questions ### What does `-G` mean on the JMeter command line? `-G` sets a property **globally on all remote worker nodes** (e.g. `-Gthreads=100`), whereas `-J` sets a property **only on the local controller**. ### Why are CSV files not found on remote workers? The JMeter controller transmits the compiled `.jmx` test tree over RMI, but it **never transmits test data files**. You must replicate CSV files to the identical local path on every worker node before launching the test. ### Why does jmeter-server bind to the wrong IP on a multi-homed host? Without an explicit setting, Java RMI picks an address from the default network interface, which on multi-homed or containerized hosts can be an internal or loopback address. Start the worker with `-Djava.rmi.server.hostname=ROUTABLE_IP` for the interface the controller can reach, and list those same routable IPs in `remote_hosts` in the controller's `jmeter.properties` instead of hostnames that might resolve to the wrong interface. Set `java.rmi.server.hostname` when launching each `jmeter-server` and verify that `server.rmi.ssl.disable` settings match. - [Distributed testing](/topics/distributed-testing/) - [Docker / Kubernetes](/topics/docker-kubernetes/) - [Remote testing manual](/user-manual/remote-test/) --- Title: JMeter JDBC Connection Pool & SQL Database Errors URL: https://docs.jmeter.ai/topics/errors/jdbc-connection-pool-errors/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # JDBC Connection Pool & Database Errors in JMeter ## Symptom When running database performance tests using the **JDBC Request** sampler and **JDBC Connection Configuration** element, samplers fail in View Results Tree or `jmeter.log` with: ```text Response code: 500 Response message: java.sql.SQLException: Cannot create PoolableConnectionFactory (Communications link failure) The last packet successfully received from the server was 0 milliseconds ago. ``` Or when database credentials or database names are incorrect: ```text java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'dbuser'@'10.0.0.5') ``` Or when all connections in the pool are busy: ```text java.sql.SQLException: Timeout waiting for idle object at org.apache.commons.dbcp2.PoolableConnectionFactory... ``` The JDBC Request sampler fails, and database queries are not executed against the database. ## Quick diagnosis (TL;DR) - **`Cannot create PoolableConnectionFactory`**: The connection pool failed to establish its initial connection. Check JDBC URL syntax, port numbers, database credentials, or database firewall rules. - **`Timeout waiting for idle object`**: All database connections in the pool (`Max Number of Connections`) are currently checked out by active virtual users, and new requests timed out waiting for a connection to be returned. ## Common causes | Error Message | Cause | Why it happens | |---------------|-------|----------------| | `Communications link failure` / `Connection refused` | Database network unreachable | Database port (3306, 5432, 1521, 1433) closed, blocked by firewall, or DB not listening on external interface | | `Cannot load JDBC driver class` | Missing JAR file | JDBC Driver `.jar` is not placed in `JMETER_HOME/lib/` or JMeter was not restarted | | `Timeout waiting for idle object` | Connection pool exhausted | Concurrency exceeds `Max Number of Connections` with slow-running SQL queries | | `Access denied for user` | Authentication failure | Incorrect database username/password or user not permitted from load injector IP | | Variable name mismatch | Config element mapping | **Variable Name Bound to Pool** in JDBC Request does not match the name in JDBC Connection Configuration | ## Fix (ordered) ### 1. Verify Variable Name Bound to Pool In JMeter, the **JDBC Connection Configuration** creates a named pool, and each **JDBC Request** must specify the exact matching pool name: - In **JDBC Connection Configuration**: - Variable Name for created pool: `APP_DB_POOL` - In **JDBC Request**: - Variable Name of Pool declared in JDBC Connection Configuration: `APP_DB_POOL` If these names differ by even one character (or case), the request will fail immediately. ### 2. Configure Correct Driver Class Name and JDBC URL Ensure the driver class and URL format match your database engine: | Database | Driver Class Name | Database URL Format | |----------|-------------------|---------------------| | **PostgreSQL** | `org.postgresql.Driver` | `jdbc:postgresql://localhost:5432/dbname?sslmode=disable` | | **MySQL / MariaDB** | `com.mysql.cj.jdbc.Driver` | `jdbc:mysql://localhost:3306/dbname?useSSL=false&serverTimezone=UTC` | | **Oracle** | `oracle.jdbc.OracleDriver` | `jdbc:oracle:thin:@localhost:1521:orcl` or `jdbc:oracle:thin:@//localhost:1521/XEPDB1` | | **Microsoft SQL Server** | `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `jdbc:sqlserver://localhost:1433;databaseName=dbname;encrypt=false` | Ensure the matching driver `.jar` is in `JMETER_HOME/lib/` ([ClassNotFound playbook](/topics/errors/class-not-found-noclassdeffound/)). ### 3. Tune Connection Pool Sizing and Validation Query In **JDBC Connection Configuration**: - **Max Number of Connections**: Set equal to or slightly higher than your active thread count (e.g. `50`–`100`). - **Max Wait (ms)**: `10000` (10 seconds timeout before failing if pool is full). - **Validation Query**: Always set a lightweight ping query to discard broken sockets: - MySQL / PostgreSQL / MSSQL: `SELECT 1` - Oracle: `SELECT 1 FROM DUAL` - **Test While Idle**: `True` - **Soft Min Evictable Idle Time**: `60000` ### 4. Configure Auto Commit and Query Type In **JDBC Request**: - If running `SELECT` queries, set **Query Type** to `Select Statement`. - If running `INSERT`, `UPDATE`, or `DELETE`, set **Query Type** to `Update Statement`. - In **JDBC Connection Configuration**, set **Auto Commit** to `True` for simple read queries, or `False` if managing multi-statement transactions. ### 5. Extract and Assert SQL Results To capture values returned by database queries: - **Variable names**: `userId,userName,userEmail` - In subsequent samplers, access individual rows: `\${userId_1}`, `\${userId_2}`, or count via `\${userId_#}`. ## Related tools and topics | Resource | Use when | |----------|----------| | [ClassNotFoundException](/topics/errors/class-not-found-noclassdeffound/) | Missing JDBC driver JAR files in `lib/` | | [Database Test Plan guide](/user-manual/build-db-test-plan/) | Step-by-step user manual for JDBC testing | | [Functions and variables](/topics/functions-and-variables/) | Passing variables between JDBC and HTTP samplers | ## Frequently asked questions ### Should each thread have its own JDBC Connection Configuration? No. Place one **JDBC Connection Configuration** at the Thread Group or Test Plan root. All threads share the pooled connections efficiently. ### Why is my query timing out under load? Check the database server's active locks and slow query log. Long-running queries hold connections checked out of the pool, starving other virtual users. Ensure the JDBC driver JAR is in `JMETER_HOME/lib/`, verify the pool variable name, and configure `SELECT 1` as the validation query. - [Database Test Plan](/user-manual/build-db-test-plan/) - [ClassNotFoundException](/topics/errors/class-not-found-noclassdeffound/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Works in GUI Fails in CLI URL: https://docs.jmeter.ai/topics/errors/gui-works-cli-fails/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # Script works in GUI, fails in CLI ## Symptom - Green samples in the GUI with a few threads - Same `.jmx` fails under: ```bash jmeter -n -t plan.jmx -l results.jtl ``` - Failures often show missing files, wrong host, plugin/class errors, or connection errors only on the CI agent Official stance: use GUI to build and debug; use **non-GUI for real load** ([best practices](/user-manual/best-practices/)). CLI is required in [CI/CD](/topics/ci-cd-load-testing/) and containers. ## Common causes | Cause | Detail | |-------|--------| | Working directory | Relative CSV, keystore, or payload paths resolve from different cwd | | Properties | GUI used defaults or GUI-set props; CLI missing `-J` / `-q` | | Plugins missing | CI image or server install lacks `lib/ext` JARs ([plugins](/topics/plugins-essentials/)) | | Headless network | Agent cannot reach SUT ([ConnectException](/topics/errors/connect-exception/)) | | Different `user.properties` | Local custom props not present on the agent | | Output paths | `-o` report dir already exists / not writable | | Java version skew | Different JVM behaviour or TLS defaults | ## Fix (ordered) 1. Run CLI **on the same machine** as the successful GUI run first: ```bash cd /path/to/plan-dir jmeter -n -t plan.jmx -l results.jtl -j jmeter.log -e -o report/ ``` 2. Open `jmeter.log` for file-not-found, class-not-found, or SSL lines. 3. Make CSV and resource paths **stable** (relative to plan location or absolute). CSV Data Set is the documented multi-user pattern ([best practices](/user-manual/best-practices/)). 4. Parameterize hosts and threads with `` `\${__P(name,default)}` `` and pass the same `-J` flags you expect in CI ([functions](/topics/functions-and-variables/)). 5. Mirror plugins into the CLI environment; restart after installs. 6. In Docker/K8s, mount plans and outputs explicitly ([Docker guide](/topics/docker-kubernetes/)); use `qainsights/jmeter` or your pinned image consistently. 7. Only after local CLI is green, run the same command in CI with the same properties and network access. ## Related tools and topics | Resource | Use when | |----------|----------| | [CI/CD load testing](/topics/ci-cd-load-testing/) | Pipeline patterns | | [Plugins essentials](/topics/plugins-essentials/) | Missing elements in CLI | | [ConnectException](/topics/errors/connect-exception/) | Network only in CI | | [Properties cheat sheet](/tools/properties-cheatsheet/) | Env differences | ## Frequently asked questions ### Is GUI success enough to ship a plan? No. Always prove non-GUI once. Production and CI never use the GUI for load. ### Why relative CSV paths break in CLI? GUI often starts with a cwd near the plan or last open file. CLI cwd is wherever you launched the process. Prefer plan-relative layout and document the launch directory. ### Does -n change sampler behaviour? Same engine, different resource profile (no GUI listeners). Functional failures are usually path/property/plugin/network differences, not `-n` itself. From the plan directory, run jmeter -n once with -j jmeter.log and fix the first path or property error in that log. - [Best practices](/user-manual/best-practices/) - [CI/CD](/topics/ci-cd-load-testing/) - [Functions and variables](/topics/functions-and-variables/) --- Title: JMeter HTML Dashboard Generation Errors & Fixes URL: https://docs.jmeter.ai/topics/errors/html-dashboard-generation-errors/ --- import RelatedContent from '../../../../components/RelatedContent.astro'; # HTML Dashboard Generation Errors in JMeter ## Symptom When attempting to generate an HTML report dashboard from a `.jtl` / `.csv` results file, the command fails in the terminal: ```text An error occurred: Cannot generate report: Error while processing samples: Consumer failed with message: Begin date cannot be after end date ``` Or when the target output folder already exists and contains files: ```text An error occurred: Cannot generate report: Error while processing samples: /reports is not empty, please choose an empty folder ``` Or when the generated HTML dashboard shows empty charts and 0 total samples: ```text An error occurred: Cannot generate report: Results file is empty or missing required CSV headers ``` ## Quick diagnosis (TL;DR) - **`Folder is not empty`**: JMeter requires the destination directory (`-o ./report_dir`) to be completely empty or non-existent. - **`Begin date cannot be after end date`**: Timestamps in the JTL file are corrupted, out of chronological order (e.g. from appending multiple runs without headers), or skewed across unsynced distributed worker system clocks. - **`Missing CSV headers`**: The JTL was saved in XML format instead of CSV, or `jmeter.save.saveservice.timestamp_format` was misconfigured. ## Common causes | Error | Root Cause | Fix | |-------|------------|-----| | Output directory not empty | Passing `-o ./dashboard` when `./dashboard` already contains previous run files | Delete the folder before running: `rm -rf ./dashboard` | | `Begin date cannot be after end date` | JTL contains unsorted timestamps or multiple test runs appended | Sort JTL by timestamp or delete old JTL file before new run | | Timezone / clock skew | Distributed worker nodes have drifting system clocks | Sync all worker clocks with NTP (`chrony` / `systemd-timesyncd`) | | Empty charts / 0 samples | JTL was generated with XML format instead of CSV | Set `jmeter.save.saveservice.output_format=csv` | | Missing columns error | Custom `user.properties` disabled mandatory dashboard columns | Restore default `jmeter.save.saveservice.*` properties | ## Fix (ordered) ### 1. Ensure the Output Directory is Empty Before Generating JMeter will refuse to overwrite existing report folders to protect against accidental data loss. Always clean the directory prior to generation: ```bash # Linux / macOS rm -rf ./html-report && jmeter -g results.jtl -o ./html-report # Windows PowerShell Remove-Item -Recurse -Force ./html-report; jmeter -g results.jtl -o ./html-report ``` ### 2. Generate Dashboard Automatically in One CLI Command Instead of generating the dashboard in a separate second step, generate it natively at the end of the test execution: ```bash # -n: CLI mode | -t: test plan | -l: results log | -e: generate report | -o: output directory jmeter -n -t testplan.jmx -l results.jtl -e -o ./html-report -j jmeter.log ``` ### 3. Fix "Begin date cannot be after end date" (Sort JTL) If multiple test runs were appended to the same JTL, or if distributed worker nodes flushed samples out of order: ```bash # 1. Extract the header line head -n 1 results.jtl > sorted.jtl # 2. Sort remaining rows numerically by the first column (timestamp) and append tail -n +2 results.jtl | sort -n -t ',' -k 1 >> sorted.jtl # 3. Generate the report from the sorted file rm -rf ./html-report jmeter -g sorted.jtl -o ./html-report ``` ### 4. Verify Required JTL Saveservice Properties The HTML dashboard generator requires standard CSV formatting. Ensure these properties are set in `bin/user.properties`: ```properties # Mandatory properties for HTML Dashboard generation jmeter.save.saveservice.output_format=csv jmeter.save.saveservice.timestamp_format=ms jmeter.save.saveservice.bytes=true jmeter.save.saveservice.label=true jmeter.save.saveservice.latency=true jmeter.save.saveservice.response_code=true jmeter.save.saveservice.response_message=true jmeter.save.saveservice.successful=true jmeter.save.saveservice.thread_counts=true jmeter.save.saveservice.thread_name=true jmeter.save.saveservice.time=true jmeter.save.saveservice.connect_time=true ``` ### 5. Synchronize System Clocks (NTP) on Distributed Nodes In distributed testing, if Worker A's clock is 5 minutes ahead of Worker B, the merged JTL file will contain backwards timestamp jumps. Ensure NTP is enabled across all machines: ```bash # Check NTP synchronization status on Linux timedatectl status ``` ## Related tools and topics | Resource | Use when | |----------|----------| | [Dashboard Report user manual](/user-manual/generating-dashboard/) | Full guide to charts, APDEX, and dashboard metrics | | [CLI Command Builder](/tools/cli-builder/) | Generate clean CLI flags for report generation | | [Throughput stuck](/topics/errors/throughput-stuck/) | Analyzing response time charts in the report | | [Distributed testing](/topics/distributed-testing/) | Time synchronization across remote worker nodes | ## Frequently asked questions ### Can I generate an HTML report from an XML results file? No. The HTML dashboard generator only supports **CSV** format. You must configure `jmeter.save.saveservice.output_format=csv` before running the test. ### Why is APDEX score showing 0 or bad ratings in my report? APDEX thresholds default to 500ms satisfied (`T`) and 1500ms tolerated (`F`). You can customize these thresholds in `user.properties` by setting `jmeter.reportgenerator.apdex_satisfied_threshold=1000` and `jmeter.reportgenerator.apdex_tolerated_threshold=3000`. Delete the existing report folder and run `jmeter -g results.jtl -o ./html-report` with a sorted CSV file. - [Dashboard Report user manual](/user-manual/generating-dashboard/) - [CLI Command Builder](/tools/cli-builder/) - [Best practices](/user-manual/best-practices/) --- Title: JMeter Tools URL: https://docs.jmeter.ai/tools/ --- # JMeter Tools Interactive helpers for common load-testing decisions. All tools run **in your browser** on [docs.jmeter.ai](https://docs.jmeter.ai): no account, no upload of test data. ## Available tools | Tool | Use it when you need to… | |------|--------------------------| | [cURL & HAR to JMX Converter](/tools/curl-to-jmx/) | Convert cURL commands and HAR files into valid JMX test plans (supports GET, POST, QUERY, etc.) | | [Thread Calculator](/tools/thread-calculator/) | Estimate concurrent threads / RPS, think time, and ramp-up | | [Heap Estimator](/tools/heap-estimator/) | Pick a starting `-Xmx` for injectors | | [CLI Command Builder](/tools/cli-builder/) | Assemble `jmeter -n -t` with report, HEAP, and `-J` flags | | [Distributed Testing Planner](/tools/distributed-planner/) | Plan pinned RMI ports, firewall rules, and cluster configs | | [Linux OS & Kernel Tuning](/tools/os-tuning/) | Generate `sysctl.conf`, `limits.conf`, and systemd configs for high concurrency | | [Coordinated Omission Calculator](/tools/coordinated-omission/) | Correct for dropped requests when throughput falls below target | | [Properties Cheat Sheet](/tools/properties-cheatsheet/) | Find high-impact `user.properties` quickly | | [Regex Extractor Builder](/tools/regex-tester/) | Paste a response (max 1 MB, browser-only) for Regex Extractor fields | ## Why these tools Docs alone rank for "what is…", but practitioners search for calculators and cheat sheets. Each tool has shareable URL state, SEO metadata, and links back into the manual so answers stay grounded in JMeter concepts. ## Related reading - [Best Practices](/user-manual/best-practices/) - [Properties Reference](/user-manual/properties-reference/) - [Regular Expressions](/user-manual/regular-expressions/) - [Remote Testing](/user-manual/remote-test/) --- Title: cURL & HAR to JMeter JMX Converter URL: https://docs.jmeter.ai/tools/curl-to-jmx/ --- import CurlToJmx from '../../../components/tools/CurlToJmx.astro'; ## How the Converter Works Creating JMeter test plans manually for dozens of API endpoints is slow and error-prone. This converter takes raw **cURL commands** (from Swagger, Postman, browser DevTools, or terminal history) and **HAR 1.2 network captures**, automatically structuring them into a production-grade Apache JMeter 5.6.3 `.jmx` test plan. ### What Gets Automatically Generated? 1. **HTTP Request Defaults (`ConfigTestElement`)**: Detects the dominant target domain across your requests and parameterizes it into `${BASE_URL}`, making environment switching (Dev $\to$ Staging $\to$ Prod) effortless. 2. **HTTP Header Manager (`HeaderManager`)**: Preserves required custom headers (`Content-Type`, `Accept`, `X-Api-Key`), while stripping transport-level noise (`Content-Length`) that JMeter calculates dynamically. 3. **HTTP Cookie Manager (`CookieManager`)**: Auto-injected to manage session cookies and cross-request state across iterations. 4. **Auth Parameterization**: Automatically detects `Authorization: Bearer ` and parameterizes it as `${AUTH_TOKEN}` in User Defined Variables. 5. **Robust Timeouts**: Connect timeout is preset to `5000ms` and response timeout to `15000ms` on every sampler to prevent thread pool lockup during load spikes. 6. **Response Code Assertions**: Generates baseline `ResponseAssertion` elements validating HTTP 200, 201, and 204 status codes. --- ## Full HTTP Method Support (Including `QUERY` RFC 9838) The converter supports all standard and modern HTTP methods: | Method | JMeter Implementation | Use Case | | :--- | :--- | :--- | | `GET` | `HTTPSamplerProxy` (Query Params in Arguments or Path) | Fetching resources and reading data | | `POST` | `HTTPSamplerProxy` (`postBodyRaw="true"` or Form fields) | Creating resources / authentication | | `QUERY` | `HTTPSamplerProxy` (`postBodyRaw="true"`, Method=`QUERY`) | Safe, idempotent complex queries with JSON payload bodies (Elasticsearch, GraphQL, modern REST) | | `PUT` | `HTTPSamplerProxy` (`postBodyRaw="true"`) | Full resource replacement | | `PATCH` | `HTTPSamplerProxy` (`postBodyRaw="true"`) | Partial resource modification | | `DELETE` | `HTTPSamplerProxy` | Removing resources | | `HEAD` / `OPTIONS` | `HTTPSamplerProxy` | Health checks and CORS preflight | ### Example: HTTP `QUERY` Method in cURL ```bash curl -X QUERY "https://api.example.com/v1/catalog/search" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sample-jwt-token-xyz" \ -d '{ "filter": { "status": "in_stock", "price": { "lte": 150 } }, "sort": "price:asc" }' ``` The converter translates this into a valid JMeter HTTP Sampler with the `QUERY` method and raw payload body configured without requiring custom plugins. --- ## Running the Generated JMX in CLI Mode Once you download the `.jmx` file, run it in non-GUI mode from your terminal: ```bash jmeter -n -t test-plan.jmx -l results.jtl -e -o ./report ``` You can override virtual users dynamically at runtime: ```bash jmeter -n -t test-plan.jmx -Jthreads=100 -l results.jtl -e -o ./report ``` To run for a fixed duration, set **Duration** to a value greater than zero before downloading the plan. This enables JMeter's scheduler and generates the required infinite-loop behavior; adding `-Jduration` to a plan converted with Duration `0` does not enable the scheduler. --- ## Use via AI Agent (MCP Tool) You can call this converter directly inside **Claude Code, Cursor, Windsurf, Qwen Code, and Copilot** via our free Model Context Protocol server: ```bash claude mcp add jmeter-docs https://docs.jmeter.ai/api/mcp --transport http --scope user ``` Prompt your AI agent: > *"Convert this cURL command into a JMeter test plan with 50 threads and 10s rampup: `curl -X QUERY https://api.example.com/v1/search -H 'Content-Type: application/json' -d '{\"query\":\"loadtest\"}'`"* Your agent calls `convert_curl_or_har_to_jmx` and outputs schema-valid XML ready for execution. --- Title: JMeter Thread Group Calculator URL: https://docs.jmeter.ai/tools/thread-calculator/ --- import ThreadCalculator from '../../../components/tools/ThreadCalculator.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Thread Group Calculator Size your Thread Group before you hit Coordinated Omission. Enter a target **requests per second (RPS)**, expected **average response time**, and optional **think time** to estimate concurrent threads, ramp-up, and a rough CLI heap. ## How the estimate works Little's Law: concurrency ≈ arrival rate × cycle time. Cycle time is **response time + think time**. ```text threads ≈ ceil(target_RPS × (response_time_ms + think_time_ms) / 1000) ``` Leave think time at **0** for busy threads (no timer). Copy Thread Group writes the fields you paste into JMeter; add a **Constant Timer** when think time is greater than zero. ### Example | Target RPS | Avg response time | Think time | Recommended threads | |------------|-------------------|------------|---------------------| | 50 | 200 ms | 0 | 10 | | 50 | 200 ms | 800 ms | 50 | | 100 | 500 ms | 0 | 50 | ## What this does not include - Pacing that holds a fixed iteration rate (Constant Throughput Timer) - Injector CPU, bandwidth, and listener overhead - Server saturation (response time rises under load; re-measure) - Splitting load across engines; see [Remote Testing](/user-manual/remote-test/) ## Recommended workflow 1. Measure average response time with a small pilot. 2. Use this calculator for an initial thread count and ramp-up. 3. Run CLI mode (`jmeter -n -t plan.jmx -l results.jtl`) without View Results Tree. 4. Compare achieved throughput in the [HTML dashboard](/user-manual/generating-dashboard/). 5. Scale out with [distributed testing](/topics/distributed-testing/) when one injector is saturated. ## Related reading - [Best Practices](/user-manual/best-practices/) - [Building a Test Plan](/user-manual/build-test-plan/) - [Glossary](/user-manual/glossary/) - [Heap Estimator](/tools/heap-estimator/) - [CLI Command Builder](/tools/cli-builder/) [Open Best Practices](/user-manual/best-practices/) and apply CLI-mode guidance before your first load run. [Thread Group concepts](/user-manual/test-plan/) · [Remote testing](/user-manual/remote-test/) Setting thousands of threads with a 1-second ramp-up and View Results Tree enabled. Achieved RPS far below estimate? Re-measure response time under load and check injector CPU. --- Title: JMeter Heap / JVM Sizing Estimator URL: https://docs.jmeter.ai/tools/heap-estimator/ --- import HeapEstimator from '../../../components/tools/HeapEstimator.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Heap / JVM Sizing Estimator Pick a **starting** `-Xmx` for injectors. Memory depends on threads, samplers, scripting, listeners, and response sizes. This tool gives a conservative first guess you should validate with GC logs. ## How to apply the flags On the command line (example): ```bash JVM_ARGS="-Xms512m -Xmx2048m" jmeter -n -t plan.jmx -l results.jtl ``` Or paste HEAP into the [CLI Command Builder](/tools/cli-builder/) with the rest of the run flags. Or set `HEAP` in your JMeter startup script / environment for the version you ship. ## Practical tips - Prefer **CLI mode** for load; GUI burns heap on rendering. - Disable **View Results Tree / Table** during load tests. - In distributed mode, size **each engine** for its share of threads. - Controllers usually need less heap than injectors. ## Related reading - [Best Practices](/user-manual/best-practices/) - [Thread Calculator](/tools/thread-calculator/) - [Remote Testing](/user-manual/remote-test/) - [Listeners](/user-manual/listeners/) Size threads with the [Thread Calculator](/tools/thread-calculator/), then re-check heap. [Properties cheat sheet](/tools/properties-cheatsheet/) · [Dashboard report](/user-manual/generating-dashboard/) Raising -Xmx endlessly while View Results Tree is still enabled. Still OOM? Reduce threads per engine, strip listeners, avoid saving response data. --- Title: JMeter CLI Command Builder URL: https://docs.jmeter.ai/tools/cli-builder/ --- import CliBuilder from '../../../components/tools/CliBuilder.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter CLI Command Builder Assemble a **non-GUI** JMeter command you can paste into a terminal, GitHub Actions, or Docker. Paths stay in your browser; nothing is uploaded. ## What the flags mean | Flag | Purpose | |------|---------| | `-n` | Non-GUI (CLI) mode — required for real load | | `-t` | Test plan (`.jmx`) | | `-l` | Results file (`.jtl` / CSV) | | `-e` `-o` | Generate the HTML dashboard into an empty folder | | `-f` | Overwrite existing results and report directory | | `-q` | Extra properties file (prefer this over editing `jmeter.properties`) | | `-j` | JMeter log file | | `-Jname=value` | Set a property for this run (`__P` in the plan) | | `-R` | Remote worker hosts (start `jmeter-server` first) | | `-X` | Exit remote servers when the test ends | `HEAP` is an environment variable consumed by JMeter startup scripts, not a `jmeter` flag. Size it with the [Heap Estimator](/tools/heap-estimator/). ## Typical workflow 1. Size threads and think time with the [Thread Calculator](/tools/thread-calculator/). 2. Build the CLI command here (add `-e -o` for a dashboard artifact). 3. Parameterize hosts and threads with `-J` / `__P` so the same `.jmx` works in every environment. 4. Gate the pipeline on dashboard error rate and percentiles, not only the process exit code. ## Related reading - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - [Best Practices](/user-manual/best-practices/) - [Generating Dashboard](/user-manual/generating-dashboard/) - [Remote Testing](/user-manual/remote-test/) Paste the command into a small CLI run, then attach the HTML report as a CI artifact. [Heap estimator](/tools/heap-estimator/) · [Properties cheat sheet](/tools/properties-cheatsheet/) Running load in GUI mode, or pointing -o at a non-empty report folder without -f. Command not found? Add JMeter bin to PATH, or use the full path to jmeter.bat / jmeter. --- Title: Distributed Testing Port & Firewall Planner URL: https://docs.jmeter.ai/tools/distributed-planner/ --- import DistributedPlanner from '../../../components/tools/DistributedPlanner.astro'; ## How JMeter Distributed Testing Works When you launch a distributed load test from a **Controller (Master)** against remote **Workers (Injectors)**, JMeter uses **Java RMI (Remote Method Invocation)** for two-way coordination: 1. **RMI Registry (`server_port`, default 1099)**: The controller connects to port 1099 on each worker node to look up the remote engine service. 2. **Worker Engine Execution (`server.rmi.localport`, e.g. 50000)**: The controller sends the compiled test plan, parameters, and startup signals to the worker's dedicated engine port. 3. **Return Sample Callback (`client.rmi.localport`, e.g. 60000)**: As workers generate load, they stream sample results and metrics back to the controller over this return port. ### Why Default Setups Fail in the Cloud By default, Java RMI uses dynamic ephemeral ports (`0`) for engine communication and callback channels. In cloud environments (AWS Security Groups, Azure NSGs, GCP Firewalls, Docker, or Kubernetes), firewalls silently drop return packets, causing tests to **freeze indefinitely at initialization**. By **pinning all three ports** (`server_port`, `server.rmi.localport`, and `client.rmi.localport`), you can write strict, deterministic firewall rules without opening wide port ranges. --- ## Step-by-Step Distributed Setup Guide ### 1. Configure Controller (Master) Node Place these properties in `bin/user.properties` on your controller machine: ```properties remote_hosts=10.0.1.10:1099,10.0.1.11:1099,10.0.1.12:1099 client.rmi.localport=60000 mode=StrippedBatch server.rmi.ssl.disable=false java.rmi.server.hostname=10.0.0.5 ``` Launch the distributed run in CLI mode: ```bash jmeter -n -t test.jmx -R 10.0.1.10,10.0.1.11,10.0.1.12 -l results.jtl -e -o ./report ``` ### 2. Configure Worker (Server) Nodes On each worker node, configure `bin/user.properties`: ```properties server_port=1099 server.rmi.localport=50000 server.rmi.ssl.disable=false ``` Start the daemon specifying its routable network IP address: ```bash ./bin/jmeter-server -Djava.rmi.server.hostname=10.0.1.10 ``` ### 3. Verify Network Reachability Before Running Tests Always test bidirectional TCP connectivity with `nc` (Netcat) or `Test-NetConnection` (PowerShell) before starting tests: ```bash # Test from Controller to Worker nc -zv 10.0.1.10 1099 nc -zv 10.0.1.10 50000 # Test from Worker to Controller nc -zv 10.0.0.5 60000 ``` --- ## Related Guides & Playbooks - [Remote Testing User Manual](/user-manual/remote-test/) - [Step-by-Step Distributed Testing Tutorial](/user-manual/jmeter-distributed-testing-step-by-step/) - [RMI Connection Refused & Port Troubleshooting](/topics/errors/rmi-connection-refused-remote-testing/) - [Docker & Kubernetes Deployment Guide](/topics/docker-kubernetes/) - [Heap Estimator for Injector Engines](/tools/heap-estimator/) --- Title: Linux Kernel & OS Tuning Configurator URL: https://docs.jmeter.ai/tools/os-tuning/ --- import OsTuningConfigurator from '../../../components/tools/OsTuningConfigurator.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; When simulating thousands of concurrent virtual users or pushing high throughput, default Linux operating system settings bottleneck load injectors before JMeter reaches its hardware capacity. Use this interactive configurator to generate tuned `/etc/sysctl.d/99-jmeter-tuning.conf`, `/etc/security/limits.d/99-jmeter.conf`, systemd overrides, and Docker/Kubernetes parameters tailored to your target scale and system RAM. --- ## Why Default Linux Limits Fail Under Load Linux out-of-the-box is configured for balanced desktop and general-purpose server workloads. High-volume load generators stress the TCP stack and operating system kernel in distinct ways: ### 1. File Descriptor Limits (`Too many open files`) Every outbound TCP socket connection, active JTL results writer, and loaded JAR library consumes a file descriptor. - **Default limit**: `ulimit -n` is typically `1024` on standard distributions. - **Under load**: A test running 2,000 threads opening connections simultaneously will crash with `java.io.IOException: Too many open files`. - **Solution**: Set `nofile` to `524,288` or `1,048,576` in `limits.conf` and `systemd` manager configs. ### 2. Ephemeral Port Exhaustion (`BindException: Address already in use`) When JMeter opens outbound HTTP/1.1 connections without keep-alive or with rapid connection cycling, closed sockets sit in the `TIME_WAIT` state for 60 seconds to ensure lingering network packets are drained. - **Default range**: `net.ipv4.ip_local_port_range` defaults to `32768 60999` (~28,231 ports). - **Under load**: Generating 1,000 new connections per second exhausts all 28k ports in less than 30 seconds, throwing `java.net.BindException: Address already in use`. - **Solution**: Expand the range to `1024 65535` (64,512 ports), enable `net.ipv4.tcp_tw_reuse = 1`, and reduce `net.ipv4.tcp_fin_timeout = 15`. > [!WARNING] > **Never enable `net.ipv4.tcp_tw_recycle`**: This legacy parameter was deprecated in Linux 4.10 and removed in 4.12 because it dropped valid SYN packets from clients or load injectors operating behind NAT / load balancers. Always use `net.ipv4.tcp_tw_reuse = 1` instead. ### 3. SYN & Listen Queue Backlog Overflows During rapid test ramp-up or surge testing, connection requests queue up in the kernel socket listen queue. - **Default backlog**: `net.core.somaxconn` defaults to `128` or `1024`. - **Under load**: Bursts overflow the queue, causing silent SYN drops and artificial connection timeouts. - **Solution**: Increase `net.core.somaxconn = 65535` and `net.ipv4.tcp_max_syn_backlog = 65535`. ### 4. Swapping Protection (`vm.swappiness = 1`) The Linux kernel aggressively pages memory to swap space when RAM usage increases. - **Default swappiness**: `60` (very prone to paging). - **Under load**: If inactive JVM heap memory is paged out to disk, the next Garbage Collection cycle must read pages back from storage, freezing threads and creating catastrophic **100ms–2000ms latency spikes**. - **Solution**: Set `vm.swappiness = 1` to ensure the kernel only swaps under critical out-of-memory emergency pressure. --- ## How to Apply These Settings ### 1. Apply Sysctl Kernel Parameters Create a dedicated file in `/etc/sysctl.d/`: ```bash sudo nano /etc/sysctl.d/99-jmeter-tuning.conf # Paste the generated sysctl.conf snippet sudo sysctl --system ``` ### 2. Apply File Descriptor Limits Place user limits in `/etc/security/limits.d/`: ```bash sudo nano /etc/security/limits.d/99-jmeter.conf # Paste the generated limits.conf snippet ``` > [!NOTE] > For `limits.conf` changes to take effect on interactive sessions, log out and log back in, then verify with `ulimit -n`. For background services managed by **systemd**, configure `DefaultLimitNOFILE` in `/etc/systemd/system.conf` and reload systemd with `sudo systemctl daemon-reexec`. ### 3. Verify Active Settings Run this quick diagnostic to confirm your kernel accepted the values: ```bash ulimit -n sysctl net.ipv4.ip_local_port_range net.ipv4.tcp_tw_reuse net.core.somaxconn vm.swappiness ss -s ``` --- ## Related Guides & Error Playbooks - [JMeter Performance Tuning Guide](/topics/jmeter-performance-tuning-guide/) - [Too Many Open Files (ulimit) Playbook](/topics/errors/too-many-open-files-ulimit/) - [BindException / Port Exhaustion Playbook](/topics/errors/bind-exception-address-in-use/) - [Heap / JVM Sizing Estimator](/tools/heap-estimator/) - [Distributed Testing Planner](/tools/distributed-planner/) - [CLI Command Builder](/tools/cli-builder/) Size your JVM heap with the [Heap Estimator](/tools/heap-estimator/) and build CLI run flags with the [CLI Builder](/tools/cli-builder/). [Distributed Testing Planner](/tools/distributed-planner/) · [Performance Tuning Guide](/topics/jmeter-performance-tuning-guide/) Enabling deprecated tcp_tw_recycle, or forgetting that systemd services ignore /etc/security/limits.conf. Still seeing BindException? Check if JMeter HTTP Request Defaults has "Use KeepAlive" enabled to reduce connection churn. --- Title: JMeter Coordinated Omission Calculator URL: https://docs.jmeter.ai/tools/coordinated-omission/ --- import CoordinatedOmission from '../../../components/tools/CoordinatedOmission.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Coordinated Omission Calculator When the server can't keep up with your target throughput, JMeter's Thread Group silently drops requests instead of queuing them. This produces **artificially low** response times and **inflated** percentiles. Enter your target RPS, actual RPS, average response time, and test duration to compute the correction factor, lost requests, corrected response time, and the thread count you should have used. ## What is coordinated omission? **Coordinated Omission** is a measurement bias that occurs when a load generator schedules the next request at a fixed interval (e.g., every 20 ms for 50 RPS) but fails to account for the time already spent waiting on the previous request. When the server degrades: 1. Threads get "stuck" waiting for slow responses. 2. Fewer requests are sent than the target rate. 3. The "missing" requests are silently dropped - never queued. 4. Measured throughput drops, but response times look artificially low. **Example:** You target 50 RPS with 100 threads. Server degrades to 5-second response time. Instead of 50 RPS, you get ~20 RPS (100 threads / 5s). Your throughput drops by 60%, and your average response time doesn't reflect what real users would experience. ## How the correction works The calculator uses the **queue-depth model** from Gil Tene's talk *[How NOT to Measure Latency](https://www.infoq.com/presentations/latency-response-time/)*: ```text correction_factor = target_RPS / actual_RPS lost_requests = (target_RPS - actual_RPS) × duration_seconds queue_depth = (target_RPS - actual_RPS) × (avg_RT_ms / 1000) corrected_RT = avg_RT_ms + (queue_depth × avg_RT_ms) needed_threads = target_RPS × (avg_RT_ms / 1000) ``` When `target_RPS > actual_RPS`, the correction factor tells you how much your measured metrics are skewed. A factor of 2.5x means your real response time is roughly 2.5× what JMeter reported. ## Example | Target RPS | Actual RPS | Avg RT | Duration | Correction | Lost reqs | Corrected RT | |------------|------------|--------|----------|------------|-----------|--------------| | 50 | 20 | 5,000ms| 60s | 2.5x | 1,800 | ~12,500ms | | 100 | 80 | 3,000ms| 120s | 1.25x | 2,400 | ~3,750ms | | 200 | 200 | 500ms | 60s | 1.0x | 0 | 500ms | ## What this does not include - **Percentile correction** - the queue-depth model corrects averages; for percentile correction, use a proper histogram (HdrHistogram) in your test. - **Think time / pacing** - real users pause between actions; this calculator assumes continuous load. - **Server-side queuing** - if the server itself queues requests, the corrected RT is a lower bound on what users experience. - **Distributed test aggregation** - run this per engine and combine results. ## Recommended workflow 1. Run your test and record target RPS, actual RPS, avg response time, and duration. 2. Use this calculator to compute the correction factor and lost requests. 3. If the factor is > 1.25, your results are significantly skewed. 4. Re-run with more threads (use the **Thread Calculator**) or lower the target RPS. 5. For accurate percentiles, instrument with HdrHistogram in your JMeter test. ## Related reading - [Best Practices](/user-manual/best-practices/) - [Thread Calculator](/tools/thread-calculator/) - [Heap Estimator](/tools/heap-estimator/) - [Generating Dashboard](/user-manual/generating-dashboard/) Size your Thread Group correctly with the [Thread Calculator](/tools/thread-calculator/) to avoid coordinated omission in the first place. [Best Practices](/user-manual/best-practices/) · [Remote testing](/user-manual/remote-test/) · [Dashboard report](/user-manual/generating-dashboard/) Setting a high target RPS with too few threads, causing throughput to drop below target while response times look artificially low. Correction factor > 2? You need significantly more threads or a lower target RPS. Use the Thread Calculator to size correctly. --- Title: JMeter Properties Cheat Sheet URL: https://docs.jmeter.ai/tools/properties-cheatsheet/ --- import PropertiesCheatsheet from '../../../components/tools/PropertiesCheatsheet.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Properties Cheat Sheet Search the properties people actually change for load tests. Always set overrides in **`user.properties`** (or `-J` / `-q`); do not edit stock `jmeter.properties` if you can avoid it. ## Related reading - Full catalog: [Properties Reference](/user-manual/properties-reference/) - [Best Practices](/user-manual/best-practices/) - [Remote Testing](/user-manual/remote-test/) - [Dashboard Report](/user-manual/generating-dashboard/) Copy a property into user.properties, restart JMeter, and verify with a small CLI run. [Hints and tips](/user-manual/hints-and-tips/) · [Heap estimator](/tools/heap-estimator/) Editing jmeter.properties in place so upgrades wipe your customizations. Property not applied? Confirm user.properties path and that JMeter was fully restarted. --- Title: JMeter Regex Extractor Builder URL: https://docs.jmeter.ai/tools/regex-tester/ --- import RegexTester from '../../../components/tools/RegexTester.astro'; import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Regex Extractor Builder Paste a response body. The tool scans for likely **dynamic values** (tokens, CSRF fields, UUIDs, JWTs) and proposes **Regular Expression Extractor** settings you can copy into JMeter. ## Privacy and limits | Rule | Detail | |------|--------| | **Where it runs** | 100% in your browser (this page). | | **What is sent** | Nothing: no upload, no server analysis. | | **Max body size** | **1 MB** (1,048,576 bytes). Larger pastes are rejected so the tab stays responsive. | | **Scope** | **Regular Expression Extractor** only (not JSON Extractor / Boundary Extractor). | ## Extractor field mapping | JMeter field | This tool | |--------------|-----------| | Name of created variable | Suggested from key / type | | Regular Expression | Generated pattern with one capture group | | Template | `$1$` | | Match No. | `1` (first match) | | Default Value | `NOT_FOUND` | ## Tips - Prefer **JSON Extractor** when the entire body is JSON; more stable than regex. - Always verify with a **Debug Sampler** or View Results Tree; browser JS RegExp is close to Java but not identical. - If nothing is found, paste a **smaller fragment** that still includes the token and its key. ## Related reading - [Regular Expressions](/user-manual/regular-expressions/) - [Functions and Variables](/user-manual/functions/) - [HTTP Recorder](/topics/http-recorder/) - [Component Reference](/user-manual/component-reference/) Add a Regular Expression Extractor under your sampler, paste the fields, then confirm with a Debug Sampler. [Functions guide](/topics/functions-and-variables/) · [Best practices](/user-manual/best-practices/) Using Match No. 0 (random) in load tests when you need a stable extraction. No candidates? Paste a smaller fragment that still includes the token. --- Title: JMeter for Beginners (2026 Path) URL: https://docs.jmeter.ai/topics/jmeter-for-beginners/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter for Beginners (2026 Path) This is a practical path from zero to a **CLI load run with an HTML report**. It uses current JMeter habits (non-GUI for load, property parameterization, dashboard reports) and links into deeper docs when you are ready. Official entry points: [Getting Started](/getting-started/get-started/), [Build a web test plan](/user-manual/build-web-test-plan/), [Best practices](/user-manual/best-practices/). ## What you will build 1. Install Java + JMeter 2. Create a Thread Group and HTTP Request 3. Add defaults, header, assertion 4. Optional: second request with a variable 5. Run non-GUI and open the HTML dashboard 6. Know what to learn next Time: about 60–90 minutes for a first success. ## Step 1: Install 1. Install a supported **Java** runtime for your JMeter version (see release notes / Getting Started). 2. Download Apache JMeter from the official distribution (this site’s [download reference](/reference/download-jmeter/) points at project download info). 3. Unzip; start GUI with `bin/jmeter` or `jmeter.bat`. You do not need a separate application server to learn: any public HTTPS test API or your local app works. ## Step 2: Mental model (5 minutes) | Piece | Role | |-------|------| | **Test Plan** | Root of the tree (`.jmx` file) | | **Thread Group** | Virtual users, ramp-up, loops | | **Sampler** | Sends a request (HTTP Request) | | **Config** | Defaults, headers, CSV | | **Assertion** | Pass/fail rules | | **Listener** | Shows results (debug only under load) | JMeter is **not** a browser. It measures protocol requests, not React render time. Deep dive: [Elements of a Test Plan](/user-manual/test-plan/). ## Step 3: First HTTP GET 1. Add **Thread Group**: 1 thread, ramp-up 1, loop 1. 2. Add **HTTP Request Defaults**: protocol `https`, server name (e.g. your API host). 3. Add **HTTP Request**: method GET, path `/` or a simple health path. 4. Add **View Results Tree** under the Thread Group. 5. Run (green start). Click the sampler in Tree; confirm response code. Follow the same structure as [Building a Web Test Plan](/user-manual/build-web-test-plan/) (Thread Group → defaults → requests → listener). ## Step 4: Make it an API-style call 1. Add **HTTP Header Manager**: `Accept: application/json` (and `Content-Type` for POST). 2. Change path to a JSON endpoint. 3. Add **Response Assertion**: response code `200` (or expected code). 4. Run again; Tree should show success. More detail: [API load testing](/topics/api-load-testing/). ## Step 5: POST with a body (optional) 1. New HTTP Request, method POST, path `/items`. 2. Body Data: ```json {"name":"demo","requestId":"\${__UUID}"} ``` 3. Header `Content-Type: application/json`. 4. Assert 200/201. `\${__UUID}` is a built-in function ([functions guide](/topics/functions-and-variables/)). ## Step 6: Tiny correlation (optional but important) If the POST returns `{"id":"123"}`: 1. Add **JSON Extractor** (or Regex Extractor) under POST → variable `itemId`. 2. GET `/items/\${itemId}`. 3. Default value `NOT_FOUND` on the extractor. Deep dive: [Correlation](/topics/correlation-dynamic-values/). ## Step 7: Parameterize for real runs On the Thread Group: - Number of threads: `\${__P(threads,1)}` - Ramp-up: `\${__P(rampup,1)}` HTTP Defaults server: `\${__P(host,httpbin.org)}` (use your host). This is the official parameterization pattern from [best practices](/user-manual/best-practices/). ## Step 8: Non-GUI load (the 2026 default) 1. **Disable** View Results Tree. 2. Save plan as `first-api.jmx`. 3. Open a terminal in a directory you can write to: ```bash jmeter -n -t first-api.jmx -l results.jtl -e -o report/ \ -Jthreads=5 -Jrampup=5 -Jhost=your.api.host ``` 4. Open `report/index.html` in a browser. You should see APDEX, statistics, and error tables ([dashboard manual](/user-manual/generating-dashboard/)). :::caution[Never load-test in GUI] GUI + View Results Tree skews injector performance. Interviewers and production teams expect CLI for load. ::: ## Step 9: Read the report like a beginner | Widget | Question it answers | |--------|---------------------| | Error % | Did calls fail? | | Average / percentiles | How slow? | | Throughput | How many requests/sec? | | APDEX | How many samples met thresholds? | Threshold defaults (satisfied 500 ms, tolerated 1500 ms) are configurable ([APDEX topic](/topics/apdex-slo-percentiles/)). ## Step 10: Next skills (ordered) 1. [HTTP Recorder](/topics/http-recorder/) for browser apps 2. [CSV users](/user-manual/best-practices/) for multi-user 3. [JWT/OAuth](/topics/jwt-oauth-sso/) for protected APIs 4. [Thread sizing](/tools/thread-calculator/) before big numbers 5. [CI/CD](/topics/ci-cd-load-testing/) to automate the CLI 6. [Distributed](/topics/distributed-testing/) when one machine is not enough 7. [Troubleshooting](/topics/troubleshooting/) when things break ## Common beginner mistakes | Mistake | Fix | |---------|-----| | Load test in GUI | Use `-n` | | No assertions | Assert status codes | | Thousands of threads day one | Start with 5–20; size properly | | Hard-coded tokens | Correlate or properties | | Ignoring errors in Tree | Fix red samples before scaling | ## Optional: containers When comfortable with CLI, run the same command in Docker ([Docker/Kubernetes](/topics/docker-kubernetes/)) with `qainsights/jmeter` or your pinned image. ## Frequently asked questions ### Do I need to know Java to use JMeter? No for basic HTTP plans. Java is required to **run** JMeter. Groovy helps for advanced scripting later. ### Which JMeter version should beginners install? A current stable release (this site last-verified notes reference the 5.6 line). Avoid very old versions per best practices. ### Is the HTTP recorder required? No. For APIs, manual HTTP Request or [cURL import](/user-manual/curl/) is often cleaner. Recorder helps for web UIs. ### How many threads for a first test? Start with 1 to validate, then 5–10 for a tiny load. Use the Thread Calculator before large tests. ### Where is the HTML report? The folder you pass to `-o` after a successful `-e` generation (open `index.html`). ### What should I learn after the first report? Correlation, parameterization with CSV/`__P`, and CI automation of the same CLI command. Complete Step 8 with your own host and open the HTML dashboard; then add one assertion you care about. - [Getting Started](/getting-started/get-started/) - [API Load Testing](/topics/api-load-testing/) - [Best Practices](/user-manual/best-practices/) - [Interview Questions](/topics/interview-questions/) --- Title: JMeter for API Load Testing URL: https://docs.jmeter.ai/topics/api-load-testing/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter for API Load Testing Apache JMeter is widely used for API load testing because the same [HTTP Request sampler](/user-manual/component-reference/) that drives browser-style web tests also drives REST, SOAP, and many JSON/XML backends. This guide walks through building an API-focused plan: install and first run, sampler configuration, headers and auth, parameterization, correlation, assertions, load sizing, CLI execution, reporting, and common failure modes. It is grounded in JMeter’s documented behaviour for HTTP sampling, variables, best practices, and dashboard reporting. For full field lists, use the [Component Reference](/user-manual/component-reference/) and [Functions and Variables](/user-manual/functions/) pages. :::tip[Use CLI mode for real load] Build and debug API plans in the GUI, then run load tests with `jmeter -n -t plan.jmx -l results.jtl -e -o report/` so the GUI does not consume injector resources. ::: :::caution[Avoid View Results Tree in load tests] Use View Results Tree only while debugging individual requests. Disable it before real API load runs because it stores response details in memory. ::: ## What “API load testing” means in JMeter In JMeter, an API test is still a **test plan**: one or more [Thread Groups](/user-manual/test-plan/), samplers that issue protocol requests, config elements (defaults, headers, cookies), post-processors that extract data, assertions that mark samples as pass/fail, and listeners or CLI result files for analysis. For HTTP APIs you typically: 1. Create a Thread Group (virtual users, ramp-up, loops or duration). 2. Add [HTTP Request Defaults](/user-manual/component-reference/) for host, port, and protocol. 3. Add an [HTTP Header Manager](/user-manual/component-reference/) for `Content-Type`, `Accept`, and auth headers. 4. Add one HTTP Request sampler per endpoint or transaction step. 5. Parameterize bodies and paths with [variables and functions](/topics/functions-and-variables/). 6. Extract tokens or IDs from responses for the next request. 7. Assert status codes and key body fields. 8. Run non-GUI load and open the [HTML dashboard](/user-manual/generating-dashboard/). JMeter does **not** execute client-side JavaScript in a real browser. It measures the server-facing protocol exchange (requests and responses). That is usually what you want for API performance, but it is different from browser UX timing. ## Prerequisites and first plan If you are new to JMeter: 1. [Getting Started](/getting-started/get-started/) - install Java and JMeter, understand GUI vs CLI. 2. [Building a Test Plan](/user-manual/build-test-plan/) - add/remove elements, save, run, stop. 3. [Building a Web Test Plan](/user-manual/build-web-test-plan/) - Thread Group, HTTP defaults, cookie manager, first HTTP samples. ### Minimal API plan shape A maintainable API plan often looks like this tree: ```text Test Plan ├── User Defined Variables (optional) ├── HTTP Request Defaults ├── HTTP Header Manager ├── HTTP Cookie Manager (if cookie-based sessions) └── Thread Group ├── Login (HTTP Request) + extractors + assertions ├── Business APIs (HTTP Requests) + extractors + assertions └── (optional) CSV Data Set Config for user/data rows ``` Prefer **one sampler reused in a loop with variables** over dozens of nearly identical samplers. Official [best practices](/user-manual/best-practices/) call this out as a way to cut resource use and keep plans maintainable. ## Configuring the HTTP Request sampler The [HTTP Request](/user-manual/component-reference/) sampler is the core element for REST and most HTTP APIs. ### Fields you will use constantly | Area | Typical API use | |------|-----------------| | **Protocol / Server / Port** | Prefer HTTP Request Defaults so every sampler inherits host and TLS settings | | **Method** | GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS as needed | | **Path** | Endpoint path, often with variables: `/v1/orders/\${orderId}` | | **Parameters** | Query or form parameters (depending on method and encoding) | | **Body Data** | Raw JSON, XML, or other payload for POST/PUT/PATCH | | **Content encoding** | Character encoding for the request body when relevant | ### Body Data vs Parameters For JSON APIs, put the payload in **Body Data** and set `Content-Type: application/json` on the Header Manager (or a child Header Manager scoped to that sampler). Using form parameters when the API expects a JSON body is a common source of `400` responses. Example body with variables: ```json { "email": "\${email}", "quantity": \${quantity}, "requestId": "\${__UUID}" } ``` ### HTTP Request Defaults Add **HTTP Request Defaults** under the Test Plan or Thread Group and set: - Server name or IP - Port - Protocol (`https` for most public APIs) - Optional common path prefix Samplers then only override path, method, and body. That matches the pattern used in the [web test plan tutorial](/user-manual/build-web-test-plan/). ## Headers, cookies, and authentication ### Header Manager Use an [HTTP Header Manager](/user-manual/component-reference/) for: - `Content-Type: application/json` - `Accept: application/json` - `Authorization: Bearer \${accessToken}` after login - Custom headers (`X-Request-Id`, API keys, tenant IDs) Scope matters: - **Thread Group level** - shared headers for all requests in that group. - **Sampler level** - overrides for one call (for example a different `Content-Type`). For advanced web scenarios that customize User-Agent or similar headers, see [Building an Advanced Web Test Plan](/user-manual/build-adv-web-test-plan/). ### Cookie Manager If the API uses session cookies (or a BFF that sets cookies), add an [HTTP Cookie Manager](/user-manual/component-reference/). Place it where the web tutorial recommends so each thread keeps its own cookie jar. Without it, multi-step flows that rely on `Set-Cookie` will fail after the first request. ### Common auth patterns **Bearer / JWT after login** 1. POST credentials to `/oauth/token` or `/login`. 2. Extract `access_token` (JSON Extractor or Regular Expression Extractor). 3. On later samplers, set `Authorization` to `Bearer \${accessToken}`. **API key header** - Store the key in a Test Plan variable or property (`\${__P(apiKey,)}`) and inject it as a header. Prefer properties for secrets passed on the CLI so they are not hard-coded in the `.jmx`. **Basic auth** - Use the [HTTP Authorization Manager](/user-manual/component-reference/) when appropriate, or set a Base64 `Authorization` header deliberately. See also the advanced web plan notes on where to put the Authorization Manager. **SOAP** - The [webservice test plan](/user-manual/build-ws-test-plan/) shows building SOAP/REST-style tests with HTTP Request, Body Data, and Header Manager (`SOAPAction`, `Content-Type`). The same pattern applies to modern REST JSON APIs. ### Importing from cURL If you already have working `curl` commands from developers or Postman exports, use JMeter’s [cURL import](/user-manual/curl/) to create HTTP samplers quickly, then clean up defaults, variables, and assertions. ## Parameterization: users, data, and environments Hard-coded credentials and IDs do not scale. Grounded options from the manual: ### CSV Data Set Config From [best practices](/user-manual/best-practices/): 1. Create a text file of usernames and passwords (comma-separated) next to the plan. 2. Add **CSV Data Set Config**; name variables (for example `USER`, `PASS`). 3. Reference `\${USER}` and `\${PASS}` on samplers. 4. The element reads a new line for each thread (per documented CSV Data Set behaviour for multi-user login). Use CSV for product IDs, search terms, and tenant names the same way. Pre-generate large data files instead of inventing random data in expensive scripts during the run when possible. ### Functions for dynamic values See the dedicated [Functions and Variables topic](/topics/functions-and-variables/) and the [full functions reference](/user-manual/functions/). Frequently used in API tests: | Need | Example | |------|---------| | Unique id | `\${__UUID}` | | Random int | `\${__Random(1,1000)}` | | Timestamp | `\${__time(yyyy-MM-dd'T'HH:mm:ss)}` (escape commas in formats when needed) | | Thread number | `\${__threadNum}` | | Property override | `\${__P(threads,10)}` | ### Properties for environments and CI Define Thread Group or host settings from properties so CLI and CI can override without editing XML: ```text threads = \${__P(threads,10)} rampup = \${__P(rampup,30)} host = \${__P(host,api.example.com)} ``` Run: ```bash jmeter -n -t api-plan.jmx -Jthreads=50 -Jrampup=60 -Jhost=staging.example.com -l results.jtl -e -o report/ ``` Official guidance: use `__P` (or `__property`) for values that must be global or overridden from the command line; use [variables](/user-manual/functions/) for thread-local state. For many properties together, pass a property file with `-q`. ## Correlation: chaining API calls Most real APIs require values from response A in request B (login token, cart id, ETag, CSRF). ### Prefer structured extractors for JSON For JSON bodies, prefer **JSON Extractor** or JMESPath-style extraction when available on your JMeter version/plugins stack over brittle full-body regular expressions. Use [Regular Expression Extractor](/user-manual/regular-expressions/) for free-text tokens, HTML fragments, or headers when needed. Typical flow: 1. Login sampler returns `{"access_token":"...","expires_in":3600}`. 2. JSON Extractor sets `accessToken`. 3. Header Manager or sampler header uses `Bearer \${accessToken}`. 4. Create-order response yields `orderId`; next GET uses `/orders/\${orderId}`. ### Defaults and failure visibility Always set a **Default Value** on extractors (for example `NOT_FOUND`) so missing tokens are obvious in View Results Tree while debugging. Pair extractors with assertions so a failed login does not silently produce thousands of `401`s. ### Regex Extractor Builder For crafting regex correlation fields quickly, use the site’s [Regex Extractor Builder](/tools/regex-tester/) (browser-only paste analysis), then paste Name, Regular Expression, Template (`$1$`), Match No., and Default into the extractor under the sampler. ## Assertions: define success before you scale Without assertions, JMeter may report “green” throughput while every response is an error page or empty body. Common choices: - **Response Assertion** - response code `200`, or substring/contains checks on body. - **JSON Assertion** / JSON Path checks - required fields present. - **Duration Assertion** - fail samples slower than a threshold (use carefully; it affects error rate). - **Size Assertion** - non-empty body. Official [best practices](/user-manual/best-practices/) advise using **as few assertions as possible** under load because each assertion costs CPU. Debug with richer checks; keep a minimal set for the load run (status code + one critical field is a common compromise). ## Controllers and realistic API scenarios API load is rarely a single GET in a loop. Useful logic controllers (see [test plan elements](/user-manual/test-plan/) and component reference): - **Once Only Controller** - login once per thread, then loop business calls. - **Transaction Controller** - group login+search+checkout samples into one reported transaction for the dashboard. - **If Controller** - branch on `\${accessToken}` / response variables. - **Loop Controller / While Controller** - pagination or poll-until-ready patterns (guard with timeouts). - **Throughput Controller** - mix traffic (for example 70% read / 30% write). Timers (constant, uniform random, precise throughput) model think time and pacing. Without think time, threads hammer the API as fast as responses return - which is valid for stress tests but not for “N concurrent users browsing.” ## Sizing threads, ramp-up, and avoiding bad metrics From [best practices](/user-manual/best-practices/): thread count depends on injector hardware, plan design, and how fast the server responds. Undersizing threads relative to target rate contributes to **coordinated omission** (inflated performance picture when the client cannot keep issuing requests on schedule). Practical workflow: 1. Measure average response time with a small pilot. 2. Estimate concurrency with the [Thread Group Calculator](/tools/thread-calculator/) (Little’s Law style: threads ≈ RPS × response time in seconds when busy and no think time). 3. Ramp gradually; very short ramp-ups create a thundering herd. 4. Re-measure under load - response times rise, so thread needs change. 5. If one injector is saturated, scale out with [distributed testing](/topics/distributed-testing/) or multiple independent CLI engines. Also use the [Heap Estimator](/tools/heap-estimator/) and [Coordinated Omission](/tools/coordinated-omission/) tools when results look “too good” or injectors struggle. ## Running the test: GUI vs CLI ### Debug in GUI - Small thread count (1-5). - View Results Tree enabled. - Confirm extractors, headers, and assertions. - Disable or remove heavy listeners before load. ### Load in non-GUI mode Documented resource advice: ```bash jmeter -n -t api-plan.jmx -l results.jtl -e -o report/ ``` | Flag | Meaning | |------|---------| | `-n` | Non-GUI mode | | `-t` | Test plan path | | `-l` | Sample results file (prefer CSV saveservice defaults) | | `-e` | Generate HTML dashboard after the run | | `-o` | Output folder for the dashboard (must be empty/new) | | `-Jname=value` | Set JMeter property for `\${__P(name)}` | Further [best practices](/user-manual/best-practices/) for lean runs: - Use CLI mode. - As few listeners as possible; with `-l` you can disable them all. - Do not use View Results Tree / Table during load. - Prefer CSV result output over XML. - Only save fields you need. - Prefer JSR223 + Groovy with “Cache compiled script” and `vars.get("x")` instead of `\${x}` inside cached scripts. ## Analyzing API results ### HTML dashboard The [dashboard generator](/user-manual/generating-dashboard/) reads CSV results and produces: - APDEX table (thresholds configurable via reportgenerator properties in `user.properties`) - Statistics table (including configurable percentiles) - Error tables and top errors by sampler - Charts: response times over time, active threads, bytes, latencies, hits/s, transactions/s, and more Generate at end of test with `-e -o`, or offline from an existing `.jtl`. ### Listeners during scripting only [Listeners](/user-manual/listeners/) such as View Results Tree and Summary Report help while building the plan. They are not a substitute for the dashboard under load. ### Real-time monitoring For live graphs during long API tests, use the [Backend Listener](/user-manual/realtime-results/) to stream metrics to InfluxDB/Grafana (or other backends supported by your setup). That complements, not replaces, the post-run dashboard. ## CI/CD and API performance gates API plans belong in the pipeline: 1. Store `.jmx` and CSV data next to application code. 2. Run non-GUI JMeter in the job. 3. Archive `results.jtl` and the `report/` folder. 4. Fail the build when error rate or key percentiles regress. Details and examples: [CI/CD Load Testing](/topics/ci-cd-load-testing/). Parameterize hosts and thread counts with `-J` / `\${__P(...)}` so the same plan hits staging nightly and a smaller gate on every PR. ## Protocol notes beyond simple REST | Style | JMeter approach | |-------|-----------------| | **REST JSON** | HTTP Request + Header Manager + JSON extractors/assertions | | **SOAP/XML** | HTTP Request + XML body + SOAP-related headers ([WS plan](/user-manual/build-ws-test-plan/)) | | **GraphQL** | HTTP POST to `/graphql` with JSON body (`query` / `variables`); treat like REST | | **Multipart upload** | HTTP Request file upload fields (see component reference) | | **WebSocket / gRPC** | Not core HTTP; requires plugins or other tools - plan protocol support explicitly | JMeter’s strength is **protocol breadth** (HTTP plus JDBC, JMS, LDAP, FTP, and more in-box). Stay on HTTP Request when the system under test is an HTTP API unless you have a clear need for another sampler. ## Common API load-testing mistakes | Mistake | What goes wrong | Fix | |---------|-----------------|-----| | Load test in GUI with View Results Tree | Injector CPU/memory distort results | CLI + `-l`; listeners off | | No assertions | Errors counted as successful samples | Assert status + critical fields | | Hard-coded tokens | Fail after expiry; not multi-user | Extract per thread; CSV users | | All threads same user | Unrealistic cache/locking behaviour | CSV Data Set unique logins | | Zero ramp-up to high threads | Spike, not soak; noisy errors | Ramp over minutes | | Functional mode / saving full bodies | Huge files, slow I/O | CSV, minimal saveservice fields | | BeanShell/JavaScript for hot paths | High CPU, poor scalability | JSR223 Groovy, compiled cache | | Undersized threads for target RPS | Coordinated omission | Thread calculator + pilot | | Secrets committed in `.jmx` | Credential leaks | `\${__P(secret,)}` / CI secrets | ## End-to-end checklist 1. Install current JMeter; avoid very old releases ([best practices](/user-manual/best-practices/)). 2. Create Thread Group + HTTP Defaults + Header Manager. 3. Add login and business HTTP samplers; import from [cURL](/user-manual/curl/) if useful. 4. Parameterize with CSV and `\${__P(...)}`. 5. Correlate tokens/IDs; assert success. 6. Debug with 1-5 threads and View Results Tree. 7. Disable heavy listeners; size threads and heap. 8. Run `jmeter -n -t … -l … -e -o …`. 9. Read APDEX, error %, and percentiles on the dashboard. 10. Wire the same command into CI with gates. ## Related tools on this site - [Thread Calculator](/tools/thread-calculator/) - RPS and response time → threads - [Heap Estimator](/tools/heap-estimator/) - starting `-Xmx` guidance - [Properties Cheat Sheet](/tools/properties-cheatsheet/) - high-impact properties - [Regex Extractor Builder](/tools/regex-tester/) - correlation helpers - [Coordinated Omission](/tools/coordinated-omission/) - when achieved RPS is below target ## Frequently asked questions ### Can JMeter load test REST APIs? Yes. Use the HTTP Request sampler with the appropriate method, path, headers, and body. REST is not a separate sampler type; it is HTTP with JSON/XML payloads and status conventions. ### Does JMeter run JavaScript in API responses? No. JMeter does not render pages or run browser JavaScript. It records protocol-level timings for the requests it sends. Client-side rendering cost is out of scope unless you use a real-browser tool alongside JMeter. ### Should I record APIs with the HTTP(S) Test Script Recorder? You can record browser or proxy traffic, then delete static assets and parameterize. Many API teams prefer building HTTP samplers directly or importing [cURL](/user-manual/curl/). If you record, follow the [recorder guide](/topics/http-recorder/) and [best practices](/user-manual/best-practices/) on include/exclude patterns. ### How do I pass an Authorization bearer token? Extract the token from the login response into a variable, then set header `Authorization` to `Bearer \${token}` via Header Manager. Keep the token thread-local unless you intentionally share via properties. ### How many threads do I need for an API test? It depends on target throughput, response time, think time, and injector capacity. Start from RPS × service time, validate with a pilot, and use the [Thread Calculator](/tools/thread-calculator/). Official docs stress correct sizing to avoid coordinated omission. ### Why is throughput lower than I expect? Common causes: server saturation (response time rose), injector limits, listeners left on, think time/timers, assertion cost, connection limits, or too few threads. Compare achieved hits/s on the dashboard with active threads and error rate. ### GUI or non-GUI for the real API load run? Non-GUI. Official best practices recommend CLI mode for load and GUI for building/debugging. Build your first HTTP flow with [Building a Web Test Plan](/user-manual/build-web-test-plan/), then parameterize hosts and threads with `\${__P(...)}` for CLI runs. - [cURL Import](/user-manual/curl/) - create samplers from existing curl commands - [Component Reference](/user-manual/component-reference/) - full HTTP Request and Header Manager fields - [Functions and Variables](/topics/functions-and-variables/) - dynamic data and properties - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automate API gates Leaving View Results Tree enabled during load; asserting nothing; hard-coding tokens; zero ramp-up to thousands of threads. 401/403 after the first call usually means missing Cookie Manager, expired token extraction, or Header Manager scope. Empty extractors: check response in View Results Tree and extractor default values. --- Title: JMeter JWT, OAuth, and SSO Load Testing URL: https://docs.jmeter.ai/topics/jwt-oauth-sso/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter JWT, OAuth, and SSO Load Testing Most modern APIs and portals require authentication. Under load you must obtain credentials **per virtual user**, keep tokens fresh, and attach them on every protected call without hard-coding secrets. This guide covers JWT bearer flows, OAuth-style token endpoints, cookie-based SSO patterns, and failure modes using core JMeter HTTP elements documented in the [component reference](/user-manual/component-reference/), [functions](/user-manual/functions/), and [best practices](/user-manual/best-practices/). JMeter does not ship a dedicated "OAuth sampler." You model auth as ordinary [HTTP Request](/user-manual/component-reference/) steps plus headers, cookies, and extractors. That matches how production clients call token and resource servers. :::tip[CLI for real load] Debug token extractors in the GUI with one thread, then run `jmeter -n -t plan.jmx -l results.jtl -e -o report/`. Leave View Results Tree off during load. ::: :::caution[Secrets in the plan] Do not commit client secrets or passwords in the `.jmx`. Pass them with `\${__P(clientSecret,)}` and CI secrets (`-JclientSecret=...`), as described under [parameterising tests](/user-manual/best-practices/). ::: ## What you are simulating | Pattern | What JMeter must do | |---------|---------------------| | **API key** | Static or property-driven header on every call | | **Bearer JWT** | Login/token call, extract access token, set `Authorization` | | **OAuth2 client credentials** | POST to token URL with client id/secret, extract token | | **OAuth2 password / ROPC** (if your IdP still allows it) | POST username/password, extract token | | **Authorization code + browser SSO** | Often needs recording, cookies, and correlation of state/CSRF (see [recorder](/topics/http-recorder/)) | | **Session cookie SSO** | Cookie Manager + login form POST; optional CSRF extract | For pure HTTP APIs, start from the [API load testing](/topics/api-load-testing/) plan shape, then add an auth step in front of business calls. ## Baseline plan shape ```text Test Plan ├── User Defined Variables / properties for host, client_id ├── HTTP Request Defaults (protocol, server, port) ├── HTTP Header Manager (Content-Type, Accept) ├── HTTP Cookie Manager (if browser/SSO cookies matter) └── Thread Group ├── Once Only Controller (or first sampler) │ ├── Token / Login HTTP Request │ ├── JSON or Regex Extractor → accessToken │ └── Response Assertion (2xx) ├── HTTP Header Manager (Authorization: Bearer \${accessToken}) │ or header on each protected sampler └── Business HTTP Requests + assertions ``` Use a [Once Only Controller](/user-manual/component-reference/) so each thread logs in once, then loops API work. That models long-lived sessions better than re-authenticating every iteration (unless your scenario requires re-login). ## Bearer JWT after a token endpoint ### 1. Token request Typical OAuth2 token endpoint (fields vary by IdP): - Method: **POST** - Path: `/oauth/token` or `/realms/.../protocol/openid-connect/token` - Body (x-www-form-urlencoded) or JSON, depending on the provider - Common fields: `grant_type`, `client_id`, `client_secret`, optional `scope`, `username`, `password` Example form-style body (illustrative): ```text grant_type=client_credentials&client_id=\${__P(clientId,)}&client_secret=\${__P(clientSecret,)}&scope=api.read ``` Set `Content-Type: application/x-www-form-urlencoded` on a Header Manager scoped to this sampler when using form encoding. For JSON token APIs, use Body Data and `application/json`. ### 2. Extract the access token Prefer a **JSON Extractor** (or JMESPath-style extraction when available) when the body is: ```json { "access_token": "eyJhbGciOi...", "expires_in": 3600, "token_type": "Bearer" } ``` - Names of created variables: `accessToken` - JSON Path examples commonly used: `$.access_token` (confirm against your response) - Default value: `TOKEN_NOT_FOUND` so failures are visible If the token is only available as free text, use a [Regular Expression Extractor](/user-manual/regular-expressions/) with a capture group and template `$1$`. The site [Regex Extractor Builder](/tools/regex-tester/) helps draft fields from a sample body (browser-local). ### 3. Attach the header Add an [HTTP Header Manager](/user-manual/component-reference/): | Name | Value | |------|--------| | Authorization | `Bearer \${accessToken}` | Scope: - Under the Thread Group after login for all subsequent calls, or - On each protected sampler if some calls are public Header Manager children of a sampler override or supplement higher-level managers depending on how you structure the tree; keep the model simple: one post-login Header Manager for the protected section. ### 4. Assert login success Without assertions, failed logins produce hours of `401` noise. Add a [Response Assertion](/user-manual/component-reference/) on the token sampler for response code `200` (or whatever your IdP returns) and optionally a substring check that `access_token` appears. ## Per-user credentials with CSV Official [best practices](/user-manual/best-practices/) show multi-user login via **CSV Data Set Config**: 1. File with `user,pass` (or `client_id,client_secret` per tenant). 2. Variable names matching columns. 3. Reference `\${user}` / `\${pass}` on the token or login sampler. 4. Each thread receives rows according to CSV config (sharing mode matters for uniqueness). Never use one shared password for thousands of threads if the system under test enforces concurrent session limits or rate-limits that user. ## Token refresh and expiry JWTs expire (`expires_in`). Options under load: 1. **Long enough tokens** for the test duration (lab-only convenience). 2. **Re-login each loop** (simple; higher auth traffic). 3. **Conditional refresh**: If Controller when remaining lifetime is low (requires storing issue time and comparing with `\${__time}` / script logic). 4. **Refresh token grant** if the IdP returns `refresh_token`: second HTTP Request + extractor updating `accessToken`. Keep refresh logic thread-local via **variables**. Do not put per-user access tokens in **properties** unless you intentionally share one token across threads (usually unrealistic and unsafe). Variables are thread-local; properties are JVM-global ([functions guide](/topics/functions-and-variables/)). ## Cookie-based SSO and portals Browser SSO often sets session cookies after SAML/OIDC redirects. 1. Add an [HTTP Cookie Manager](/user-manual/component-reference/) at Test Plan or Thread Group level so each thread has its own jar ([web test plan](/user-manual/build-web-test-plan/)). 2. Record the login journey with the [HTTP(S) Test Script Recorder](/topics/http-recorder/), or build the POST sequence manually. 3. Correlate CSRF, `state`, `nonce`, and form fields ([correlation guide](/topics/correlation-dynamic-values/)). 4. Replay with one thread until green, then scale. JMeter does **not** execute browser JavaScript. If login requires heavy client-side crypto or WebAuthn-only paths, you may need a different approach (pre-minted tokens, test IdP, or a real browser tool for that step only). ## Authorization Manager and Basic auth For HTTP Basic, the [HTTP Authorization Manager](/user-manual/component-reference/) can supply credentials for a base URL. For Bearer JWT, Header Manager is the usual path. See also [advanced web test plan](/user-manual/build-adv-web-test-plan/) notes on where to place managers. ## Parameterizing environments | Property | Example use | |----------|-------------| | `tokenUrl` / `host` | Staging vs prod IdP | | `clientId` / `clientSecret` | CI secrets | | `threads` / `rampup` | Load profile | ```bash jmeter -n -t auth-api.jmx \ -Jhost=api.staging.example.com \ -JclientId="$CLIENT_ID" \ -JclientSecret="$CLIENT_SECRET" \ -Jthreads=50 \ -l results.jtl -e -o report/ ``` Plan fields use `\${__P(host,)}` and similar ([best practices](/user-manual/best-practices/)). ## Assertions and SLOs for auth traffic Measure: - Token endpoint **error %** and latency separately from business APIs (use clear sampler labels). - Business API **401/403** rate (auth regression). - Overall APDEX/percentiles on the [dashboard](/user-manual/generating-dashboard/). If the IdP is shared, include it in capacity discussions: load tests can DDoS your own auth tier. ## Common failure modes | Symptom | Likely cause | Fix | |---------|--------------|-----| | All 401 after first success in recording | Token/cookie not correlated | Extractor + Cookie Manager | | `\${accessToken}` literal in header | Extractor failed | Default value, Tree view, JSON path | | Works for 1 user, fails at scale | IdP rate limit, same user CSV | Unique users; throttle auth | | Intermittent 401 mid-test | Expiry | Refresh or re-login | | SSL errors to IdP | Trust store / SNI | JVM trust; HTTP Request TLS settings | | Secrets leaked in jmx/jtl | Body saved | Minimize saveservice; property secrets | ## Security checklist 1. Property-driven secrets only. 2. Restrict who can download CI artifacts that may contain tokens in request bodies (prefer not saving full bodies). 3. Use synthetic users in non-prod IdPs. 4. Do not disable TLS verification outside isolated labs. 5. Align test scopes with least privilege. ## Related reading - [API Load Testing](/topics/api-load-testing/) - [Correlation / dynamic values](/topics/correlation-dynamic-values/) - [Functions and Variables](/topics/functions-and-variables/) - [HTTP Recorder](/topics/http-recorder/) - [Best Practices](/user-manual/best-practices/) - [CI/CD](/topics/ci-cd-load-testing/) ## Frequently asked questions ### Does JMeter have a built-in OAuth sampler? No. Model token and resource calls with HTTP Request, Header Manager, Cookie Manager, and extractors. ### How do I send a JWT bearer token? Extract `access_token` into a variable, then set header `Authorization` to `Bearer \${accessToken}`. ### Should every thread share one token? Usually no. Shared tokens hide per-user cache and session behaviour and can hit concurrent-use limits. Prefer CSV users or client-credentials per tenant as your scenario requires. ### Why do I get 401 only under load? Token expiry, IdP throttling, wrong cookie scope, or extractors failing when error bodies replace JSON tokens. Assert on the login sampler and watch error % by label on the dashboard. ### Can I load test SAML browser SSO? You can record HTTP redirects and posts, but complex browser-only steps may not replay. Many teams inject API tokens for the load phase and test full SSO separately. ### Where do I store client secrets? In CI secrets or local env, passed via `-J` into `\${__P(...)}`, not hard-coded in the plan file. Build a token sampler with JSON extraction and a single protected GET; validate with one thread before scaling. - [Correlation](/topics/correlation-dynamic-values/) - extractors end-to-end - [API Load Testing](/topics/api-load-testing/) - HTTP plan structure - [Functions and Variables](/topics/functions-and-variables/) - __P and CSV Hard-coded bearer tokens in the jmx; no assertion on login; one shared user for all threads; saving full Authorization headers in verbose XML results. Literal `\${accessToken}` means the extractor did not run or the path is wrong. Open View Results Tree on the token response and fix the JSON path or regex before increasing threads. --- Title: JMeter Mutual TLS (mTLS) & Client Certificates URL: https://docs.jmeter.ai/topics/client-certificates-mtls-keystore/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Mutual TLS (mTLS) & Client Certificates **Mutual TLS (mTLS)**—also known as two-way SSL authentication—requires both the client and the server to verify each other’s cryptographic certificates during the TLS handshake. It is widely used in banking APIs, zero-trust enterprise microservices, B2B integrations, and healthcare systems. This guide explains how to configure client certificates in Apache JMeter using PKCS#12 / JKS keystores, assign unique certificates per virtual user using **KeyStore Configuration**, and troubleshoot SSL handshake errors. --- ## 1. Preparing the Keystore JMeter supports both standard **PKCS#12** (`.p12` / `.pfx`) and Java **JKS** (`.jks`) keystores. If you have a client certificate (`client.crt`) and private key (`client.key`): ```bash # Convert PEM cert + key into PKCS12 format openssl pkcs12 -export \ -in client.crt \ -inkey client.key \ -out client-keystore.p12 \ -name "client_user_1" \ -password pass:secretPassword123 ``` --- ## 2. Global Single-Certificate Setup (via System Properties) If all threads in your load test use the **same** client certificate, you can configure JMeter globally via `system.properties` or command-line parameters: ### In `bin/system.properties` (or passed via `-D` in CLI): ```properties javax.net.ssl.keyStore=/path/to/client-keystore.p12 javax.net.ssl.keyStorePassword=secretPassword123 javax.net.ssl.keyStoreType=PKCS12 # If target server uses a private custom CA root: javax.net.ssl.trustStore=/path/to/custom-truststore.jks javax.net.ssl.trustStorePassword=trustSecret123 ``` ### In Non-GUI CLI Mode: ```bash jmeter -n -t plan.jmx \ -Djavax.net.ssl.keyStore=./certs/client.p12 \ -Djavax.net.ssl.keyStorePassword=secretPassword123 \ -Djavax.net.ssl.keyStoreType=PKCS12 \ -l results.jtl ``` --- ## 3. Multiple Unique Certificates per Virtual User (KeyStore Configuration) In real-world testing (e.g., simulating 1,000 distinct banking customers), each virtual user requires their **own unique client certificate**. ### Step 1: Create a Combined Multi-Certificate Keystore Import multiple certificates with sequential alias names (`cert_0`, `cert_1`, `cert_2`, ...): ```bash # Import alias 1 keytool -importkeystore \ -srckeystore user1.p12 -srcstoretype PKCS12 -srcstorepass pass1 \ -destkeystore multi-client.jks -deststoretype JKS -deststorepass masterPass \ -srcalias user1 -destalias cert_0 # Import alias 2 keytool -importkeystore \ -srckeystore user2.p12 -srcstoretype PKCS12 -srcstorepass pass2 \ -destkeystore multi-client.jks -deststoretype JKS -deststorepass masterPass \ -srcalias user2 -destalias cert_1 ``` ### Step 2: Configure `system.properties` for Dynamic Alias Support In `system.properties`: ```properties https.use.cached.ssl.context=false ``` *(Setting `https.use.cached.ssl.context=false` is essential: it forces JMeter to evaluate the keystore context per thread rather than caching the first certificate across the entire JVM).* ### Step 3: Add the KeyStore Configuration Element In your JMeter test plan: 1. Add **Config Element → Keystore Configuration**. 2. Configure fields: - **Preload**: `True` - **Variable name containing certificate alias**: `clientCertAlias` - **Alias start index**: `0` - **Alias end index**: `99` (for 100 certificates) ### Step 4: Map Aliases to Virtual Users Add a **User Defined Variables** or **CSV Data Set Config** with `clientCertAlias` variable: - Thread 1 gets `cert_0` - Thread 2 gets `cert_1` - Or use `cert_\${__threadNum}` to auto-map by thread ID. --- ## 4. GUI SSL Manager (Interactive Testing) For quick interactive debugging in the GUI: 1. Navigate to **Options → SSL Manager**. 2. Select your `.p12` or `.jks` file. 3. Enter the keystore password when prompted. --- ## 5. Troubleshooting & Debugging mTLS If requests fail with `javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate` or `handshake_failure`: 1. **Enable TLS Handshake Debugging**: Run JMeter with `-Djavax.net.debug=ssl:handshake` to output verbose TLS negotiation steps: ```bash jmeter -n -t plan.jmx -Djavax.net.debug=ssl:handshake -l results.jtl ``` 2. **Verify Certificate Expiration & Key Usage**: ```bash keytool -list -v -keystore client-keystore.p12 -storetype PKCS12 ``` 3. **Verify Server CA Trust**: Ensure the server's certificate chain is signed by a CA in your `trustStore` (or standard Java `cacerts`). Convert your client certificates into PKCS12 format and verify with a 1-thread GUI test using Options -> SSL Manager. - [JWT, OAuth & SSO Guide](/topics/jwt-oauth-sso/) - [SSL Handshake Error Playbook](/topics/errors/ssl-handshake-exception/) - [SSL Peer Unverified Playbook](/topics/errors/ssl-peer-unverified/) - [Properties Reference](/user-manual/properties-reference/) Leaving `https.use.cached.ssl.context=true` when running multi-certificate tests (causing all threads to reuse the first thread's certificate); using expired certificates; failing to supply client private keys. If the server rejects the certificate with "Certificate unknown" or "Bad Certificate", verify with OpenSSL CLI: `openssl s_client -connect host:443 -cert client.crt -key client.key`. --- Title: JMeter Correlation and Dynamic Values URL: https://docs.jmeter.ai/topics/correlation-dynamic-values/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Correlation and Dynamic Values **Correlation** means capturing a value from one response and reusing it in later requests so a multi-step flow works under many threads. Without it, recorded scripts fail on replay: session IDs, CSRF tokens, order IDs, and JWTs change every run. This guide walks through extractors, variable scope, chaining patterns, debugging, and load-safe practice, grounded in JMeter [regular expressions](/user-manual/regular-expressions/), [functions and variables](/user-manual/functions/), [best practices](/user-manual/best-practices/), and the [component reference](/user-manual/component-reference/). :::tip[One thread first] Fix correlation with **one thread** and View Results Tree. Only then increase load. Extractor bugs multiply into thousands of errors under concurrency. ::: ## Why recordings break on replay The [HTTP(S) Test Script Recorder](/topics/http-recorder/) captures **literal** values from your session. On the next run the server issues new secrets. Typical dynamic fields: - Session cookies (often handled by [HTTP Cookie Manager](/user-manual/component-reference/)) - CSRF / anti-forgery tokens in HTML or JSON - OAuth `state`, `nonce`, `code` - JWT `access_token` - Resource IDs (`orderId`, `cartId`) - Pagination cursors Cookies are correlated automatically if the Cookie Manager is present. Everything else needs **post-processors** (extractors) or explicit functions. ## End-to-end workflow 1. Run the journey once with Tree view; note the first red sampler. 2. Inspect the **previous** response body/headers for the missing value. 3. Add an extractor under that previous sampler. 4. Replace hard-coded text in later samplers with `\${varName}`. 5. Set a **Default Value** (`NOT_FOUND`) on the extractor. 6. Re-run one thread until green. 7. Parameterize users with CSV; re-validate. 8. Disable heavy listeners; run CLI load. ## Extractor types (when to use which) | Tool | Best for | |------|----------| | **JSON Extractor** | REST JSON bodies (`access_token`, nested ids) | | **Regular Expression Extractor** | HTML snippets, headers, mixed text | | **CSS Selector Extractor** | HTML elements when CSS queries fit | | **XPath Extractor** | XML / some HTML (costlier; use carefully under load) | | **Boundary Extractor** | Fixed left/right text boundaries | | **Cookie Manager** | `Set-Cookie` / Cookie headers | For JSON APIs, prefer structured JSON extraction over fragile full-body regex when possible. For free text, regex remains standard; see the [regular expressions](/user-manual/regular-expressions/) chapter. ## Regular Expression Extractor fields Documented concepts you will set on every regex extractor: | Field | Role | |-------|------| | **Name of created variable** | e.g. `csrfToken` → `\${csrfToken}` | | **Regular Expression** | Pattern with **capture groups** `(...)` | | **Template** | `$1$` for first group, `$0$` full match | | **Match No.** | `1` first match; `0` random; negative for all + `_matchNr` | | **Default Value** | Used when no match (debug signal) | Example HTML: ```html ``` Pattern (illustrative): ```text name="_csrf"\s+value="([^"]+)" ``` Template: `$1$` → variable holds `a1b2c3d4`. Build candidates faster with the [Regex Extractor Builder](/tools/regex-tester/) (paste response locally in the browser; nothing is uploaded). ## JSON correlation example Login response: ```json {"access_token":"eyJ...","order":{"id":"ORD-9"}} ``` 1. JSON Extractor on login sampler: variable `accessToken`, path to token. 2. Second extractor or multi-path config for `orderId` if supported by your element setup. 3. Header Manager: `Authorization: Bearer \${accessToken}`. 4. Next path: `/orders/\${orderId}`. Always assert login success so empty tokens do not flood the next step. ## Variable scope and timing From the [functions manual](/user-manual/functions/): - Variables are **thread-local**. Thread 5 cannot read thread 4's `\${orderId}` by default. - Properties are **global** to the JVM (`\${__P}` / `__setProperty`). Use for environment config, not per-user secrets under load. - Undefined `\${name}` is returned **unchanged** (no hard error). That is why defaults and assertions matter. Extractors run as **post-processors** after their parent sampler (and according to scope rules in the tree). Put the extractor **under** the sampler that returns the value, not under a later sibling that never sees the response. ## Chaining multi-step business flows ```text Login → extract token Create cart → extract cartId Add item → use cartId Checkout → extract orderId Get order → use orderId ``` Use **Transaction Controllers** to group steps for dashboard reporting ([dashboard](/user-manual/generating-dashboard/)). Keep sampler **labels stable** (`Login`, `CreateCart`) so series and filters stay readable. ### Controllers that interact with correlation - **Once Only Controller**: login/extract once per thread. - **If Controller**: branch when `\${accessToken}` equals default failure value. - **While Controller**: poll until status is ready (guard with max iterations to avoid infinite loops). ## Cookies vs body tokens | Mechanism | Element | |-----------|---------| | Session cookie | HTTP Cookie Manager | | CSRF in HTML form | Regex / CSS / Boundary extractor → form parameter | | Bearer token | Header Manager + variable | | Query parameter id | Path or parameters field `\${id}` | Missing Cookie Manager is a top cause of "works in browser during record, fails in JMeter." ## Debugging checklist 1. View Results Tree → Response data of the **source** sampler. 2. Confirm the pattern matches in a single-thread run. 3. Check variable with Debug Sampler or by seeing request values on the next sampler. 4. Verify extractor **scope** (main sample vs sub-samples; redirects). 5. Check character encoding and multiline flags for regex. 6. Escape commas inside function parameters if you also use functions ([functions guide](/topics/functions-and-variables/)). ## Load-test hygiene for extractors [Best practices](/user-manual/best-practices/): use as few assertions as needed under load; avoid heavy listeners. Same idea for extractors: - Prefer cheap JSON path over huge regex on multi-megabyte HTML. - Do not extract unused fields. - Do not log every variable on every sample. - Precompute CSV data when values are not server-dynamic. ## Correlation and distributed testing In [distributed mode](/topics/distributed-testing/), each worker is a separate JVM. Per-thread variables stay on that worker. CSV files used for users must exist **on each worker** (not auto-copied). Do not assume a property set on one engine is visible on another. ## Common mistakes | Mistake | Result | |---------|--------| | Hard-coded recorded token | Immediate or mid-test auth failures | | Extractor on wrong sampler | Empty variable | | No default value | Silent empty strings | | Regex without group but template `$1$` | Wrong or empty | | Match No. wrong | Picks stale or random match | | Sharing tokens via properties | Cross-talk between users | | Skipping Cookie Manager | Session lost | ## Practice path 1. [Record or build](/topics/http-recorder/) a two-step flow. 2. Correlate one token with regex or JSON. 3. Add CSV users ([best practices](/user-manual/best-practices/)). 4. Add [JWT/OAuth](/topics/jwt-oauth-sso/) header pattern if API-based. 5. Run CLI + dashboard; confirm zero `\${...}` literals in failures. ## Frequently asked questions ### What is correlation in JMeter? Capturing dynamic values from responses (tokens, IDs) into variables and sending them on later requests so multi-step scenarios work for every thread. ### JSON Extractor or Regular Expression Extractor? For JSON responses, prefer JSON-oriented extractors. Use regular expressions for HTML fragments, headers, or unstructured text. ### Why is my variable still showing as `\${csrf}`? The variable was never set. JMeter leaves undefined references unchanged. Fix the extractor and use a default value to detect misses. ### Do I need extractors if I use a Cookie Manager? Cookies often work automatically with Cookie Manager. Body and header tokens still need extractors. ### Can one thread read another thread's extracted orderId? Not with ordinary variables. Variables are thread-local by design. Use properties only for intentional global data, not per-user IDs. ### How do I correlate after recording? Replay with one thread, find the first failure, extract from the previous response, replace hard-coded values, and repeat until green. Take any red sampler from a recorded plan and replace one hard-coded ID with a Regex or JSON extractor end-to-end. - [Regular Expressions](/user-manual/regular-expressions/) - extractor theory - [Regex Extractor Builder](/tools/regex-tester/) - draft patterns - [HTTP Recorder](/topics/http-recorder/) - where dynamic values come from - [JWT OAuth SSO](/topics/jwt-oauth-sso/) - token chaining Extractor under the wrong sampler; no default value; correlating cookies manually while Cookie Manager is missing; using properties for per-user tokens. If Match No. and Template look right but the value is wrong, check redirect sub-samples and whether the data is in a header instead of the body. --- Title: JMeter HTTP(S) Test Script Recorder Guide URL: https://docs.jmeter.ai/topics/http-recorder/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter HTTP(S) Test Script Recorder Guide The **HTTP(S) Test Script Recorder** is the fastest way for many teams to draft a JMeter web or browser-mediated API plan: run JMeter’s proxy, point the browser at it, click through a journey, and obtain HTTP Request samplers automatically. This guide covers how recording works, the recommended template workflow, HTTPS certificates, include/exclude filters, post-recording cleanup, correlation, and troubleshooting - based on the official [proxy step-by-step](/user-manual/jmeter-proxy-step-by-step/), [component reference](/user-manual/component-reference/), and [best practices](/user-manual/best-practices/). :::tip[Filter before you record] The most important recording skill is **excluding noise** (images, CSS, analytics). Unfiltered sessions create unmaintainable plans. Official best practices stress include/exclude patterns up front. ::: :::note[Recording improved since JMeter 2.10] Since JMeter 2.10, recording better handles embedded resources and on-the-fly certificates. You need a working `keytool` (from the JRE/JDK). See the Apache wiki link in the step-by-step tutorial if certificate generation fails. ::: ## How the recorder works 1. JMeter starts an embedded **HTTP proxy** (default port **8888** in the browser tutorial). 2. The browser sends traffic through that proxy. 3. JMeter creates **HTTP Request** samplers (and related elements depending on settings) under a **Target Controller**. 4. Responses still return to the browser so you can navigate normally. The recorder is **not** a full browser driver: it captures HTTP(S) conversations. Client-side JavaScript timing and in-page rendering are outside JMeter’s model (same as other HTTP sampler testing). ### Where samples are stored From the component reference and best practices: - The recorder expects a **Thread Group** with a **Recording Controller** (or you set **Target Controller** explicitly). - Default behaviour often stores samples under the first **Recording Controller** when “Use Recording Controller” is selected. - Always add a Recording Controller **before** you start recording if you rely on that default. ## Recommended quick start (Recording template) Official [basic instructions](/user-manual/jmeter-proxy-step-by-step/): 1. Start JMeter from `JMETER_HOME/bin` (`jmeter` / `jmeter.bat` / `jmeterw.bat` as appropriate). 2. Open **Templates…** on the menu bar. 3. Select the **Recording** template and create the plan. 4. In **HTTP Request Defaults**, set **Server name or IP** (and clear or set path as appropriate). 5. Open **HTTP(S) Test Script Recorder** and click **Start**. 6. Install the generated CA certificate for HTTPS (next section). 7. Configure the browser proxy to the recorder host/port. 8. Navigate the application. 9. Stop the recorder; save the plan; validate with a low thread count. The template approach is preferable to hand-assembling proxy + controllers when you are learning. ## Configure the browser proxy From the Firefox-oriented tutorial (same ideas apply to other browsers): 1. Keep JMeter running with the recorder **Started**. 2. Browser network settings → **Manual proxy configuration**. 3. HTTP proxy host: `localhost` (or the machine running JMeter). 4. Port: **8888** (or whatever you set on the recorder). 5. Use this proxy for all protocols when recording HTTPS through the same proxy. 6. Browse the site; samplers appear under the target controller. ### Localhost proxy pitfalls Best practices note: - If the browser works even when JMeter is **not** running, it is **not** using the proxy. - Some browsers **ignore proxy settings for `localhost` / `127.0.0.1`**. Try the LAN hostname or machine IP in the browser URL bar **and** ensure the proxy still points at JMeter. - Corporate PAC files and system VPNs often bypass or block local proxies - use a clean browser profile when possible. ## HTTPS and the JMeter CA certificate When you **Start** the recorder, JMeter generates/export certificates for MITM HTTPS recording. ### Certificate files Documented names: - `ApacheJMeterTemporaryRootCA.crt` (and related `.usr` variants on some platforms) in the **JMeter launch directory** (typically `JMETER_HOME/bin` when started from there). - Underlying keystore file `proxyserver.jks` - delete it to force regeneration if certificates are stale (component reference). ### Install the CA in the browser / OS The component reference includes install steps for major browsers: trust **ApacheJMeterTemporaryRootCA** as a certificate authority for websites. Until it is trusted, HTTPS sites show errors or the recorder sees `unknown_ca`-class failures. Best practices: > The error `unknown_ca` probably means you are trying to record HTTPS and the browser has not accepted the JMeter Proxy server certificate. After installing: 1. Restart the browser if required by your OS. 2. Start the recorder again if needed. 3. Visit an HTTPS page and confirm samplers appear without TLS errors in the browser. ### Corporate SSL inspection If the enterprise already intercepts TLS, you may stack trust issues (enterprise CA + JMeter CA). You may need both CAs trusted, or record in an environment without double inspection. This is environmental - not a JMeter checkbox. ## Include and exclude patterns (keep plans maintainable) Best practices § Using the HTTP(S) Test Script Recorder: - **Filter out** requests you do not care about (for example images). JMeter can download embedded resources later via HTTP Request options if you need them. - Prefer an **include** pattern when your app shares an extension (`.*\.jsp`, `.*\.html`, …). - Or **exclude** patterns like `.*\.gif` and similar static types. - Also exclude stylesheets, JavaScript files, and other includes when they are not part of the performance question. - **Test patterns**, then erase and re-record cleanly. Default-ish exclude suggestions appear in properties such as `proxy.excludes.suggested` (see [properties reference](/user-manual/properties-reference/)) covering common static extensions (`css`, `js`, `png`, `woff`, …). ### Grouping Recorder settings can group samples (for example by first URL path segment or separators) to keep the tree readable. Use grouping so a multi-page journey does not become a flat list of hundreds of samplers without structure. ## Abstracting common values while recording One of the most useful documented features: define **User Defined Variables** (or Test Plan variables) such as `server=xxx.example.com` **before/during** recording so JMeter can **replace** matching values in recorded samples with `\${server}`. Notes: - Replacement matching is **case-sensitive**. - This reduces later cleanup when promoting plans across environments. Combine with `\${__P(host,)}` after recording if CI must override hosts ([functions guide](/topics/functions-and-variables/)). ## After recording: mandatory cleanup checklist A raw recording is a **draft**, not a finished load test. 1. **Save** the test plan under a meaningful name (best practices: save each test case draft, wipe, record the next). 2. Set **HTTP Request Defaults** so samplers are not full of repeated server/port fields (tutorial warning: forgetting defaults means manual cleanup). 3. Add **HTTP Cookie Manager** for session cookies ([web test plan](/user-manual/build-web-test-plan/)). 4. Add **Header Manager** only where needed; remove noisy browser headers you do not intend to simulate. 5. **Correlate** dynamic values: CSRF tokens, viewstate, session IDs, redirect IDs - use [Regular Expression Extractor](/user-manual/regular-expressions/), JSON Extractor, etc. 6. Replace hard-coded logins with **CSV Data Set** users ([best practices](/user-manual/best-practices/)). 7. Add **assertions** (status, key text/JSON) so errors surface. 8. Insert **timers** for think time if modelling users. 9. Disable **View Results Tree** before load; run CLI for real volume. 10. Parameterize threads/host with `\${__P(...)}` for automation. ### Correlation is the hard part Recorded scripts often fail on replay because tokens changed. Workflow: 1. Replay with **one thread**. 2. Find the first red sampler in View Results Tree. 3. Inspect the **previous** response for the dynamic value. 4. Add an extractor; replace hard-coded recorded value with `\${var}`. 5. Repeat until the journey passes. Use the [Regex Extractor Builder](/tools/regex-tester/) to draft regex fields from a pasted response body (browser-local). ## Validate before load From the step-by-step tutorial: validate the script before a real test. Practical approach: 1. Thread Group: **1** thread, **1** loop (or a short ramp). 2. View Results Tree enabled. 3. Run; fix correlation and assertions. 4. Only then increase threads and switch to non-GUI: ```bash jmeter -n -t recorded-journey.jmx -l results.jtl -e -o report/ ``` ## Recorder settings worth knowing Consult the [HTTP(S) Test Script Recorder component reference](/user-manual/component-reference/) for the full field list. Concepts you will configure often: | Setting | Why it matters | |---------|----------------| | Port | Must match browser proxy | | Target Controller | Where samplers land | | Grouping | Tree readability | | Patterns to include/exclude | Noise control | | Follow redirects / session options | Depends on app (verify replay) | | Create new transaction after request (ms) | Splits bursts into transactions | Exact labels vary slightly by JMeter version - use the reference for your release. ## Alternatives to the proxy recorder | Approach | When to use | |----------|-------------| | **HTTP(S) Test Script Recorder** | Browser HTML apps, cookie-heavy flows, quick drafts | | **[cURL import](/user-manual/curl/)** | API calls already available as curl/Postman exports | | **Manual HTTP Request samplers** | Simple APIs, maximum clarity | | **[Access log sampler tutorial](/user-manual/jmeter-accesslog-sampler-step-by-step/)** | Replaying production-like HTTP logs | Choose recording when user journeys are easier to click than to hand-author; choose cURL/manual when the surface is pure JSON APIs. ## Security and privacy - Recorded plans may contain **session cookies, tokens, and personal data**. Treat `.jmx` as sensitive. - The JMeter CA allows JMeter to decrypt HTTPS for recording - use only on machines and networks you control. - Remove secrets before committing plans to git; switch to CSV/`__P` for credentials. - Stop the recorder and revert browser proxy settings after sessions so traffic is not accidentally sent to a closed proxy. ## Troubleshooting | Symptom | Likely cause | Fix | |---------|--------------|-----| | No samples recorded | Browser not using proxy | Verify proxy; try non-localhost URL; disable PAC | | HTTPS errors / `unknown_ca` | CA not trusted | Install `ApacheJMeterTemporaryRootCA.crt` | | Only some pages record | Include pattern too strict | Broaden include or use excludes instead | | Huge messy plan | No excludes | Add static excludes; re-record | | Replay fails at login | Dynamic token | Correlate CSRF/session; Cookie Manager | | Works in browser during record, fails in JMeter | Missing headers, body, or async API calls | Compare View Results Tree request to browser devtools | | Certificate age issues | Old keystore | Delete `proxyserver.jks` and regenerate per docs | | `keytool` errors | JDK tools missing/misconfigured | Fix JAVA_HOME / keytool per JMeter 2.10+ recording wiki | ## Recording API-only vs full browser journeys ### Browser HTML applications Recording shines when: - Flows span many pages and redirects. - Cookies and form fields are tedious to hand-build. - Business users can click a script while performance engineers clean it. Expect heavy correlation for modern single-page apps that call JSON APIs underneath. Often the maintainable end state is: record once to discover API calls, then rebuild a slim API-level plan ([API load testing](/topics/api-load-testing/)). ### API-only services If developers already give you OpenAPI examples or curl commands, [cURL import](/user-manual/curl/) may produce a cleaner tree than a browser recording full of static assets and third-party tags. Use the recorder when the only documentation is “click through the UI.” ## Transaction naming after recording Raw sampler names are often full paths or query strings. Before load: - Rename samplers to stable business labels (`Login`, `Search`, `AddToCart`). - Wrap multi-step sequences in **Transaction Controllers** so the [dashboard](/user-manual/generating-dashboard/) reports user-meaningful transactions. - Apply `jmeter.reportgenerator.exporter.html.series_filter` when you only want certain labels in the HTML report. Stable names make CI gates and trend charts possible; recorded URL labels churn every time the front-end router changes. ## Team workflow: from recording to repository 1. Engineer records in a sandbox with synthetic users. 2. Correlation and CSV parameterization land in a feature branch. 3. Peer review checks: no secrets, listeners off, `\${__P}` for host/threads. 4. CI smoke runs the plan non-GUI against staging ([CI/CD](/topics/ci-cd-load-testing/)). 5. Nightly job increases threads only after smoke is green. Treat the first recording as **throwaway discovery** if the cleaned plan diverges heavily - do not romanticize the raw tree. ## End-to-end checklist 1. Recording template created; defaults server set. 2. Recording Controller present; target set. 3. Include/exclude patterns configured and smoke-tested. 4. Recorder started; CA installed for HTTPS. 5. Browser proxy → JMeter port. 6. Journey executed once cleanly. 7. Recorder stopped; plan saved. 8. Cookie manager, correlation, assertions added. 9. One-thread validation green. 10. CLI load run with listeners off. 11. Sampler labels stabilized; secrets removed. 12. Plan documented with required `-J` properties and CSV layout. ## Related reading - [Proxy step-by-step (official tutorial)](/user-manual/jmeter-proxy-step-by-step/) - [Best Practices - recorder & variables](/user-manual/best-practices/) - [Building a Web Test Plan](/user-manual/build-web-test-plan/) - [Regular Expressions](/user-manual/regular-expressions/) - [cURL import](/user-manual/curl/) - [API load testing](/topics/api-load-testing/) ## Frequently asked questions ### What port does the JMeter recorder use? The step-by-step tutorial configures the browser for port **8888**, which is the usual default. Always match the port shown in the HTTP(S) Test Script Recorder panel. ### Why do I need ApacheJMeterTemporaryRootCA.crt? HTTPS recording requires JMeter to present certificates to the browser. Trusting JMeter’s temporary root CA allows the browser to accept that TLS interception for test traffic. ### Should I record images and CSS? Usually no. Best practices say to filter them out; JMeter can fetch embedded resources from HTML if you enable that on HTTP Request for a deliberate reason. ### Workbench or Test Plan? Modern JMeter workflows use the **Recording template** and elements in the **Test Plan** tree (Thread Group + Recording Controller + recorder). Rely on current templates rather than obsolete Workbench-centric instructions from very old tutorials. ### Why does replay fail immediately after a perfect recording? Dynamic values (tokens, timestamps, nonces) embedded in the recording expired or changed. Correlate them with extractors and ensure a Cookie Manager is present. ### Can I record mobile app traffic? If the mobile client can use an HTTP proxy and trusts the JMeter CA (or you use a device proxy setup), you can capture HTTP(S) API calls. Platform-specific TLS pinning may block interception. ### Is recording enough for a production load test? No. Recording is a draft generator. You still need parameterization, correlation, assertions, timers, CLI execution, and sensible thread sizing ([Thread Calculator](/tools/thread-calculator/)). Use the [Recording template](/user-manual/jmeter-proxy-step-by-step/) once end-to-end, then clean the plan with Cookie Manager and one correlated token. - [cURL Import](/user-manual/curl/) - alternative for API-only traffic - [Access Log Sampler](/user-manual/jmeter-accesslog-sampler-step-by-step/) - production log replay - [Regex Extractor Builder](/tools/regex-tester/) - correlation helper - [Building a Web Test Plan](/user-manual/build-web-test-plan/) - structure after recording Recording without excludes; committing secrets inside recorded headers; load-testing a raw recording with View Results Tree enabled; forgetting the Cookie Manager. If nothing records, the browser is not proxying. If HTTPS fails with unknown_ca, reinstall the JMeter root CA. If replay fails mid-flow, correlate the first dynamic value that differs from the recording. --- Title: JMeter Functions and Variables Guide URL: https://docs.jmeter.ai/topics/functions-and-variables/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Functions and Variables Guide Functions and variables are how Apache JMeter turns a static tree of samplers into data-driven load. This guide explains syntax rules, the difference between **variables** and **properties**, the functions you will use most, CSV and file input, scripting functions, parameterization for CLI/CI, sharing data across threads, and common mistakes - grounded in the official [Functions and Variables](/user-manual/functions/) chapter and [Best Practices](/user-manual/best-practices/). For the exhaustive function table and per-function parameters, always use the [full reference](/user-manual/functions/). ## Function and variable syntax ### Functions A function call looks like: ```text \${__functionName(var1,var2,var3)} ``` Rules from the manual: - Parentheses surround parameters, for example `\${__time(YMD)}`. - Functions that need **no parameters** may omit parentheses: `\${__threadNum}` is equivalent to `\${__threadNum()}`. - If a parameter contains a **comma**, escape it with `\`, otherwise JMeter treats the comma as a parameter delimiter. Example: `\${__time(EEE\, d MMM yyyy)}` - Unescaped commas produce confusing errors (the docs show JavaScript `Math.max(2,5)` splitting into two parameters). - Functions can appear in sampler fields, config elements, and many other test element fields. - **Case sensitivity** applies to functions, variables, and properties. - JMeter **trims spaces** from variable names used when storing function results (for example a trailing space in a third argument name is trimmed). ### Variables Reference a variable as: ```text \${VARIABLE} ``` Important documented behaviour: > If an undefined function or variable is referenced, JMeter does **not** report/log an error - the reference is returned **unchanged**. If `UNDEF` is not defined, `\${UNDEF}` stays `\${UNDEF}`. That makes missing extractors easy to miss unless you assert on values or use extractor default values like `NOT_FOUND`. ### Windows paths and backslashes When a `\` precedes a variable in a Windows path, escape carefully or JMeter may not interpolate the variable. The manual recommends using `/` as the separator (JVMs on Windows accept it), or proper escaping of backslashes. ## Variables vs properties (must-know) From the official note: - **Variables** are **local to a thread**. - **Properties** are **common to all threads**. - Properties are referenced with `__P` or `__property`, not `\${PROP}` alone (unless you also mirror them into variables). | | Variables | Properties | |--|-----------|------------| | Scope | Per thread | Whole JMeter JVM (all threads) | | Typical set by | Extractors, CSV Data Set, `vars.put` in scripts, UDVs | `-J` CLI, `user.properties`, `__setProperty`, GUI props | | Typical read | `\${name}` | `\${__P(name,)}` or `\${__P(name,default)}` | | Use for | Tokens, CSV columns, per-user state | Host, threads, env flags, cross-thread signals | ### Sharing across threads or thread groups Because variables do not cross threads by design, the [best practices](/user-manual/best-practices/) chapter lists options when a value is only known at runtime: - Store it as a **property** (global to the instance) - Write to a **file** and re-read - Use `bsh.shared` (legacy BeanShell patterns) - Write custom Java classes For values known **before** the test starts, prefer parameterization with properties (`-J` / `-q`) rather than cross-thread writes. ## Most-used functions by job Grouped loosely like the official reference (Information, Input, Calculation, Scripting, Formatting, …). ### Information and identity | Function | Role | Example | |----------|------|---------| | `__threadNum` | Current thread number | `\${__threadNum}` | | `__threadGroupName` | Thread group name (newer JMeter) | `\${__threadGroupName}` | | `__samplerName` | Current sampler label | `\${__samplerName}` | | `__machineIP` / `__machineName` | Injector identity (useful in distributed logs) | `\${__machineName}` | | `__time` | Current time with format | `\${__time(yyyy-MM-dd)}` | | `__timeShift` | Time plus offset | see reference for args | | `__log` / `__logn` | Log while evaluating | debug carefully under load | ### Generating data | Function | Role | Example | |----------|------|---------| | `__Random` | Random integer in range | `\${__Random(1,1000,myRand)}` | | `__RandomString` | Random string | `\${__RandomString(10,abcdef)}` | | `__UUID` | Type-4 UUID | `\${__UUID}` | | `__counter` | Incrementing counter | `\${__counter(TRUE,)}` | | `__RandomDate` | Random date in range | see reference | | `__digest` | Hash digests (SHA, MD5, …) | see reference | Many calculation functions accept an optional variable name argument to **store** the result as well as return it - check each function’s parameter list in the reference. ### Reading properties and nested names | Function | Role | Example | |----------|------|---------| | `__P` | Property with optional default | `\${__P(threads,10)}` | | `__property` | Longer form property access | see reference | | `__setProperty` | Set a property during the test | use sparingly; concurrency-aware | | `__V` | Evaluate nested variable names | `\${__V(user_\${n})}` | `__P` is the backbone of CLI/CI parameterization ([best practices § parameterising tests](/user-manual/best-practices/)): ```text LOOPS=\${__P(loops,10)} ``` ```bash jmeter -n -t plan.jmx -Jloops=12 ``` ### String helpers | Function | Role | |----------|------| | `__substring` | Slice a string | | `__urlencode` / decode helpers | Encode query parts | | `__split` | Split into variables (escape commas in args) | | `__dateTimeConvert` | Convert date formats | | `__intSum` / `__longSum` | Arithmetic | ### File and CSV input functions | Function | Role | |----------|------| | `__StringFromFile` | Read a line from a file | | `__FileToString` | Read entire file (payloads, certs - watch size) | | `__CSVRead` | Older CSV read helper | | `__XPath` | XPath against a file | | `__StringToFile` | Write a string to a file (side effects!) | For multi-user login data, official best practices prefer the **CSV Data Set Config** element over ad-hoc scripting (see next section). ### Scripting functions | Function | Notes | |----------|------| | `__groovy` | Run Groovy (preferred modern scripting) | | `__BeanShell` | Legacy; best practices advise moving to JSR223 | | `__javaScript` | Legacy Nashorn-era; not ideal for intensive load | Best practices: for intensive load, use languages whose engine implements `Compilable` - **Groovy** does; BeanShell/JavaScript were called out as poor choices for hot paths as of the JMeter 3.1-era guidance still published in the manual. Prefer **JSR223 elements** with **Cache compiled script** and `vars.get("name")` inside scripts instead of embedding `\${name}` in cached script text (caching would freeze the first interpolated value). ## CSV Data Set Config (primary parameterization tool) From [best practices - User variables](/user-manual/best-practices/): 1. Create a text file of usernames/passwords separated by commas (same directory as the plan is a common pattern). 2. Add **CSV Data Set Config**; set variable names (for example `USER`, `PASS`). 3. Replace login fields with `\${USER}` and `\${PASS}`. 4. The CSV Data Set reads a **new line for each thread** (for that documented multi-user login pattern). Configure recycle/stop-thread behaviour according to whether you want data to loop or threads to stop when the file ends - see the [component reference](/user-manual/component-reference/) for CSV Data Set fields. **Large random datasets:** create files ahead of time and read with CSV Dataset rather than generating expensive random data on the fly for every sample. ## User Defined Variables and Test Plan variables - **User Defined Variables** config elements and Test Plan-level variables define name/value pairs available to the plan. - Matching with the HTTP(S) recorder’s replacement feature is **case-sensitive** when abstracting server names into `\${server}` ([best practices - recorder](/user-manual/best-practices/)). - For CLI overrides, bind those values to `__P` as shown above. - Multiple property files: pass with `-q` when many properties change together. ## Where evaluation happens (practical implications) Functions and variables are evaluated when JMeter needs the field value for a sample or config - not “once at plan load” for every case. Implications: - `\${__UUID}` on a sampler produces a **new** id each time that field is evaluated for a sample. - Putting `\${__Random}` in HTTP Defaults may not do what you expect if the default is resolved differently than a per-sampler field - prefer placing dynamic calls on the sampler that should change. - Extractors run as post-processors **after** a sampler; downstream samplers see new `\${token}` values. When debugging, use **View Results Tree** (scripting phase only) and Debug Sampler / Debug PostProcessor patterns to print variables. Disable them for load. ## Patterns that show up in real plans ### Environment-specific host ```text \${__P(host,localhost)} \${__P(port,443)} \${__P(protocol,https)} ``` Wire HTTP Request Defaults to these values; CI passes `-Jhost=staging.example.com`. ### Authorization header after login 1. Login sampler → JSON/Regex extractor → `accessToken` 2. Header Manager: `Authorization` = `Bearer \${accessToken}` 3. Keep `accessToken` as a **variable** (per thread). Only promote to a property if you intentionally share one token across threads. ### Unique email per thread ```text user_\${__threadNum}_\${__time(HHmmss)}@example.com ``` Or precompute in CSV for repeatability. ### Nested dynamic names If you create `user_1`, `user_2`, …: ```text \${__V(user_\${__threadNum})} ``` ### Counter for order ids `\${__counter(TRUE,)}` (see reference for TRUE/FALSE per-thread vs global counter behaviour). ## Distributed testing interactions In [distributed mode](/topics/distributed-testing/): - Each worker is a separate JVM → **properties and variables do not sync across workers**. - `__machineName` / IP help label which injector produced a sample when analyzing combined logs. - CSV files must exist **on each worker**; they are not shipped with the plan. - `-Gprop=value` sets a property on **remote servers**; `-J` is for the client side - know which side reads `\${__P(...)}` for your plan design. ## Performance and correctness tips 1. Prefer **CSV** over heavy `__groovy` on every sample when data can be precomputed. 2. Prefer **JSR223 Groovy** with compile cache over BeanShell function calls in hot paths. 3. Do not log (`__log`) on every sample at scale. 4. Escape commas in function parameters. 5. Assert critical `\${vars}` so literal `\${token}` strings cannot look like success. 6. Remember undefined → unchanged string. 7. For intensive scripts, use `vars.get` / `props.get` inside JSR223, not `\${}` inside cached scripts. 8. Keep property names stable for CI; document them in the plan README. ## Quick reference: CLI property flags | Flag | Effect | |------|--------| | `-Jname=value` | Set JMeter property on client | | `-Gname=value` | Set property on remote servers (distributed) | | `-q file` | Additional property file | | `-S` / system props | See Getting Started override docs for full CLI list | Thread Group example: ```text Number of Threads = \${__P(threads,1)} Ramp-up = \${__P(rampup,1)} ``` Safe defaults for local runs; CI raises threads. ## Debugging variables safely When a value is wrong, isolate evaluation without creating a load-test anti-pattern: 1. **View Results Tree** (scripting only) - inspect request after variable substitution. 2. **Debug Sampler** + Tree - dump variables for the thread at that point in the tree. 3. Extractor **default values** - `NOT_FOUND` is easier to spot than a silent empty string. 4. **Response Assertion** on login - fail fast before thousands of dependent calls. 5. Temporary `\${__log(message)}` - remove before load; logging every sample is expensive. Never leave Debug Sampler or View Results Tree enabled for the CLI performance run you archive in CI. ## Functions inside controllers and deferred evaluation Some fields are evaluated later than others (for example, certain controller conditions or script elements). If a function appears to run “too often” or “too early”: - Move the dynamic expression onto the sampler field that should change per sample. - Prefer post-processors to set a variable once per response, then reference `\${var}` downstream. - For Once Only login, ensure extractors sit under the login sampler, not under a later random controller path that might skip login. When using **If Controller** or similar, condition strings that embed functions should be tested with one thread and Tree view so you see the evaluated branch. ## Property files for teams For shared environments, maintain property files rather than long `-J` lists: ```bash jmeter -n -t plan.jmx -q env/staging.properties -l out.jtl -e -o report/ ``` Document keys in the repository (`threads`, `rampup`, `host`, `usersFile`). Official best practices encourage `user.properties` overrides instead of editing stock `jmeter.properties` for durable configuration - the same idea scales to environment-specific `-q` files in CI ([CI/CD guide](/topics/ci-cd-load-testing/)). ## Learning path 1. Read syntax + variables vs properties on this page. 2. Practice `\${__Random}` and `\${__UUID}` on a single HTTP sampler; confirm in View Results Tree. 3. Add CSV Data Set for two users. 4. Replace host/threads with `\${__P}`. 5. Extract a token and pass it to the next sampler. 6. Skim the [complete function list](/user-manual/functions/) for niche helpers (`__digest`, `__timeShift`, …). 7. When scripting grows past a one-liner, move to JSR223 Groovy elements per best practices. 8. Wire the same plan into a CLI command with `-J` overrides and confirm defaults still work offline. ## Related tools - [Regex Extractor Builder](/tools/regex-tester/) - build correlation that *sets* variables - [Properties Cheat Sheet](/tools/properties-cheatsheet/) - which properties teams change most - [Thread Calculator](/tools/thread-calculator/) - once data is dynamic, size load correctly ## Frequently asked questions ### What is the difference between a JMeter variable and a property? Variables are thread-local; properties are shared across all threads in the JVM. Read properties with `\${__P(name,default)}`. Read variables with `\${name}`. ### Why does my function argument break at a comma? Commas separate parameters. Escape literal commas as `\,` inside the parameter, as shown in the functions manual for `__time` formats. ### Why do I still see `\${token}` in the request? The variable was never set (extractor failed or wrong name). JMeter leaves undefined references unchanged and does not always error. ### How do I pass values between thread groups? Not with ordinary variables. Use properties, files, or other documented sharing approaches in best practices. Prefer design that avoids cross-group chatty sharing. ### Should I use __CSVRead or CSV Data Set Config? For multi-user data rows, official best practices demonstrate **CSV Data Set Config**. `__CSVRead` remains a function for specific cases; see the reference. ### Is BeanShell still recommended? For intensive load, the manual advises JSR223 with Groovy (Compilable) and moving off BeanShell. Existing BeanShell may still run; new work should prefer Groovy. ### How do I set threads from Jenkins or GitHub Actions? Use `\${__P(threads,10)}` in the Thread Group and pass `-Jthreads=50` on the `jmeter -n` command in CI ([CI/CD guide](/topics/ci-cd-load-testing/)). Add `\${__P(host,localhost)}` to HTTP Request Defaults and run once with `-Jhost=…` to prove CLI parameterization end-to-end. - [Functions reference](/user-manual/functions/) - every function and parameter - [Regular Expressions](/user-manual/regular-expressions/) - extract values into variables - [Best Practices](/user-manual/best-practices/) - CSV users, __P, JSR223 - [Properties Reference](/user-manual/properties-reference/) - property names for configuration Forgetting to escape commas; using variables when you need cross-thread properties; `\${var}` inside cached JSR223 scripts; assuming undefined variables error loudly. If values look like literal `\${…}`, check extractor scope, variable name spelling (case-sensitive), and that the sampler order places extractors before dependent requests. --- Title: JMeter CSV Data Set Config & Parameterization URL: https://docs.jmeter.ai/topics/csv-data-set-config-guide/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter CSV Data Set Config & Parameterization Data-driven testing ensures that virtual users execute requests using realistic, varied inputs (usernames, passwords, product IDs, search queries, payment tokens) rather than repeating identical static payloads. The **CSV Data Set Config** element is Apache JMeter’s primary component for feeding external CSV data into test plans. This guide explains configuration parameters, **Sharing Modes**, End-of-File (EOF) behaviors, and best practices for distributed load testing. --- ## 1. Core Configuration Fields Reference | Parameter | Recommended Setting | Description | |---|---|---| | **Filename** | `users.csv` or `./data/users.csv` | Path to CSV file. Relative paths resolve from JMeter launch directory. | | **File encoding** | `UTF-8` | Encoding format. Avoid leaving blank if files contain international characters. | | **Variable Names** | `username,password,userRole` | Comma-separated variable names. If left blank, first row of CSV is read as headers. | | **Ignore first line** | `True` (if CSV has header row) | Prevents the header text row from being processed as actual test data. | | **Delimiter** | `,` (or `\t` for tab-separated) | Character separating values in each row. | | **Allow quoted data?** | `True` | Allows values containing commas wrapped in quotes (`"New York, NY"`). | | **Recycle on EOF?** | `True` or `False` | When the end of the file is reached, determines whether to loop back to top. | | **Stop thread on EOF?** | `True` or `False` | Stops the virtual user thread when the file runs out of records. | | **Sharing mode** | `All threads` / `Current thread group` | Controls how file cursors are shared across threads. | --- ## 2. Understanding Sharing Modes Sharing Mode defines which virtual users share the CSV file read cursor: ### A. All Threads (Default & Most Common) - **Behavior**: All virtual users across all Thread Groups read from a single shared file cursor. - **Result**: Every row in the CSV file is read sequentially across the entire test. No two threads receive the same row on a given step. - **Best for**: Unique test credentials, single-use coupon codes, unique transaction IDs. ### B. Current Thread Group - **Behavior**: Each Thread Group maintains its own independent file read cursor. - **Result**: Thread Group A and Thread Group B both start reading from row 1 of the file independently. - **Best for**: Multi-stage workflows where each group needs access to the same baseline pool of customer IDs. ### C. Current Thread - **Behavior**: Every virtual user thread opens its own separate file cursor and reads from row 1. - **Result**: If you have 50 threads, each thread reads line 1 on iteration 1, line 2 on iteration 2. - **Best for**: Per-thread dedicated datasets or isolated user state files. ### D. Identifier (Named Sharing Group) - Assign an arbitrary string (e.g., `group_checkout`). All CSV Data Set configs sharing that identifier string share the same cursor. --- ## 3. End-of-File (EOF) Behaviors | Recycle on EOF? | Stop thread on EOF? | Behavior when rows run out | |---|---|---| | **True** | **False** | **Infinite Loop**: Automatically wraps back to line 1 and continues indefinitely. | | **False** | **True** | **Graceful Shutdown**: The thread stops immediately upon exhausting data. | | **False** | **False** | **Default Value (``)**: Variables are assigned literal string `` on subsequent reads. | --- ## 4. Multi-Slave & Distributed Testing Considerations When running JMeter in distributed master-slave mode (`jmeter -r`): :::caution[CSV Files Must Exist on Remote Injectors] JMeter does **not** automatically upload CSV data files to remote slave servers. You must copy the CSV file to the exact same relative directory path on every remote server before starting the test. ::: ### Strategy 1: Partitioning Data Files To ensure remote slaves do not use duplicate credentials: - Split `users.csv` into `users_slave1.csv` and `users_slave2.csv`. - In CSV Data Set Config, reference dynamic filename: ```text users_\${__P(nodeId, 1)}.csv ``` ### Strategy 2: Modular Offset Scripting Use the `__CSVRead` function with thread and host offsets for mathematical partitioning without physical file splits. --- ## 5. Parameterization Best Practices 1. **Keep Paths Relative**: Always use `./data/users.csv` instead of absolute Windows paths (`C:\Users\...`) to ensure portability across developer machines, Docker containers, and CI/CD agents. 2. **Always Set Variable Names Explicitly**: Defining `username,password` in the element rather than relying on header rows avoids subtle bugs if CSV header formatting changes. 3. **Use Memory Buffers for Huge CSVs**: For datasets with millions of rows, ensure file storage has fast SSD read latency. Audit your CSV Data Set Config elements: convert absolute paths to relative paths and verify that EOF settings match your test duration goals. - [Functions & Variables Guide](/topics/functions-and-variables/) - [CSV Data Set Errors Playbook](/topics/errors/csv-data-set-file-not-found-sharing/) - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - [Best Practices Manual](/user-manual/best-practices/) Using absolute file paths that break in CI/CD containers; leaving "Recycle on EOF" false with "Stop thread" false causing variables to be set to literal ``. If threads immediately terminate upon launch, check whether your CSV file is empty or missing from the working directory. --- Title: JMeter JSR223 Groovy Scripting Guide & Cookbook URL: https://docs.jmeter.ai/topics/jsr223-groovy-scripting-guide/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter JSR223 Groovy Scripting Guide & Cookbook Apache JMeter provides JSR223 test elements (Samplers, PreProcessors, PostProcessors, Assertions, and Listeners) to execute custom logic during a test run. **Apache Groovy** is the standard scripting engine in JMeter: it compiles directly to Java bytecode, supports automatic script caching, and executes with near-native Java performance. This guide provides a comprehensive reference to implicit script objects, compilation caching rules, and production-tested Groovy recipes for real-world load testing. :::tip[Always Use Groovy with Compilation Caching] Always select **groovy** as the language in JSR223 elements and keep **"Cache compiled script if available"** enabled. Never use BeanShell or JavaScript for load paths—Groovy with caching is up to 50x faster and prevents JVM Metaspace exhaustion. ::: ## Implicit Objects Reference Every JSR223 test element automatically exposes several pre-configured objects in the script scope: | Object | Class / Type | Description & Primary Use Case | |---|---|---| | `vars` | `org.apache.jmeter.threads.JMeterVariables` | Thread-local variable store. Read and write variables for the current virtual user. | | `props` | `java.util.Properties` | Global properties shared across **all threads and thread groups** in the JMeter JVM instance. | | `prev` | `org.apache.jmeter.samplers.SampleResult` | Result of the **previous** sampler (PostProcessors, Assertions, Listeners). | | `sampler` | `org.apache.jmeter.samplers.Sampler` | The current sampler object being executed or prepared (PreProcessors, Samplers). | | `ctx` | `org.apache.jmeter.threads.JMeterContext` | Internal engine context: thread number, engine state, active thread count, and current sampler. | | `log` | `org.slf4j.Logger` | SLF4J logger instance writing to `jmeter.log` (e.g., `log.info("msg")`, `log.error("err")`). | | `OUT` | `java.io.PrintStream` | Standard system output (`System.out`). | | `args` | `String[]` | Array of script parameter tokens passed in the **Parameters** field. | --- ## 1. Thread Variables (`vars`) `vars` holds variables specific to the executing thread. Variables created here cannot be seen by other virtual users. ```groovy // Read variable String token = vars.get("authToken") String defaultId = vars.get("userId") ?: "guest-1000" // Write variable vars.put("orderId", "ORD-98765") vars.put("isEligible", "true") // Store non-string objects (accessible only within the same thread) List items = ["item_A", "item_B", "item_C"] vars.putObject("userCart", items) // Retrieve stored object List cart = (List) vars.getObject("userCart") ``` :::caution[Avoid String Interpolation Inside Cached Scripts] Never write `vars.get("\${varName}")` or `String id = "\${userId}"` inside a cached JSR223 script. When JMeter interpolates `\${...}` before compilation, the script text changes every iteration, destroying compilation cache and causing memory leaks. Always use `vars.get("userId")`. ::: --- ## 2. Global Properties (`props`) `props` is a thread-safe `java.util.Properties` instance visible across all threads, Thread Groups, and setUp/tearDown Thread Groups. ```groovy // Read property with a fallback default String apiHost = props.getProperty("app.host", "api.example.com") // Write a property across thread groups props.put("sharedAuthKey", "key-live-99212") // Synchronized counter / token rotation synchronized (props) { int currentCounter = Integer.parseInt(props.getProperty("globalCounter", "0")) props.put("globalCounter", String.valueOf(currentCounter + 1)) } ``` --- ## 3. Previous Sample Result (`prev`) Available in **JSR223 PostProcessor**, **JSR223 Assertion**, and **JSR223 Listener** to inspect or modify response metadata: ```groovy // Read response status and body int responseCode = prev.getResponseCode().toInteger() String responseBody = prev.getResponseDataAsString() long latencyMs = prev.getLatency() long responseTime = prev.getTime() // Modify sample result dynamically if (responseBody.contains("SESSION_EXPIRED")) { prev.setSuccessful(false) prev.setResponseCode("401") prev.setResponseMessage("Session expired detected in payload") } // Ignore sampler from final dashboard / metrics if needed if (prev.getSampleLabel().startsWith("HealthCheck")) { prev.setIgnore() } ``` --- ## 4. Groovy Cookbook & Practical Recipes ### Recipe A: Parsing & Extracting JSON with JsonSlurper ```groovy import groovy.json.JsonSlurper String response = prev.getResponseDataAsString() def json = new JsonSlurper().parseText(response) // Extract top-level or nested values String jwtToken = json.auth.access_token int totalOrders = json.data.orders.size() // Find items matching condition def activeOrder = json.data.orders.find { it.status == "ACTIVE" } if (activeOrder) { vars.put("activeOrderId", activeOrder.id.toString()) } vars.put("jwtToken", jwtToken) vars.put("totalOrders", totalOrders.toString()) ``` ### Recipe B: Generating JSON Request Payloads with JsonOutput ```groovy import groovy.json.JsonOutput def payload = [ timestamp: System.currentTimeMillis(), customerId: vars.get("customerId") ?: "cust-1", actions: [ [action: "PAGE_VIEW", target: "/checkout"], [action: "CLICK_BUTTON", target: "btn_place_order"] ], metadata: [ clientVersion: "v2.4.0", platform: "web" ] ] String jsonString = JsonOutput.toJson(payload) vars.put("dynamicPayload", jsonString) ``` ### Recipe C: Computing HMAC-SHA256 Signatures Used for signing requests to AWS, Stripe, or custom cryptographic APIs: ```groovy import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec String secret = "mySuperSecretKey123" String dataToSign = vars.get("timestamp") + "." + vars.get("userId") Mac mac = Mac.getInstance("HmacSHA256") SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256") mac.init(secretKey) byte[] rawHmac = mac.doFinal(dataToSign.getBytes("UTF-8")) String signature = rawHmac.encodeHex().toString() vars.put("apiSignature", signature) ``` ### Recipe D: Date & Timestamp Calculations ```groovy import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit // ISO-8601 UTC timestamp String isoNow = Instant.now().toString() // Future expiration timestamp (7 days from now) String expiresAt = Instant.now().plus(7, ChronoUnit.DAYS).toString() // Custom formatted date DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") .withZone(ZoneId.of("UTC")) String formattedDate = formatter.format(Instant.now()) vars.put("isoNow", isoNow) vars.put("expiresAt", expiresAt) vars.put("formattedDate", formattedDate) ``` ### Recipe E: Writing Error Payloads to a Debug File ```groovy if (!prev.isSuccessful()) { String logLine = "${new Date().format('yyyy-MM-dd HH:mm:ss')} | " + "Thread: ${ctx.getThreadNum()} | " + "URL: ${prev.getUrlAsString()} | " + "Code: ${prev.getResponseCode()} | " + "Body: ${prev.getResponseDataAsString()}\n" new File("jmeter-failures.log") << logLine } ``` --- ## 5. Performance Best Practices 1. **Enable Script Caching**: Check **"Cache compiled script if available"** on every JSR223 element. 2. **Never interpolate variables into script text**: Write `vars.get("token")`, not `"\${token}"`. 3. **Use SLF4J parameterized logging**: Write `log.debug("Processing user {}", userId)` instead of string concatenation `log.debug("Processing user " + userId)` to save memory when debug logging is disabled. 4. **Avoid heavy file I/O**: Do not write file logs for every sampler during a high-throughput run. Guard disk operations with `if (!prev.isSuccessful())`. 5. **Pre-instantiate expensive objects**: If reusable across runs, store pre-compiled formatters or cryptographic helpers in static fields or `props`. Replace legacy BeanShell samplers with JSR223 Groovy and verify that "Cache compiled script" is checked across all test elements. - [Functions and Variables Guide](/topics/functions-and-variables/) - [JMeter Assertions Guide](/topics/jmeter-assertions-guide/) - [JSR223 Script Error Troubleshooting](/topics/errors/jsr223-groovy-script-errors/) - [Component Reference](/user-manual/component-reference/) Using `\${var}` string interpolation inside JSR223 script bodies which destroys compilation caching; selecting BeanShell or JavaScript instead of Groovy; performing unbuffered disk writes inside high-frequency loops. Check `jmeter.log` for compilation and runtime stack traces. Verify variable existence with `vars.get("varName") ?: "default"` to prevent `NullPointerException`. --- Title: JMeter Assertions and SLA Validation Guide URL: https://docs.jmeter.ai/topics/jmeter-assertions-guide/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Assertions and SLA Validation Guide Assertions in Apache JMeter validate that responses received from the target server conform to expected status codes, response times, headers, and payload structures. When an assertion fails, JMeter marks the sample as failed (red), records the failure message, and triggers configured error handling rules. This guide covers assertion execution hierarchy, deep dives into the most critical assertion types, custom JSR223 assertions, and performance best practices under high concurrency. :::tip[Assertion Hierarchy & Scope] Assertions apply to all samplers at their hierarchical level and below. Placing an assertion directly under the **Thread Group** evaluates it against *every single request* in that group. To validate a single API call, always attach the assertion as a child of that specific sampler. ::: --- ## 1. Core Assertion Types Overview | Assertion Type | Target | CPU / Memory Overhead | Best For | |---|---|---|---| | **Response Assertion** | Status code, headers, URL, body | **Lowest** (native string / regex) | HTTP 200, status messages, text matching | | **JSON Assertion** | REST JSON response payloads | **Low** (JSONPath evaluation) | Validating specific fields, arrays, or object properties | | **Duration Assertion** | Response time in milliseconds | **Negligible** (integer comparison) | Strict SLA latency enforcement | | **Size Assertion** | Byte size of response | **Negligible** (byte comparison) | Empty body or minimum payload length checks | | **XPath2 Assertion** | XML / SOAP responses | **Medium** (DOM / SAX parsing) | Complex XML tree validation | | **JSR223 Assertion** | Dynamic / multi-condition rules | **Low** (if Groovy cached) | Cross-field validation, database verification | --- ## 2. Response Assertion (The Workhorse) The Response Assertion tests fields of the response using substring, pattern matching, or equality. ### Key Configuration Settings - **Field to Test**: - `Text Response` (Response body) - `Response Code` (HTTP status code, e.g., `200`, `201`) - `Response Message` (e.g., `OK`, `Created`) - `Response Headers` (e.g., `Content-Type: application/json`) - `Request Headers` / `URL Sampled` - **Pattern Matching Rules**: - **Contains**: Case-sensitive substring search anywhere in the target. - **Matches**: Full regular expression match across the entire string (must match from start to end). - **Equals**: Exact literal match of the full string. - **Substring**: Fast literal substring matching (no regex compilation overhead). - **Not**: Inverts the assertion logic (passes if pattern is *absent*). - **Or**: Succeeds if *any* listed pattern matches. ```text Field to Test: Response Code Pattern Matching Rule: Equals Patterns to Test: 200 ``` --- ## 3. JSON Assertion & JSON Path Validation Used for REST APIs returning `application/json`. It evaluates expressions using JSONPath syntax. ### Configuration Fields - **Assert JSON Path exists**: e.g., `$.data.user.id` or `$.items[?(@.price > 100)]` - **Additionally validate value**: Check if the extracted value matches an expected condition. - **Match as regular expression**: If checked, validates the value using regex. - **Expected Value**: The literal or regex string expected at the JSONPath location. - **Expect null**: Asserts that the targeted field explicitly equals `null`. - **Invert assertion**: Fails if the JSONPath exists or matches. ### Common JSONPath Patterns | Pattern | Meaning | Example Match | |---|---|---| | `$.status` | Top-level property | `"SUCCESS"` | | `$.data.items.length()` | Array element count | `5` | | `$.items[0].id` | First item ID in array | `101` | | `$.users[*].email` | Array of all emails | `["a@b.com", "c@d.com"]` | | `$.orders[?(@.total > 500)]` | Filters orders with total > 500 | Non-empty array | --- ## 4. Duration & Size Assertions (SLA Validation) ### Duration Assertion Enforces a hard maximum response time limit. If `prev.getTime() > Duration (ms)`, the sampler fails with: `The test took too long: 1240 ms, max allowed 1000 ms`. ```text Duration in milliseconds: 1000 ``` :::caution[Use Reporting Percentiles Over Heavy Duration Assertions] Avoid adding Duration Assertions to every sampler during high-volume soak tests if your goal is calculating p95/p99 percentiles. JMeter's HTML Dashboard and Backend Listener calculate percentiles automatically without failing samples artificially. ::: ### Size Assertion Validates response size in bytes: - **Size to compare**: Full response, body only, or headers only. - **Comparison Type**: `=`, `!=`, `>`, `<`, `>=`, `<=`. --- ## 5. Advanced Custom Assertions with JSR223 Groovy When built-in assertions cannot express complex business logic (e.g., verifying mathematical calculations, token expiration times, or cross-variable consistency), use a **JSR223 Assertion**. In a JSR223 Assertion, use `AssertionResult` to signal success or failure: ```groovy import groovy.json.JsonSlurper // Parse response String response = prev.getResponseDataAsString() if (!response) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage("Response body was completely empty.") return } try { def json = new JsonSlurper().parseText(response) // Validate schema field if (json.status != "ACTIVE") { AssertionResult.setFailure(true) AssertionResult.setFailureMessage("Expected status ACTIVE but got: ${json.status}") return } // Cross-validate with JMeter variable String expectedUserId = vars.get("expectedUserId") if (json.user?.id?.toString() != expectedUserId) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage("User ID mismatch: expected ${expectedUserId}, got ${json.user?.id}") return } // SLA check combined with business validation if (prev.getTime() > 2000) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage("SLA breach: request took ${prev.getTime()}ms (limit 2000ms)") } } catch (Exception e) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage("Invalid JSON format: " + e.getMessage()) } ``` --- ## 6. Performance Optimization for Assertions 1. **Prefer Substring over Matches**: In Response Assertion, select **Substring** instead of **Contains/Matches** when regex is unnecessary. Substring uses simple string index scanning and consumes minimal CPU. 2. **Limit XML/XPath Assertions**: XPath assertions construct a full DOM tree in memory for every response. For XML under heavy load, use regular expression extractors or fast boundary extractors instead. 3. **Keep Assertion Scope Narrow**: Place assertions directly as children of specific samplers, not at the Thread Group level unless globally required. 4. **Always Check "Cache compiled script"**: If using JSR223 Assertions, enable caching and avoid `\${var}` interpolation. Audit your test plan: replace global Thread-Group-level assertions with targeted child assertions, and change Response Assertion rules from "Matches" to "Substring". - [JSR223 Groovy Scripting Guide](/topics/jsr223-groovy-scripting-guide/) - [Correlation & Dynamic Values](/topics/correlation-dynamic-values/) - [APDEX, SLOs & Percentiles](/topics/apdex-slo-percentiles/) - [Component Reference](/user-manual/component-reference/) Using heavy XPath/DOM assertions under thousands of virtual users; applying Duration Assertions when percentiles should be calculated post-run; forgetting that thread-level assertions run on every child request. If assertions fail with `Assertion error: false`, review View Results Tree -> Assertion Results tab to inspect the exact failure message and expected vs received values. --- Title: JMeter Logic Controllers and Flow Control Guide URL: https://docs.jmeter.ai/topics/logic-controllers-flow-control/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Logic Controllers and Flow Control Guide **Logic Controllers** determine the order and conditions under which samplers in a test plan execute. They allow you to build realistic, branching, looping, and aggregated user flows—such as conditional checkouts, polling asynchronous tasks, looping through array responses, and calculating composite business transaction metrics. This guide provides a practical reference to the most critical logic controllers, condition syntax, and common orchestration patterns. --- ## 1. Controller Quick Reference | Controller | Purpose | Typical Scenario | |---|---|---| | **Transaction Controller** | Aggregates child samplers into one composite transaction metric | Measuring total checkout duration (3 API calls as 1 business transaction) | | **If Controller** | Executes child elements only if a condition evaluates to `true` | Conditional paths (e.g., execute payment only if `balance > 0`) | | **While Controller** | Loops child elements until a condition evaluates to `false` | Polling an asynchronous order or job status endpoint until `STATUS == READY` | | **ForEach Controller** | Iterates over an array of indexed JMeter variables (`item_1`, `item_2`) | Processing every item extracted by a JSON or RegEx extractor | | **Loop Controller** | Executes children a fixed number of times | Repeating a specific step within a thread iteration | | **Switch Controller** | Switches execution to one child based on a numeric index or name | Multi-branch routing based on user type (`ADMIN`, `CUSTOMER`, `GUEST`) | | **Once Only Controller** | Executes only during the first iteration of each thread | Login or token retrieval at thread startup | | **Runtime Controller** | Limits execution of child elements to a specified number of seconds | Time-boxing a specific test phase | --- ## 2. If Controller & Modern Groovy Conditions The **If Controller** controls conditional branching. :::tip[Always Use Groovy Expressions in If Controllers] Uncheck **"Interpret Condition as Variable Expression?"** and use `\${__groovy(...)}` or a direct expression. This avoids JavaScript engine overhead and guarantees compiled execution. ::: ### Recommended If Controller Syntax: ```groovy // Check string equality \${__groovy(vars.get("userType") == "PREMIUM")} // Check HTTP response code from previous request \${__groovy(vars.get("JMeterThread.last_sample_ok") == "true")} // Check numeric value \${__groovy(vars.get("cartTotal").toInteger() > 100)} // Check variable existence / not empty \${__groovy(vars.get("authToken") != null && !vars.get("authToken").isEmpty())} ``` - **Evaluate for all children**: If checked, JMeter re-evaluates the condition before executing *every child element*. If unchecked, it evaluates the condition once upon entering the controller. --- ## 3. While Controller (Async Polling & Retries) The **While Controller** loops until its condition evaluates to `false`. ### Supported Conditions: - **Blank (empty)**: Exits when the last sampler in the loop fails. - **`LAST`**: Exits when the last sampler fails. If the sampler before the loop failed, the loop is not entered. - **Groovy Expression**: Custom condition string evaluating to `"false"` or `"true"`. ### Pattern: Polling Asynchronous Status with Max Retries To poll an endpoint `/api/jobs/\${jobId}/status` until status is `COMPLETED` (with a max retry safety counter): 1. **Before While Controller (JSR223 Sampler)**: ```groovy vars.put("jobStatus", "PENDING") vars.put("pollCount", "0") ``` 2. **While Controller Condition**: ```groovy \${__groovy(vars.get("jobStatus") != "COMPLETED" && vars.get("pollCount").toInteger() < 10)} ``` 3. **Inside While Controller**: - HTTP Request: `GET /api/jobs/\${jobId}/status` - JSON Extractor: extracts `jobStatus` - Flow Control Action: 2-second think time - JSR223 PostProcessor: ```groovy int count = vars.get("pollCount").toInteger() + 1 vars.put("pollCount", count.toString()) ``` --- ## 4. ForEach Controller (Iterating Over Extracted Arrays) When a **JSON Extractor** extracts an array with match number `-1` (all matches), JMeter generates indexed variables: - `productId_matchNr` = `3` - `productId_1` = `prod-101` - `productId_2` = `prod-102` - `productId_3` = `prod-103` ### ForEach Controller Configuration: - **Input variable prefix**: `productId` - **Start index for variable**: `0` (or `1`) - **End index for variable**: `\${productId_matchNr}` - **Output variable name**: `currentProductId` - **Add "_" before number**: Checked Inside the controller, simply reference `\${currentProductId}` on every iteration. --- ## 5. Transaction Controller (Composite Metrics) The **Transaction Controller** groups multiple HTTP requests into a single parent business transaction (e.g., *“Checkout Journey”* consisting of `/cart/validate`, `/payment/authorize`, and `/order/create`). ### Key Settings: - **Generate parent sample**: - **Checked (Recommended)**: The dashboard report shows only the consolidated parent transaction line (*“Checkout Journey”*), keeping reports clean and summarizing total user-perceived latency. - **Unchecked**: Outputs both individual child requests and the parent transaction line. - **Include duration of timer and pre-post processors in generated sample**: - **Unchecked (Recommended)**: Measures pure server processing and network latency. - **Checked**: Includes think times and client-side scripting delays in the overall transaction duration. --- ## 6. Switch & Runtime Controllers ### Switch Controller Routes execution to one specific child element based on: - **Index**: `0` for 1st child, `1` for 2nd child. - **Name**: Value matching the exact name of a child sampler. - **Value**: `\${paymentType}` → routes dynamically to child sampler named `CREDIT_CARD` or `PAYPAL`. ### Runtime Controller Enforces a hard time cap on child samplers: - **Runtime (seconds)**: `60` (threads run child loop continuously for 60 seconds, then exit). Encapsulate multi-step user workflows inside Transaction Controllers with "Generate parent sample" checked for cleaner dashboard reports. - [JSR223 Groovy Scripting Guide](/topics/jsr223-groovy-scripting-guide/) - [Correlation & Dynamic Values](/topics/correlation-dynamic-values/) - [Timers & Pacing Guide](/topics/timers-pacing-throughput-modeling/) - [Component Reference](/user-manual/component-reference/) Writing JavaScript or raw unescaped variable strings in If Controllers instead of `\${__groovy(...)}`; omitting a maximum loop counter in While Controllers causing infinite loops on server failure. If an If Controller never executes, log the condition output with `log.info("Condition result: " + vars.get("myVar"))` in a preceding JSR223 sampler. --- Title: JMeter Timers, Think Time, and Pacing Guide URL: https://docs.jmeter.ai/topics/timers-pacing-throughput-modeling/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Timers, Think Time, and Pacing Guide In real-world traffic, human users and client applications do not hammer servers continuously with zero delay. Without timers, JMeter threads fire requests as fast as the network and CPU permit, creating unrealistic load spikes and artificial bottlenecks. This guide explains **Timer Execution Scoping**, how to implement realistic **Think Time**, how to configure **Throughput Pacing**, and how to model target transactions-per-second (TPS) accurately. :::important[Critical Rule: Timers Execute BEFORE Samplers] A common beginner mistake is assuming a timer delays *after* a request completes. In JMeter's execution order: `Timers` → `PreProcessors` → `Sampler` → `PostProcessors` → `Assertions` → `Listeners` A timer attached to a sampler pauses the thread **before** that sampler is dispatched. ::: --- ## 1. Think Time vs Pacing: What is the Difference? | Concept | Definition | Goal | Recommended Element | |---|---|---|---| | **Think Time** | The pause a human user spends reading, typing, or deciding between steps. | Simulate human delay and realistic concurrency. | **Uniform Random Timer**, **Gaussian Random Timer**, **Flow Control Action** | | **Pacing** | Controlled delay added per iteration to ensure each virtual user maintains a fixed iteration rate. | Achieve consistent, predictable total TPS regardless of response time variations. | **Constant Throughput Timer**, **Precise Throughput Timer**, **Flow Control Action (Groovy)** | --- ## 2. Timer Types & Usage Patterns ### A. Uniform Random Timer (Recommended for Human Simulation) Delivers a random delay uniformly distributed between a minimum and maximum offset. - **Formula**: `Delay = Constant Delay Offset + (Random Number * Random Delay Maximum)` - **Example**: - `Constant Delay Offset`: `2000` (ms) - `Random Delay Maximum`: `3000` (ms) - **Result**: Pauses randomly between **2,000 ms and 5,000 ms** (2s to 5s). ### B. Gaussian Random Timer Distributes delays along a bell curve (normal distribution) around a mean value, closely matching human behavioral variance. - `Constant Delay Offset`: `3000` ms (Mean / Average) - `Deviation`: `1000` ms (Standard deviation) - **Result**: ~68% of delays fall between 2s and 4s; ~95% fall between 1s and 5s. ### C. Flow Control Action (Think Time Component) Instead of attaching timers to individual samplers, you can insert a standalone **Flow Control Action** sampler (formerly *Test Action*): - **Action**: `Pause` - **Duration**: `\${__Random(1000,3000)}` ms - **Advantage**: It visually appears as an explicit sequential step in your test tree. --- ## 3. Pacing & Target Throughput Modeling When your performance test SLA requires maintaining a fixed throughput (e.g., exactly **500 Requests Per Minute** or **100 TPS**), use throughput timers. ### Constant Throughput Timer (CTT) Calculates delays to pace threads toward a global or per-thread target. - **Target Throughput (in samples per minute)**: Target rate (e.g., `6000` for 100 RPS). - **Calculate Throughput based on**: - `this thread only`: Each thread paces independently to hit the target rate. - `all active threads`: Threads coordinate to collectively hit the total target rate. - `all active threads in current thread group`: Scoped to the enclosing group. :::caution[CTT Can Only DELAY Threads, Not Accelerate Them] If your application takes 2 seconds to respond and you only have 5 threads, the maximum throughput mathematically possible is `5 / 2s = 2.5 RPS`. A throughput timer cannot speed up slow threads—you must size your thread count to provide sufficient headroom. ::: --- ## 4. Precise Throughput Timer (Next-Gen Open Model) Introduced in JMeter modern releases, the **Precise Throughput Timer (PTT)** uses Poisson arrival processes to generate independent, realistic arrival rates that avoid artificial lockstep synchronization. ### Recommended PTT Configuration: - **Target Throughput**: `50` (samples per `second`) - **Duration**: `600` (seconds) - **Number of threads in the thread group**: Sized with sufficient buffer (e.g., 1.5x expected concurrency). - **Random seed**: Allows reproducible arrival schedules across regression runs. --- ## 5. Dynamic Pacing Calculation with JSR223 Groovy To enforce exact end-to-end iteration pacing (e.g., "Each virtual user iteration must take exactly 10 seconds regardless of how long API calls took"): 1. Add a **JSR223 PreProcessor** at the start of the iteration: ```groovy // Record iteration start time vars.putObject("iterationStartTime", System.currentTimeMillis()) ``` 2. Add a **Flow Control Action** + **JSR223 Timer** at the end of the iteration: ```groovy long targetIterationDurationMs = 10000 // 10 seconds pacing long startTime = (Long) vars.getObject("iterationStartTime") long elapsedTime = System.currentTimeMillis() - startTime long sleepTime = targetIterationDurationMs - elapsedTime if (sleepTime > 0) { return sleepTime } else { log.warn("Iteration overrun by {} ms! Target was {} ms.", Math.abs(sleepTime), targetIterationDurationMs) return 0 } ``` --- ## 6. Common Pitfalls & Best Practices 1. **Beware of Global Timers**: A timer placed at the root of a Thread Group pauses *before every single sampler* in that group. If you have 10 samplers and a 5-second timer, each iteration takes at least 50 seconds. 2. **Combine with Thread Calculators**: Use the [Thread Calculator](/tools/thread-calculator/) to compute required thread concurrency given target RPS and expected latency: ```text Threads = Target RPS * (Response Time in seconds + Think Time in seconds) ``` 3. **Avoid Constant Timers for Humans**: Static constant delays (e.g., exactly 2000 ms) create unnatural lockstep requests where thousands of virtual users hit the backend simultaneously in synchronized waves. Use the interactive Thread Calculator tool to calculate thread requirements before applying Constant or Precise Throughput Timers. - [Thread Calculator Tool](/tools/thread-calculator/) - [Workload Modeling & Thread Groups](/topics/thread-groups-workload-modeling/) - [JSR223 Groovy Scripting Guide](/topics/jsr223-groovy-scripting-guide/) - [Component Reference](/user-manual/component-reference/) Placing timers at the root of a thread group unintentionally delaying every HTTP sampler; failing to allocate enough threads to achieve the target throughput specified in Constant Throughput Timer. If throughput falls below the target configured in your timer, check thread CPU utilization and average response time—the system may be bottlenecked and unable to service more iterations. --- Title: JMeter Thread Groups & Workload Modeling URL: https://docs.jmeter.ai/topics/thread-groups-workload-modeling/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Thread Groups & Workload Modeling A **Thread Group** is the execution engine of any Apache JMeter test plan. It defines how many virtual users (threads) execute the test, how fast they spin up (ramp-up), how long the test runs (duration), and how the workload progresses over time. This guide explores both core JMeter thread groups and custom plugin thread groups, explaining how to model the 5 major performance testing types: **Baseline**, **Step-Up (Load/Stress)**, **Spike**, **Soak (Endurance)**, and **Breakpoint**. --- ## 1. Thread Group Types Comparison | Thread Group | Source | Key Advantage | Best Testing Scenario | |---|---|---|---| | **Standard Thread Group** | Built-in | Zero plugins required; simple ramp-up and duration controls | Baseline, smoke, and simple steady-state load tests | | **setUp Thread Group** | Built-in | Runs strictly *before* main load starts | Test data creation, admin login, pre-warming cache | | **tearDown Thread Group** | Built-in | Runs strictly *after* main load finishes | Test data deletion, database cleanup, report notifications | | **Concurrency Thread Group** | JMeter Plugins | Dynamic thread adjustments, step ramp-ups without thread restart | Step-up load tests, target RPS shaping with Throughput Timer | | **Ultimate Thread Group** | JMeter Plugins | Complete control over multi-stage schedules (staggered ramp, hold, shutdown) | Complex multi-wave schedules and spike testing | | **Arrivals Thread Group** | JMeter Plugins | Open workload model: schedules *arrival rate* (iterations/sec) instead of fixed users | Modern cloud APIs where user arrivals are independent of system latency | --- ## 2. The 5 Major Workload Test Models ### Model 1: Baseline / Smoke Test - **Goal**: Verify script correctness, correlation integrity, and initial server health under minimal load. - **Config**: 1 to 5 threads, 10-second ramp-up, 1-2 iterations. ### Model 2: Steady-State Load Test - **Goal**: Measure response times, throughput, and resource utilization at expected production peak load. - **Config**: Ramp up to target users (e.g., 200 users over 5 minutes), hold steady for 30–60 minutes, ramp down gracefully. ### Model 3: Step-Up (Stress / Scalability) Test - **Goal**: Identify capacity limits, latency degradation inflection points, and auto-scaling triggers. - **Config (using Concurrency Thread Group)**: - Target Concurrency: `500` - Ramp Up Time: `20 minutes` - Ramp-Up Steps: `5` (Increments of 100 users every 4 minutes) - Hold Target Rate: `10 minutes` ### Model 4: Spike Test - **Goal**: Observe system behavior when traffic spikes dramatically (e.g., flash sales, breaking news). - **Config (using Ultimate Thread Group)**: - Base load: 50 threads for 10 minutes. - Spike: Instant surge to 1,000 threads for 2 minutes. - Recovery: Drop back to 50 threads to observe if the system auto-recovers or crashes. ### Model 5: Soak (Endurance) Test - **Goal**: Detect memory leaks, unclosed database connection pools, disk buffer exhaustion, and GC degradation over time. - **Config**: 70% of peak load sustained for 4 to 24 hours. --- ## 3. Configuring Standard Thread Group ```text Action to be taken after a Sampler error: Continue (or Start Next Thread Loop) Number of Threads (users): \${__P(threads, 50)} Ramp-up period (seconds): \${__P(rampup, 60)} Loop Count: Infinite (checked) Specify Thread Lifetime: Checked Duration (seconds): \${__P(duration, 1800)} Startup delay (seconds): 0 ``` :::tip[Parameterize with __P for CI/CD] Always use `\${__P(threads, 50)}` and `\${__P(duration, 300)}` in your thread groups so you can dynamically override parameters from the CLI without editing the `.jmx` file: `jmeter -n -t plan.jmx -Jthreads=200 -Jduration=1200 -l results.jtl` ::: --- ## 4. Concurrency Thread Group + Throughput Shaping Timer For advanced step-up tests, combine the **Concurrency Thread Group** with the **Throughput Shaping Timer** (via JMeter Plugins): 1. **Concurrency Thread Group**: Manages virtual user concurrency automatically. 2. **Throughput Shaping Timer**: Sets the exact target RPS schedule (e.g., Step 1: 50 RPS for 5m → Step 2: 100 RPS for 5m). 3. Connect the two using a **Feedback Loop**: Set `Thread Schedule` in the Thread Group to link with the Throughput Shaping Timer. --- ## 5. Closed vs Open Workload Models - **Closed Workload Model** (Standard Thread Group): Virtual users finish an iteration, wait for think time, and immediately start another. If the server slows down, throughput drops automatically because threads are blocked waiting for responses. - **Open Workload Model** (Arrivals Thread Group / Precise Throughput Timer): New user arrivals occur at fixed intervals regardless of how fast or slow the server is responding. This accurately reflects open internet traffic where incoming requests do not slow down just because your backend is saturated. --- ## 6. Sizing Ramp-Up & Thread Lifecycles 1. **Never Ramp Up Instantly to Thousands of Users**: Instant ramp-up (e.g., 1,000 users in 0 seconds) causes an artificial TCP handshake storm, overwhelming load balancers with SSL handshakes before tests even begin. 2. **Ramp-Up Formula Rule of Thumb**: ```text Ramp-up (seconds) >= Target Threads / (5 to 10) ``` *(e.g., for 500 threads, ramp up over at least 50 to 100 seconds).* 3. **Choose "Start Next Thread Loop" on Error**: For multi-step business journeys, when step 1 (login) fails, starting the next loop avoids cascading 404/401 errors on subsequent steps. Choose the appropriate workload model for your test objectives and parameterize thread counts using properties (`\${__P(threads,10)}`). - [Timers, Think Time & Pacing Guide](/topics/timers-pacing-throughput-modeling/) - [JMeter Memory & JVM Tuning](/topics/jmeter-performance-tuning-guide/) - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - [Plugins Essentials](/topics/plugins-essentials/) Ramping up hundreds of threads in 0 seconds causing instant connection timeouts; running infinite loops without a duration timeout; relying on closed workload models when testing open APIs. If thread counts spike but throughput remains flat, inspect server CPU and JMeter heap metrics for resource starvation. --- Title: JMeter JDBC Database Load Testing Guide URL: https://docs.jmeter.ai/topics/jdbc-database-load-testing/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter JDBC Database Load Testing Guide Apache JMeter enables direct load testing and performance benchmarking of relational databases (PostgreSQL, MySQL, Oracle, MS SQL Server, MariaDB) using JDBC. This allows performance engineers to isolate database query latency, test connection pool limits, benchmark stored procedures, and validate database performance independently of the application layer. This guide walks through driver installation, connection pool sizing, parameterized queries, and extracting result sets into JMeter variables. --- ## 1. Installing the JDBC Driver JMeter does not bundle proprietary database drivers. You must download the appropriate JDBC driver `.jar` file and place it in JMeter’s `lib/` directory, then restart JMeter: | Database | Driver Class Name | Maven / JAR Artifact | Example Database URL | |---|---|---|---| | **PostgreSQL** | `org.postgresql.Driver` | `postgresql-42.x.jar` | `jdbc:postgresql://localhost:5432/testdb` | | **MySQL / MariaDB** | `com.mysql.cj.jdbc.Driver` | `mysql-connector-j-8.x.jar` | `jdbc:mysql://localhost:3306/testdb?useSSL=false` | | **Oracle DB** | `oracle.jdbc.OracleDriver` | `ojdbc8.jar` / `ojdbc11.jar` | `jdbc:oracle:thin:@//localhost:1521/XEPDB1` | | **MS SQL Server** | `com.microsoft.sqlserver.jdbc.SQLServerDriver` | `mssql-jdbc-12.x.jar` | `jdbc:sqlserver://localhost:1433;databaseName=testdb;encrypt=true;trustServerCertificate=true` | --- ## 2. Configuring JDBC Connection Configuration The **JDBC Connection Configuration** config element defines the connection pool. ### Core Settings: - **Variable Name Bound to Pool**: e.g., `db_pool_main` *(Must match the Variable Name in your JDBC Request samplers)*. - **Max Number of Connections**: Maximum concurrent database connections (e.g., `50`). - **Pool Timeout**: `10000` (ms) — how long a thread waits if all pool connections are occupied before throwing an error. - **Idle Timeout**: `60000` (ms). - **Validation Query**: Simple query to check connection health before borrowing: - PostgreSQL / MySQL: `SELECT 1` - Oracle: `SELECT 1 FROM DUAL` - **Transaction Isolation**: `DEFAULT` (or `TRANSACTION_READ_COMMITTED`). --- ## 3. Writing JDBC Requests Add **Sampler → JDBC Request** under your Thread Group: ### Key Settings: - **Variable Name of Pool**: `db_pool_main` - **Query Type**: - `Select Statement`: Standard read queries. - `Prepared Select Statement`: Parameterized read query (prevents SQL injection and improves DB execution plan caching). - `Prepared Update Statement`: `INSERT`, `UPDATE`, `DELETE` operations. - `Callable Statement`: Stored procedure execution. ### Example A: Parameterized Prepared Select Statement ```sql SELECT user_id, email, status, created_at FROM users WHERE status = ? AND country = ? ORDER BY created_at DESC LIMIT 10; ``` - **Parameter values**: `ACTIVE, \${userCountry}` - **Parameter types**: `VARCHAR, VARCHAR` - **Variable names**: `userId, userEmail, userStatus, userCreatedAt` --- ## 4. Extracting & Using SQL Result Sets When you specify variable names in the **Variable names** field (e.g., `userId, userEmail`), JMeter automatically parses the result set into indexed variables: - `userId_#`: Total number of returned rows (e.g., `10`). - `userId_1`: First row's `user_id`. - `userId_2`: Second row's `user_id`. - `userId_n`: nth row's `user_id`. ### Iterating Over SQL Results with ForEach Controller: 1. Set **Input variable prefix**: `userId` 2. **End index**: `\${userId_#}` 3. **Output variable name**: `currentUserId` 4. Inside the ForEach loop, make subsequent HTTP calls to `/api/users/\${currentUserId}`. --- ## 5. Benchmark Stored Procedures (Callable Statement) ```sql {call process_monthly_invoice(?, ?, ?)} ``` - **Parameter values**: `\${accountId}, \${billingCycle}, INOUT` - **Parameter types**: `INTEGER, VARCHAR, OUT VARCHAR` --- ## 6. JDBC Load Testing Best Practices 1. **Size Pool Connections Appropriately**: Set `Max Number of Connections` equal to or greater than the number of active concurrent threads in the Thread Group to prevent threads from blocking on pool locks. 2. **Use Prepared Statements**: Always prefer *Prepared Select/Update* statements over raw SQL strings to allow the database engine to reuse execution plans and avoid parse overhead. 3. **Clean Up Generated Test Data**: Use a **tearDown Thread Group** with a dedicated cleanup query to delete records inserted during test execution. Download your database vendor's JDBC JAR, drop it into JMeter's `lib/` directory, and run a 1-thread smoke test to verify connectivity. - [JDBC Pool Errors Playbook](/topics/errors/jdbc-connection-pool-errors/) - [ClassNotFound & Missing JARs](/topics/errors/class-not-found-noclassdeffound/) - [Database Test Plan Manual](/user-manual/build-db-test-plan/) - [Properties Reference](/user-manual/properties-reference/) Forgetting to place the JDBC driver JAR in JMeter's `lib/` directory; mismatched pool variable names between config and samplers; setting connection pool size too low for high thread counts. If connections fail, verify firewall access to DB port (5432/3306/1433) and check `jmeter.log` for `Cannot create PoolableConnectionFactory`. --- Title: JMeter JVM, Memory & Operating System Tuning URL: https://docs.jmeter.ai/topics/jmeter-performance-tuning-guide/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter JVM, Memory & Operating System Tuning When running high-volume performance tests (thousands of virtual users or tens of thousands of requests per second), the bottleneck is frequently the **load generator itself** rather than the target application. Un-tuned JMeter injectors suffer from heap exhaustion (`OutOfMemoryError`), excessive Garbage Collection (GC) pauses, port exhaustion, and CPU throttling. This guide provides end-to-end instructions for tuning JMeter's JVM heap, Garbage Collector, operating system TCP parameters, and test plan efficiency. --- ## 1. JVM Heap Sizing (`setenv.sh` / `setenv.bat`) By default, Apache JMeter ships with a conservative heap allocation (often 1 GB). For production load generation, allocate 50% to 70% of available system RAM to the JVM heap. Create a `setenv.sh` (Linux/macOS) or `setenv.bat` (Windows) file in JMeter’s `bin/` directory: ### Linux / macOS (`bin/setenv.sh`): ```bash #!/bin/sh # Allocate 8GB min and max heap with G1GC export HEAP="-Xms8g -Xmx8g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m" export GC_ALGO="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=15" export JVM_ARGS="-XX:+AlwaysPreTouch -Djava.awt.headless=true" ``` ### Windows (`bin/setenv.bat`): ```bat @echo off set HEAP=-Xms8g -Xmx8g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m set GC_ALGO=-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=15 set JVM_ARGS=-XX:+AlwaysPreTouch -Djava.awt.headless=true ``` :::tip[Keep -Xms equal to -Xmx] Setting the initial heap (`-Xms`) equal to the maximum heap (`-Xmx`) eliminates JVM memory resizing overhead during test execution and guarantees that heap memory is pre-allocated upon startup (`-XX:+AlwaysPreTouch`). ::: --- ## 2. Garbage Collection (GC) Optimization Use the **G1 Garbage Collector** (default on modern Java versions). Key flags: - `-XX:+UseG1GC`: Low-latency concurrent collector optimized for multi-gigabyte heaps. - `-XX:MaxGCPauseMillis=100`: Target maximum pause time goal. - `-XX:InitiatingHeapOccupancyPercent=45`: Initiates concurrent marking before memory gets dangerously full. - `-XX:G1ReservePercent=15`: Prevents allocation failures during concurrent cycles. To log garbage collection events for analysis: ```bash -Xlog:gc*,gc+phases=debug:file=jmeter_gc.log:time,uptime,pid:filecount=5,filesize=50M ``` --- ## 3. Operating System & Kernel TCP Tuning (Linux) Under high RPS, JMeter opens and closes thousands of TCP sockets per minute. Without kernel tuning, you will encounter `java.net.BindException: Address already in use` or `Too many open files`. ### A. Increase File Descriptor Limits (`/etc/security/limits.conf`) ```text * soft nofile 655350 * hard nofile 655350 * soft nproc 655350 * hard nproc 655350 ``` ### B. Optimize TCP Sockets in `/etc/sysctl.conf` Apply with `sudo sysctl -p`: ```ini # Enable fast recycling of TIME_WAIT sockets net.ipv4.tcp_tw_reuse = 1 # Expand ephemeral port range net.ipv4.ip_local_port_range = 1024 65535 # Reduce TIME_WAIT timeout to 30 seconds net.ipv4.tcp_fin_timeout = 15 # Increase network connection backlog queue net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.core.netdev_max_backlog = 100000 # Increase socket memory buffers net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 ``` --- ## 4. Test Plan & Execution Architecture Best Practices | Anti-Pattern (High Overhead) | Tuned Best Practice (Maximum Throughput) | |---|---| | Running test via GUI | **Always use CLI (`jmeter -n -t plan.jmx`)** | | Active View Results Tree or Summary Report | **Disable all GUI listeners during load runs** | | Saving full response data in JTL log | **Save only minimal CSV metrics (`jmeter.save.saveservice.*`)** | | BeanShell / JavaScript scripts | **JSR223 Groovy with "Cache compiled script" checked** | | Dynamic `\${var}` inside cached scripts | **`vars.get("var")` inside script body** | | Heavy DOM XPath extractors | **Boundary Extractor or JSON Extractor** | --- ## 5. Network Interface & DNS Caching By default, Java caches DNS lookups forever. If load testing microservices behind an AWS ALB or round-robin DNS: 1. In `system.properties`, set DNS cache TTL: ```properties networkaddress.cache.ttl=10 networkaddress.cache.negative.ttl=0 ``` 2. In HTTP Request Defaults, check **Use MD5 checksum** only if verifying large file download integrity. Create a `bin/setenv.sh` or `bin/setenv.bat` file in your JMeter directory with `-Xms4g -Xmx4g` and verify with the interactive Heap Estimator tool. - [Heap Estimator Tool](/tools/heap-estimator/) - [OutOfMemoryError Heap Playbook](/topics/errors/out-of-memory-heap/) - [Too Many Open Files (ulimit)](/topics/errors/too-many-open-files-ulimit/) - [Thread Calculator Tool](/tools/thread-calculator/) Allocating more than 80% of total physical RAM to JMeter heap (causing OS kernel page swapping); keeping View Results Tree enabled in headless CLI runs. If the test freezes or pauses periodically, inspect GC logs (`jmeter_gc.log`) to verify whether Full GC stop-the-world pauses are occurring. --- Title: JMeter Plugins Essentials URL: https://docs.jmeter.ai/topics/plugins-essentials/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Plugins Essentials Apache JMeter is extensible: custom samplers, listeners, timers, and config elements can be added as JARs under `lib/ext`. The community **JMeter Plugins** ecosystem and **Plugins Manager** are the usual way teams install popular extensions (custom thread groups, parallel controllers, WebSocket, etc.). Official project material points to plugins via wiki links (for example [Boss / resources](/user-manual/boss/) references JMeterPlugins). This guide covers grounded install discipline, must-know plugin categories, and operational risks. :::caution[Version compatibility] Plugins must match your **JMeter major/minor** line. After upgrading JMeter, re-check every plugin. Distributed workers need **identical** plugin sets ([remote testing](/user-manual/remote-test/)). ::: ## Core vs plugins | In core JMeter | Often via plugins | |----------------|-------------------| | HTTP, JDBC, JMS, LDAP, FTP, mail samplers | WebSocket, gRPC, Kafka, MQTT clients | | Standard Thread Group, timers, assertions | Ultimate/custom thread groups, throughput shaping | | HTML dashboard, Backend Listener | Extra listeners/graphs | | Programmatic API / DSL (5.6+) | Third-party DSL helpers | Always prefer a **core** element when it meets the need: fewer moving parts, better docs on this site’s [component reference](/user-manual/component-reference/). ## Plugins Manager (typical workflow) Community Plugins Manager (JAR in `lib/ext`): 1. Download the Plugins Manager JAR into `JMETER_HOME/lib/ext`. 2. Restart JMeter. 3. Options → Plugins Manager (menu label may vary slightly by version). 4. Install plugins; apply; restart if prompted. 5. Confirm new elements appear in the right-click Add menu. **CI/Docker:** do not click GUI. Either: - Bake plugins into the image, or - Script install with the Plugins Manager cmd tooling if you use it, or - Copy known-good JARs into `lib/ext` from a vetted cache. Pin versions. “Latest” plugins on a floating CI image cause heisenbugs. ## Custom / extended thread groups Standard [Thread Group](/user-manual/test-plan/) supports threads, ramp-up, loops, and schedulers. Plugins commonly add: | Capability | Why teams install it | |------------|----------------------| | Stepping ramp | Stair-step concurrency | | Ultimate-style schedules | Complex day patterns | | Arrival-rate / RPS shaping | Open-loop style load (with timers/plugins) | | Delayed start options | Related core property exists for delayed thread creation in best practices | Even with plugins, [best practices](/user-manual/best-practices/) still apply: size threads for hardware and avoid coordinated omission; validate with pilots; prefer CLI for real load. Use the [Thread Calculator](/tools/thread-calculator/) for first estimates. Document in the plan README which thread group **class** you used so others can open the jmx. ## Parallel Controller (and concurrency inside a thread) A frequent plugin is a **Parallel Controller** (or similarly named element) that runs child samplers concurrently **within** one virtual user iteration (e.g. parallel resource fetches). Contrast: | Element | Concurrency model | |---------|-------------------| | Thread Group threads | Concurrent **users** | | Parallel Controller (plugin) | Concurrent **actions** for one user | | Transaction Controller (core) | Group samples for reporting, not necessarily parallel I/O | If you simulate browsers that load assets in parallel, parallel controllers can help. For API tests, prefer explicit sequential business steps unless parallelism is required. Watch thread explosion: parallel children × many VUs multiplies connection count. ## Other high-value plugin categories | Category | Examples of use | |----------|-----------------| | **Protocol** | WebSocket ([guide](/topics/websocket-load-testing/)), gRPC/Kafka/MQTT ([guide](/topics/grpc-kafka-mqtt/)) | | **Timers** | Throughput shaping, sophisticated pacing | | **Listeners** | Extra graphs (still disable heavy GUI listeners under load) | | **Config** | Parameterized controllers, dummy samplers for debugging | | **Functions** | Extra function packs (verify security of custom code) | ## Install without Plugins Manager 1. Obtain plugin ZIP/JAR from a trusted release. 2. Place JARs in `lib/ext` (and any required deps per plugin README, sometimes `lib/`). 3. Restart JMeter. 4. Commit a **lockfile** or image layer that lists SHA256 of each JAR for the team. Never download arbitrary JARs from untrusted mirrors on build agents. ## Distributed and container rules From remote testing docs: data files and classes must be available on servers. Plugins are code: - Copy `lib/ext` plugins to **every** worker image. - Same JMeter version everywhere. - Controller sending a plan that references a missing plugin class fails at runtime on workers. See [Docker/Kubernetes](/topics/docker-kubernetes/) for baking plugins into images. ## Performance and safety 1. Plugins can add CPU/allocation overhead; measure. 2. Prefer JSR223 Groovy over legacy BeanShell for custom logic in core ([best practices](/user-manual/best-practices/)). 3. Custom plugins that log every sample can destroy throughput. 4. Review licenses of plugins for enterprise compliance. 5. After JMeter upgrade, run a smoke plan covering every plugin element you use. ## Debugging missing elements | Symptom | Fix | |---------|-----| | Element not in menu | Plugin not installed; wrong JMeter version | | Cannot open jmx | Missing plugin that defined a class in the plan | | Works locally, fails in CI | CI image lacks plugins | | Serialization errors remote | Worker plugin mismatch | ## Related reading - [WebSocket load testing](/topics/websocket-load-testing/) - [gRPC Kafka MQTT](/topics/grpc-kafka-mqtt/) - [Component reference](/user-manual/component-reference/) - [Extending JMeter](/extending/extending-jmeter/) - [Distributed testing](/topics/distributed-testing/) ## Frequently asked questions ### Are JMeter plugins part of Apache core? Popular plugins are community extensions installed into `lib/ext`. Core JMeter ships many protocols, but not every modern stack client. ### What is Plugins Manager? A community tool that installs plugin sets into your JMeter installation from a catalog. Restart JMeter after installs as required. ### Do I need plugins for HTTP API tests? Often no. HTTP Request, Header Manager, CSV, extractors, and dashboard are core. Add plugins for missing protocols or advanced thread schedules. ### Why does my jmx fail on another machine? That machine lacks the plugins (or JMeter version) used when the plan was saved. Align installations or remove plugin-only elements. ### Can plugins be used in non-GUI mode? Yes. CLI loads the same `lib/ext` classes. Ensure the CI/container image contains them. ### Where do I learn to write my own plugin? See [Extending JMeter](/extending/extending-jmeter/) for developer-oriented guidance on custom components. List every non-core element in your plans and pin matching plugin versions into your Docker/CI image. - [Extending JMeter](/extending/extending-jmeter/) - [WebSocket](/topics/websocket-load-testing/) - [Best Practices](/user-manual/best-practices/) Floating plugin versions; workers without plugins; using parallel controllers without connection limits; installing untrusted JARs. --- Title: JMeter WebSocket Load Testing URL: https://docs.jmeter.ai/topics/websocket-load-testing/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter WebSocket Load Testing Apache JMeter’s **core** distribution focuses on protocols such as HTTP, JDBC, JMS, LDAP, and FTP (see the [component reference](/user-manual/component-reference/) sampler list). **WebSocket is not a built-in core sampler** in the same way HTTP Request is. Production WebSocket load tests with JMeter almost always depend on the **plugin ecosystem** (JMeter Plugins / Plugins Manager and community WebSocket plugins). This guide explains a grounded, plugin-aware workflow: install plugins, design sessions, correlate, size threads, and operate CLI load without overstating what core JMeter alone can do. :::note[Plugin-aware] Plugin class names, sampler labels, and versions change over time. Treat UI field names below as **patterns**. Confirm against the plugin docs for the exact version you install, and pin plugin versions in CI for reproducibility. ::: :::tip[HTTP first] Many “WebSocket apps” still authenticate and bootstrap over **HTTPS**. Model login with core [HTTP Request](/topics/api-load-testing/) + [correlation](/topics/correlation-dynamic-values/), then open the socket with the plugin sampler. ::: ## What WebSocket load means A WebSocket client: 1. Completes an HTTP Upgrade handshake. 2. Keeps a **long-lived** bidirectional connection. 3. Sends and receives messages (text/binary) with app-level framing. 4. Closes or drops under errors. Load dimensions differ from REST: | Dimension | REST-style HTTP | WebSocket | |-----------|-----------------|-----------| | Connection | Often short (keep-alive pool) | Long-lived per VU | | Metric focus | Request latency, RPS | Connect time, message latency, msg/s, errors, connection drops | | Thread usage | Sample ≈ request | Thread may block on read/write for the session lifetime | | Memory | Per-sample buffers | Per-open connection state | JMeter’s thread model ([best practices](/user-manual/best-practices/) on sizing threads) still applies: each concurrent session typically needs a thread (or plugin-specific async mode if offered). Undersizing threads relative to message rates invites [coordinated omission](/tools/coordinated-omission/) style bias. ## Install plugins (Plugins Manager) Core JMeter does not install third-party plugins by itself. Community practice: 1. Install **JMeter Plugins Manager** (see [plugins essentials](/topics/plugins-essentials/) and the JMeter wiki plugins page linked from project docs such as [Boss](/user-manual/boss/)). 2. Search for a maintained **WebSocket** plugin compatible with your JMeter major version. 3. Install, **restart** JMeter, confirm new samplers appear under Sampler. 4. For CI/Docker, bake the same plugin set into the image or install in the job before `jmeter -n`. [Distributed testing](/topics/distributed-testing/) requires **identical plugins on every worker**. Missing plugin JARs cause serialization or class-not-found failures remotely. ## Reference architecture for a plan ```text Test Plan ├── HTTP Request Defaults / Header Manager (auth bootstrap) ├── CSV Data Set (users) └── Thread Group ├── HTTP Login (core) + extract token ├── WebSocket Open (plugin) // pass token via query/header if supported ├── Loop Controller │ ├── WebSocket Write/Ping (plugin) │ ├── WebSocket Read (plugin) + assertions/extractors if available │ └── Timer (pace messages) └── WebSocket Close (plugin) ``` Exact sampler names depend on the plugin (Open, Single Read, Single Write, request-response, ping/pong, etc.). ## Authentication patterns | Pattern | Approach | |---------|----------| | Ticket in query string | Extract from HTTP, use `\${ticket}` in open URL | | Bearer on upgrade | Plugin header fields if supported; else query ticket | | Cookie session | Cookie Manager + open to same host | | Subprotocol | Plugin field for `Sec-WebSocket-Protocol` when required | Use [JWT/OAuth](/topics/jwt-oauth-sso/) guidance for the HTTP side. Never hard-code long-lived tokens in the plan. ## Designing message load 1. Define **message rate per session** (e.g. 1 msg/s) and **session count** (threads). 2. Aggregate throughput ≈ sessions × msg/s if the server keeps up. 3. Use timers for pacing; avoid unbounded tight write loops unless stress-testing. 4. Separate samplers for **connect**, **write**, **read**, **close** so the [dashboard](/user-manual/generating-dashboard/) shows which phase fails. 5. Assert on payload fragments or status where the plugin exposes response data. Payloads: prefer variables and CSV over huge embedded binaries. Functions such as `\${__UUID}` and `\${__time}` help unique message ids ([functions](/topics/functions-and-variables/)). ## Correlation over the socket If the server pushes an id you must echo: 1. Read sampler captures response. 2. Regex/JSON extractor (if response is available as sample data) sets `\${msgId}`. 3. Next write uses `\${msgId}`. If the plugin does not expose body to standard post-processors, check plugin-specific “read to variable” options in its documentation. ## Running load (CLI) Same lean rules as HTTP ([best practices](/user-manual/best-practices/)): ```bash jmeter -n -t websocket-plan.jmx -l results.jtl -e -o report/ \ -Jthreads=200 -Jrampup=120 -Jhost=ws.example.com ``` - Disable View Results Tree for load. - Size heap for concurrent connections ([Heap Estimator](/tools/heap-estimator/)). - Watch injector file descriptors and ephemeral ports; long-lived sockets stress OS limits. - Prefer dedicated injectors; do not co-locate with the system under test. ## Metrics that matter From JMeter results (labels you control) plus optional [Backend Listener](/topics/grafana-influx-backend-listener/): - Connect success rate and connect time - Write/read error % - Response time for request-response message pairs - Active threads / open sessions - Server-side connection count and message lag (not only JMeter) HTML dashboard still works on the JTL if samples are recorded as standard SampleResults. ## Limitations and honesty checklist 1. Core JMeter alone is **not** a full WebSocket IDE. 2. Plugin quality and maintenance vary; pin versions. 3. Browser WebSocket traffic recorded via HTTP proxy may **not** capture socket frames the way HTTP is recorded. 4. Extremely high fan-in may need specialized tools; prove scale with pilots. 5. TLS (`wss://`) needs correct JVM trust stores, same as HTTPS. ## Troubleshooting | Symptom | Checks | |---------|--------| | Sampler missing in GUI | Plugin not installed / wrong JMeter version | | Works in GUI, fails in CI | Plugin absent in CI image | | 401 on open | Token query/header not correlated | | Handshake fail | Proxy, TLS, wrong scheme `ws` vs `wss` | | Threads stuck | Blocking read without timeout; plugin timeout settings | | OOM | Too many open sessions per JVM; raise heap or split engines | ## Related reading - [Plugins essentials](/topics/plugins-essentials/) - [API load testing](/topics/api-load-testing/) - [Correlation](/topics/correlation-dynamic-values/) - [Grafana / Influx / Backend Listener](/topics/grafana-influx-backend-listener/) - [Distributed testing](/topics/distributed-testing/) - [gRPC Kafka MQTT](/topics/grpc-kafka-mqtt/) ## Frequently asked questions ### Does stock Apache JMeter include a WebSocket sampler? WebSocket support is provided through the plugin ecosystem, not as a primary core sampler like HTTP Request. Install a maintained WebSocket plugin via Plugins Manager or manual JARs. ### Can I use the HTTP(S) Test Script Recorder for WebSockets? The recorder is built for HTTP(S) request/response capture. Do not expect full WebSocket frame recording the way you record REST calls. Build socket steps with the plugin after HTTP login. ### How many threads do I need for WebSocket tests? Often one thread per concurrent connection for classic Thread Groups. Size from concurrent sessions and message pacing, then validate injector CPU, RAM, and file descriptors. ### Do plugins need to be on every distributed worker? Yes. Workers must match the controller’s JMeter version and plugin set, same as other third-party engines in remote testing. ### Should I still generate an HTML dashboard? Yes. If the plugin writes standard sample results, `-e -o report/` works. Label connect/write/read/close clearly for readable statistics. Install Plugins Manager, add a WebSocket plugin matching your JMeter version, and prove open-write-close with one thread before load. - [Plugins Essentials](/topics/plugins-essentials/) - [JWT OAuth SSO](/topics/jwt-oauth-sso/) - [Best Practices](/user-manual/best-practices/) Assuming core JMeter has WebSocket; forgetting plugins in CI; no timeouts on reads; mixing wss hosts with wrong trust stores. --- Title: JMeter gRPC, Kafka, and MQTT URL: https://docs.jmeter.ai/topics/grpc-kafka-mqtt/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # gRPC / Kafka / MQTT with JMeter (Plugin Ecosystem) Modern systems often speak **gRPC**, **Kafka**, or **MQTT** alongside HTTP. Stock Apache JMeter includes a **wide** set of protocols (HTTP, JDBC, JMS, LDAP, FTP, mail, and more in the [component reference](/user-manual/component-reference/)), but **gRPC, Kafka, and MQTT clients are not the classic core HTTP-centric story**. Teams typically add **community plugins** or custom samplers. This guide sets honest expectations, install rules, and test-design patterns grounded in JMeter’s extension model and operational best practices. :::note[Plugin-aware] There is no single Apache-maintained “official” sampler set for every gRPC/Kafka/MQTT feature. Validate plugin compatibility with your JMeter version, pin JARs, and read that plugin’s own docs for field-level detail. ::: ## What core JMeter already covers Useful adjacent core capabilities: | Need | Core approach | |------|----------------| | HTTP/JSON APIs | HTTP Request ([API guide](/topics/api-load-testing/)) | | JMS queues/topics | JMS samplers ([JMS plans](/user-manual/build-jms-point-to-point-test-plan/)) | | JDBC backends | JDBC Request | | Custom TCP | Java Request / custom sampler ([extending](/extending/extending-jmeter/)) | | Live metrics | Backend Listener ([guide](/topics/grafana-influx-backend-listener/)) | If your “Kafka test” is really “HTTP service that writes to Kafka,” load the **HTTP API** with core JMeter and monitor Kafka lag separately. ## Plugin ecosystem overview | Protocol | Typical JMeter approach | |----------|-------------------------| | **gRPC** | Plugin sampler using `.proto` / reflection; or gateway HTTP/JSON if available | | **Kafka** | Plugin producer/consumer samplers; or JMS if you use a JMS bridge (different semantics) | | **MQTT** | Plugin publisher/subscriber samplers | | **WebSocket** | Plugins ([WebSocket guide](/topics/websocket-load-testing/)) | Install via [Plugins Manager / lib/ext](/topics/plugins-essentials/). Identical plugins on all [distributed](/topics/distributed-testing/) workers. ## Shared design principles (all three) 1. **Bootstrap auth** often still uses HTTP (OIDC token) → core HTTP + [JWT](/topics/jwt-oauth-sso/) + [correlation](/topics/correlation-dynamic-values/). 2. **Stable sampler labels** for dashboard/Grafana cardinality. 3. **CLI load**: `jmeter -n -t ... -l ...` ([best practices](/user-manual/best-practices/)). 4. **Size threads** for concurrent streams/producers ([Thread Calculator](/tools/thread-calculator/)). 5. **Assert** business success (not only “socket connected”). 6. **Observe the broker/service** (consumer lag, gRPC server metrics), not only JMeter RPS. ## gRPC load testing patterns ### When plugins fit - Direct unary or streaming calls to gRPC services. - Teams already invested in JMeter for mixed protocols. ### Plan sketch ```text Thread Group ├── HTTP get token (optional) ├── gRPC sampler (plugin): method, metadata, message ├── Assertion / extractor on response payload └── Timer ``` ### Pitfalls - Protobuf version skew between plugin and server. - TLS and metadata (`authorization`) misconfiguration. - Streaming RPCs hold threads longer than unary calls. - Reflection vs descriptor files in CI images. ### Alternative Many orgs use dedicated gRPC load tools or k6/ghz for pure gRPC and keep JMeter for HTTP/JMS. That can be the right split ([vs alternatives](/topics/jmeter-vs-alternatives/)). ## Kafka load testing patterns ### Producer-focused - Plugin Kafka Producer sampler: topic, key, payload, acks. - CSV or functions for keys (`\${__UUID}`). - Measure produce latency and error %. ### Consumer-focused - Harder in load tools: consumer lag is a **platform** metric. - Plugin consumers may poll messages; define success clearly (message received vs processing time). - Avoid unbounded consume loops without stop conditions. ### Semantics Kafka is not HTTP: throughput depends on batching, compression, partition count, and broker disks. Align test topics with non-prod clusters and retention policies so you do not flood shared brokers. ### JMS note Core **JMS** samplers talk to JMS providers. That is not a drop-in Kafka client even if some stacks bridge protocols. Use the right tool for the wire protocol you mean to stress. ## MQTT load testing patterns ### Publisher / subscriber - Fan-in: many publishers, few topics. - Fan-out: few publishers, many subscribers (threads as subscribers). - QoS levels change latency and reliability trade-offs; document which QoS you test. ### Session and auth - Username/password or certs via plugin fields. - Unique `clientId` per thread (`client-\${__threadNum}`) to avoid broker kicks. ### IoT scale Millions of devices usually need specialized generators; prove plugin limits with pilots before promising scale. ## Containers and CI Bake protocol plugins into images ([Docker](/topics/docker-kubernetes/)). CI must: - Contain protos/schemas if required - Provide broker endpoints via `\${__P}` - Network-reach Kafka/MQTT/gRPC from the runner ## Observability | System | Watch | |--------|-------| | gRPC server | RED metrics, status codes | | Kafka | produce error rate, lag, ISR | | MQTT broker | connections, drop rates | | JMeter | JTL dashboard + optional Backend Listener | ## Decision table: JMeter plugins vs other tools | Situation | Lean toward | |-----------|-------------| | Mixed HTTP + one plugin protocol, existing jmx skills | JMeter + plugins | | Pure gRPC at huge scale, code-first | Specialized gRPC load tool / k6 ecosystem | | Kafka correctness/perf of brokers | Kafka-native benchmarks + app-level HTTP tests | | Need GUI correlation for HTTP then message | JMeter hybrid plans | ## Related reading - [Plugins essentials](/topics/plugins-essentials/) - [WebSocket](/topics/websocket-load-testing/) - [Extending JMeter](/extending/extending-jmeter/) - [API load testing](/topics/api-load-testing/) - [Best practices](/user-manual/best-practices/) ## Frequently asked questions ### Does Apache JMeter core include Kafka or gRPC samplers? Not as the primary built-in story like HTTP Request. Use plugins, custom samplers, or test adjacent HTTP APIs. ### Can I use JMS samplers for Kafka? Only if you intentionally use a JMS layer. Wire-level Kafka clients are different; prefer a Kafka plugin or other tools for Kafka protocol load. ### How do I install protocol plugins? Plugins Manager or manual JARs into `lib/ext`, restart, pin versions, mirror into CI/worker images. ### What is the biggest distributed-testing risk with plugins? Workers missing plugin JARs or version skew causing ClassNotFound or serialization errors. ### Should every message protocol test be done in JMeter? No. Choose JMeter when it fits team skills and hybrid protocols. Use specialized tools when they are clearly better for a single technology. ### How do I assert success for async messaging? Define explicit signals: produce ack, message visible to a consumer group, or downstream HTTP status. Pure fire-and-forget without observability is a weak test. Confirm whether you must hit the wire protocol or only an HTTP facade; install the matching plugin only if wire-level load is required. - [Plugins Essentials](/topics/plugins-essentials/) - [Extending JMeter](/extending/extending-jmeter/) - [Distributed Testing](/topics/distributed-testing/) --- Title: JMeter Grafana InfluxDB Backend Listener URL: https://docs.jmeter.ai/topics/grafana-influx-backend-listener/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter + Grafana / InfluxDB / Backend Listener For long tests you need **live** visibility, not only a post-run HTML report. Since JMeter 2.13, the [Backend Listener](/user-manual/component-reference/#Backend_Listener) can send metrics to external backends. JMeter ships Graphite and InfluxDB clients; Grafana commonly visualizes InfluxDB or Graphite data. This guide summarizes the official [Real-time results](/user-manual/realtime-results/) chapter and component reference fields so you can wire live dashboards without abandoning CLI + [HTML dashboard](/user-manual/generating-dashboard/) artifacts. :::tip[Both, not either] Use Backend Listener for **during-test** graphs. Still write a JTL with `-l` and generate the HTML report with `-e -o` for durable, shareable results. ::: ## What Backend Listener is Backend Listener is a **Listener** implementation that pushes metrics through a `BackendListenerClient` rather than only painting GUI graphs. Official clients include: | Client | Introduced / notes | |--------|--------------------| | **GraphiteBackendListenerClient** | Graphite-compatible metrics; also used with InfluxDB Graphite input in some setups | | **InfluxdbBackendListenerClient** | Since JMeter **3.2**; direct Influx write, custom schema, annotations support | | **InfluxDBRawBackendListenerClient** | Since JMeter **5.4**; writes sample-oriented data (heavier) | You can implement `AbstractBackendListenerClient` for other backends (JDBC, JMS, custom HTTP), as described in the real-time results overview. ## Metrics exposed (core concepts) The real-time results doc groups metrics such as: ### Thread / virtual user metrics - `test.minAT` / `test.maxAT` / `test.meanAT` - active threads - `test.startedT` / `test.endedT` - started / finished threads Names are prefixed by a configurable **root metrics prefix**. ### Response-related metrics (per sampler name) Examples documented: - `.ok.count` - successful responses - `.h.count` - hits per second (includes sub-results depending on Transaction Controller settings) - `.ok.min` / `.ok.max` - min/max successful response times - Additional percentile and error metrics as documented for your client **Transaction Controller note:** for hit-rate style metrics, official text warns about parent sampler generation settings. Keep transaction usage consistent so Grafana panels mean what you think. ## Adding Backend Listener to a plan 1. Add **Backend Listener** under Test Plan or Thread Group (scope like other listeners). 2. Choose implementation class (`InfluxdbBackendListenerClient` is the usual Influx path). 3. Fill parameters from the [component reference](/user-manual/component-reference/). 4. Run a short CLI test and confirm points arrive in Influx. 5. Build or import Grafana panels on those measurements. ### InfluxdbBackendListenerClient parameters (documented) From the component reference (verify against your JMeter version): | Parameter | Role | |-----------|------| | `influxdbUrl` | Write URL, e.g. `http://influxHost:8086/write?db=jmeter` | | `influxdbToken` | InfluxDB 2 token (since 5.2); example format in docs | | `measurement` | Line protocol measurement; default often `jmeter` | | `application` | Tag for separating apps/tests | | `title` / run title fields | Help distinguish runs in Grafana | | `eventTags` | Tags for Grafana annotations (`events` measurement) | | `summaryOnly` | When true, send fewer detail series (lighter) | | `samplersRegex` | Filter which sampler labels are sent | | `percentiles` | Which percentiles to export | Exact property rows can evolve; copy from your JMeter UI or the versioned component reference on this site. ### InfluxDB v2 The real-time results chapter includes an **InfluxDB v2** subsection (anchor `influxdb_v2` in the manual). Use org/bucket style URLs and tokens as shown there and in the component reference cloud example for raw client: `https://.../api/v2/write?org=org-id&bucket=jmeter` ### GraphiteBackendListenerClient Parameters include `graphiteHost`, `graphitePort` (default **2003**; pickle sender notes for port **2004** in the reference). You can point at Graphite itself or an InfluxDB instance with Graphite input enabled, depending on your stack. ### InfluxDBRawBackendListenerClient Since 5.4, raw client writes more granular sample data. Expect **higher write volume** and Influx load. Use when you need per-sample analysis in the TSDB; prefer the aggregated Influx client for large tests if summary metrics suffice. ## Grafana setup pattern Official docs mention Grafana dashboards and InfluxDB annotations. Typical flow: 1. Create Influx datasource in Grafana (URL, token, org/bucket or database). 2. Query the `jmeter` measurement (or your `measurement` name). 3. Panel active threads (`minAT`/`meanAT`/`maxAT`), throughput, and response time percentiles. 4. Enable annotations from the `events` measurement if you set `eventTags` / title fields. 5. Variable filters on `application` and `transaction` tags to switch tests. Screenshot references appear in the component reference (`grafana_dashboard.png`). Community dashboards exist; always remap metric names to **your** prefix and JMeter version. ## CLI operation ```bash jmeter -n -t plan.jmx -l results.jtl \ -JinfluxHost=influx.internal \ -e -o report/ ``` Backend Listener configuration usually lives in the plan. You can still parameterize hosts with variables if you externalize URL pieces via `\${__P}` where the element allows. Lean-run rules still apply ([best practices](/user-manual/best-practices/)): - No View Results Tree under load. - Backend Listener itself costs CPU and network; use `samplersRegex` / `summaryOnly` to reduce series. - Ensure the injector can reach Influx (firewall, DNS). ## Distributed tests With [remote testing](/topics/distributed-testing/): - Each worker runs the plan, so **each worker may send metrics** if Backend Listener is in the plan. - Tag by hostname or application property so Grafana can split injectors. - Controller still aggregates the JTL when using standard remote mode. - Do not overwhelm Influx with thousands of high-cardinality series (unique dynamic sampler names). ## Cardinality and naming discipline Bad: - Sampler labels containing free-text URLs with unique ids every sample. Good: - Stable labels: `Login`, `Search`, `Checkout`. - Dynamic data in body/parameters, not in the sample label. High cardinality destroys Influx performance and Grafana usability. ## Failure modes | Symptom | Check | |---------|-------| | No data in Grafana | URL/token/db; network from injector; Backend Listener enabled | | Partial series | `samplersRegex` too strict; summaryOnly | | Influx OOM / heavy writes | Raw client at high RPS; reduce cardinality | | Clock skew graphs | NTP on injectors and Influx | | Auth errors Influx 2 | Token permissions for org/bucket | ## Related reading - [Real-time results (manual)](/user-manual/realtime-results/) - [Backend Listener component](/user-manual/component-reference/) - [Generating dashboard](/user-manual/generating-dashboard/) - [CI/CD load testing](/topics/ci-cd-load-testing/) - [APDEX / SLOs / percentiles](/topics/apdex-slo-percentiles/) ## Frequently asked questions ### What is JMeter Backend Listener? A listener that sends metrics to external backends through a BackendListenerClient implementation instead of only showing GUI graphs. ### Which Influx client should I use? For live dashboards during large tests, start with InfluxdbBackendListenerClient (since 3.2). Use InfluxDBRawBackendListenerClient (since 5.4) when you need raw sample writes and can afford the volume. ### Does Backend Listener replace the HTML report? No. Keep `-l` results and `-e -o` HTML dashboards for offline analysis and artifacts. Backend Listener is for live monitoring. ### Can I use Graphite instead of InfluxDB? Yes. GraphiteBackendListenerClient ships with JMeter. Grafana can also query Graphite datasources. ### Why are my Grafana series empty for some samplers? Check `samplersRegex`, whether those labels actually ran, and whether Transaction Controller parent/child settings change what is emitted. ### How do annotations work? InfluxdbBackendListenerClient can write events used as Grafana annotations; `eventTags` and title-related fields help tag runs. See the component reference and Grafana Influx annotation docs linked from the manual. Add InfluxdbBackendListenerClient with a lab Influx URL, run a two-minute CLI test, and build one Grafana panel on active threads. - [Real-time results](/user-manual/realtime-results/) - [Dashboard report](/user-manual/generating-dashboard/) - [Best Practices](/user-manual/best-practices/) Unique sampler labels per request; raw Influx client at huge RPS without capacity planning; relying only on live graphs with no JTL artifact. --- Title: JMeter APDEX, SLOs, and Percentiles URL: https://docs.jmeter.ai/topics/apdex-slo-percentiles/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # Performance SLOs, APDEX, and Percentiles with JMeter Load tests only help if you define **what good looks like**. This guide connects service-level objectives (SLOs) to JMeter’s [HTML dashboard](/user-manual/generating-dashboard/) metrics: APDEX, percentiles, averages, error rate, and throughput, with definitions aligned to the [glossary](/user-manual/glossary/) and report generator properties. ## Core metrics (grounded definitions) ### Elapsed time (response time) From the [glossary](/user-manual/glossary/): elapsed time is from just before sending the request to just after the last response byte is received. It does not include client-side rendering or browser JavaScript execution. ### Latency Time to the **first** response byte (glossary). Useful alongside elapsed for distinguishing slow servers from large payloads. ### Connect time Time to establish the connection including SSL handshake where measured (glossary; available for certain samplers). ### Throughput Requests per unit time over the full test window (glossary). High throughput with high errors is not success. ### Median and percentiles - **Median**: 50th percentile (glossary). - **Percentile (e.g. 90th)**: value below which that percentage of samples fall (glossary). Averages hide long tails. SLOs usually use **percentiles** (p95/p99), not only mean. ### Error percentage Failed samples / samples. Failures include assertion failures and transport errors depending on how the sample is marked. Without assertions, HTTP 500 HTML pages may still count as successful samples. ## What is APDEX? [APDEX](https://en.wikipedia.org/wiki/Apdex) (Application Performance Index) scores user satisfaction from response times against two thresholds: - **Satisfied** if response time ≤ T - **Tolerating** if T < time ≤ 4T (classic definition uses F = 4T; JMeter configures satisfied and tolerated thresholds explicitly) - **Frustrated** if above the tolerated threshold or failed (see how your report classifies errors) JMeter’s dashboard includes an APDEX table “based on configurable values for tolerated and satisfied thresholds” ([generating dashboard](/user-manual/generating-dashboard/)). ### Default JMeter report thresholds From report generator properties (also in [properties reference](/user-manual/properties-reference/)): | Property | Default | |----------|---------| | `jmeter.reportgenerator.apdex_satisfied_threshold` | **500** ms | | `jmeter.reportgenerator.apdex_tolerated_threshold` | **1500** ms | Override in `user.properties` (do not rely only on editing stock files long-term; copy overrides per best practices style). ### Per-transaction APDEX `jmeter.reportgenerator.apdex_per_transaction` sets per-sample thresholds: ```text sample_name:satisfaction|tolerance; ``` Values in milliseconds; regex sample names supported as documented in the dashboard chapter. ## Percentiles in the JMeter dashboard The statistics table includes configurable percentiles. Related properties: | Property | Default percentile | |----------|--------------------| | `aggregate_rpt_pct1` | 90 | | `aggregate_rpt_pct2` | 95 | | `aggregate_rpt_pct3` | 99 | `statistic_window` controls sliding window size for percentile evaluation (default 20000); higher is more accurate but uses more memory ([dashboard](/user-manual/generating-dashboard/)). ## Mapping SLOs to JMeter Example product SLO language: > 99% of checkout requests succeed in under 750 ms over a rolling 30 days. Load-test translation for a pre-prod experiment: | SLO piece | JMeter expression | |-----------|-------------------| | Success | Error % for label `Checkout` ≤ 1% (or stricter) | | Latency | p99 (or pct3) for `Checkout` ≤ 750 ms | | Load shape | Threads/RPS that represent peak hour (document assumptions) | | Duration | Soak long enough for steady state (not only ramp) | Use **Transaction Controllers** with stable names so dashboard series match SLO names. ## Good vs bad targets | Weak target | Stronger target | |-------------|-----------------| | "Average under 1s" | "p95 under 1s and errors under 0.1%" | | One global threshold | Per-transaction thresholds (login vs report download) | | Spike only | Spike + soak | | Open GUI eyeballing | CLI report + CI gate | ## Configuring thresholds for a suite 1. Agree SLOs with product/SRE. 2. Set `apdex_satisfied_threshold` / `tolerated` to match T and frustrated boundary you chose. 3. Optionally set `apdex_per_transaction` for critical labels. 4. Set `aggregate_rpt_pct*` to the percentiles in your SLO (e.g. 95/99). 5. Filter noise with `series_filter` / sample filters so static assets do not dilute scores. 6. Generate report: `-e -o report/`. ## CI gates from report metrics After the dashboard is generated, parse statistics (e.g. `statistics.json` paths for your version) for: - `errorPct` - Mean or percentile fields for critical transactions See [CI/CD load testing](/topics/ci-cd-load-testing/). Gates should fail the build when SLOs are violated in the test environment, with clear caveats that pre-prod ≠ prod. ## Live metrics vs offline report | Path | Use | |------|-----| | HTML dashboard | Auditable artifact, APDEX table, error tables | | Backend Listener → Grafana | Live during long tests ([guide](/topics/grafana-influx-backend-listener/)) | Define SLOs once; both paths should use the same sampler labels. ## Coordinated omission and honest SLOs If the injector cannot keep up, latency percentiles look better than users experience. [Best practices](/user-manual/best-practices/) warn about coordinated omission when thread counts are wrong. Validate achieved throughput vs target ([CO tool](/tools/coordinated-omission/), [Thread Calculator](/tools/thread-calculator/)) before claiming SLO compliance from a test. ## Worked example 1. SLO: Search API p95 ≤ 300 ms, errors ≤ 0.5%, at 50 RPS. 2. Size threads from response time pilot ([calculator](/tools/thread-calculator/)). 3. Label sampler `Search`. 4. Assert HTTP 200 + JSON field present. 5. Run CLI 15+ minutes steady. 6. Report: check `Search` p95 and error %. 7. APDEX satisfied threshold set near 300 ms if you want APDEX aligned to that SLO. ## Related reading - [Generating dashboard](/user-manual/generating-dashboard/) - [Glossary](/user-manual/glossary/) - [CI/CD](/topics/ci-cd-load-testing/) - [Best practices](/user-manual/best-practices/) - [API load testing](/topics/api-load-testing/) ## Frequently asked questions ### What is APDEX in JMeter? A satisfaction score derived from response times versus configured satisfied and tolerated thresholds, shown in the HTML dashboard APDEX table. ### What are the default APDEX thresholds? 500 ms satisfied and 1500 ms tolerated unless you override reportgenerator properties. ### Why not use only average response time? Averages hide long tails. Users feel p95/p99. SLOs should specify percentiles and error rates. ### How do I change dashboard percentiles? Set `aggregate_rpt_pct1`, `pct2`, and `pct3` (defaults 90, 95, 99) in report configuration properties. ### Can APDEX thresholds differ per API? Yes, via `jmeter.reportgenerator.apdex_per_transaction` with sample names or regex, as documented in the dashboard chapter. ### Does a green APDEX mean production is safe? No. It means samples in **that test** met thresholds under **that** load model and environment. Combine with capacity planning and production monitoring. Write one SLO in percentile + error form, map it to a sampler label, and configure matching APDEX or percentile properties before your next CLI run. - [Dashboard report](/user-manual/generating-dashboard/) - [Glossary](/user-manual/glossary/) - [CI/CD Load Testing](/topics/ci-cd-load-testing/) --- Title: Customizing JMeter HTML Dashboard Reports URL: https://docs.jmeter.ai/topics/html-dashboard-report-customization/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # Customizing JMeter HTML Dashboard Reports Apache JMeter includes a built-in **HTML Dashboard Generator** that transforms raw JTL/CSV execution logs into responsive, interactive web dashboards featuring APDEX ratings, response time percentiles, throughput curves, and error breakdowns. While the default report is functional, performance engineers can customize APDEX satisfaction thresholds per transaction, filter internal samplers, adjust percentile granularities (p90, p95, p99), and customize report titles. This guide explains how to customize your HTML dashboard generator via `user.properties` and CLI arguments. --- ## 1. Generating the Dashboard (CLI Quick Reference) ### Option A: Generate Automatically at the End of a Test ```bash jmeter -n -t plan.jmx -l results.jtl -e -o ./report/ ``` *(The output folder `./report/` must be completely empty or non-existent).* ### Option B: Generate from an Existing JTL File ```bash jmeter -g results.jtl -o ./report/ ``` --- ## 2. Customizing APDEX Thresholds per Transaction By default, JMeter uses a global APDEX satisfied threshold (T) of 500 ms and tolerated threshold (F) of 1500 ms: - **Satisfied**: Response time `≤ T` - **Tolerating**: Response time between T and F (`T < response time ≤ F`) - **Frustrated**: Response time `> F` or the request failed In real applications, lightweight static requests should have T = 100 ms, while heavy database reports may tolerate T = 3000 ms. In `bin/user.properties` (or passed via `-J`): ```properties # Global default APDEX thresholds (in milliseconds) jmeter.reportgenerator.apdex_satisfied_threshold=500 jmeter.reportgenerator.apdex_tolerated_threshold=1500 # Per-Transaction custom APDEX override (using regex sample name matching) jmeter.reportgenerator.apdex_per_transaction=^(Login|AuthToken)$:200,600;\ ^(Checkout_Payment)$:1000,3000;\ ^(Download_Report)$:5000,15000 ``` --- ## 3. Filtering Samplers with Regex If your test plan contains health checks, debug requests, or token preparation calls that should not skew executive reporting metrics, filter them using regular expressions: ```properties # Include only samplers matching pattern jmeter.reportgenerator.exporter.html.series_filter=^(TC_|API_).* # Exclude specific internal steps jmeter.reportgenerator.exporter.html.series_filter=^(?!Debug_|Health_).*$ ``` --- ## 4. Adjusting Response Time Percentiles By default, the dashboard displays 90th, 95th, and 99th percentiles in summary tables and charts. You can adjust these buckets in `user.properties`: ```properties # Custom percentile values (e.g. 50th, 90th, 99.9th) jmeter.reportgenerator.statistic.percentiles=50,90,95,99,99.9 # Custom graph granulatity (in milliseconds) - default is 60000ms (1 minute) jmeter.reportgenerator.overall_granularity=10000 ``` *(Setting granularity to `10000` (10 seconds) provides higher-resolution time-series response time and throughput graphs).* --- ## 5. Customizing Dashboard Title & Branding You can change the header title displayed on the generated web report: ```properties # Custom report title in top navigation bar jmeter.reportgenerator.report_title=Acme Core Banking API - Performance Benchmark ``` ### Passing Custom Report Properties on the CLI: ```bash jmeter -n -t plan.jmx -l results.jtl -e -o ./report/ \ -Jjmeter.reportgenerator.report_title="Nightly Build Regression Report" \ -Jjmeter.reportgenerator.overall_granularity=15000 ``` --- ## 6. Dashboard Generator Best Practices 1. **Keep Transaction Names Clean**: Avoid dynamic URL parameters in sampler names (e.g., use `/api/users/{id}` instead of `/api/users/12345`). Dynamic names create thousands of distinct rows in the dashboard table, bloating HTML file size. 2. **Never Run with Full XML Logging**: Ensure results are saved as CSV format (`jmeter.save.saveservice.output_format=csv`) to allow fast parsing by the report generator. 3. **Use Transaction Controllers**: Check **"Generate parent sample"** so composite business transactions appear as single unified rows in APDEX and summary tables. Configure custom APDEX thresholds in `user.properties` and generate an updated HTML dashboard report with `jmeter -g results.jtl -o ./report/`. - [APDEX, SLOs & Percentiles](/topics/apdex-slo-percentiles/) - [Dashboard Generation Manual](/user-manual/generating-dashboard/) - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - [Grafana / Influx / Backend Listener](/topics/grafana-influx-backend-listener/) Attempting to output to an existing, non-empty directory (JMeter will throw an exception and abort); generating reports from XML log files instead of CSV. If report generation fails with `File results.jtl is empty`, verify that tests executed samplers and that saveservice properties conform to standard CSV columns. --- Title: JMeter Docker and Kubernetes URL: https://docs.jmeter.ai/topics/docker-kubernetes/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Docker and Kubernetes Teams run JMeter in containers for CI, ephemeral injectors, and scaled workers. Apache JMeter itself is a Java application started with documented CLI flags (`jmeter -n -t ...`); containers wrap that binary, JVM heap, plugins, and filesystem mounts. This guide stays grounded in official CLI, properties, distributed testing, and best practices, plus practical container patterns (including the community image `qainsights/jmeter` used on this site’s CI examples). :::caution[Not an official Apache image] Container images on Docker Hub are **community or vendor** builds unless Apache publishes one you explicitly trust. Pin digests, scan images, and verify the JMeter version inside matches your plans and plugins. ::: ## Why containers help - Reproducible JMeter + Java + plugin set - Easy CI ([CI/CD guide](/topics/ci-cd-load-testing/)) - Scale injectors as Jobs/Deployments - Isolate heap and CPU with cgroup limits Containers do not remove the need for correct thread sizing, lean listeners, or honest test data ([best practices](/user-manual/best-practices/)). ## Non-GUI is mandatory Inside containers there is typically no display. Always: ```bash jmeter -n -t /plans/test.jmx -l /out/results.jtl -e -o /out/report -j /out/jmeter.log ``` | Flag | Container note | |------|----------------| | `-n` | Required headless | | `-t` | Path **inside** the container | | `-l` / `-e` / `-o` | Write to a **mounted** volume so the host/CI keeps artifacts | | `-J` / `-q` | Inject environment-specific properties | | `-r` / `-R` | Distributed workers ([remote testing](/topics/distributed-testing/)) | Official lean form also appears in best practices: `jmeter -n -t test.jmx -l test.jtl`. ## Docker: minimal pattern ### Mount plan and output ```bash docker run --rm \ -v "\${PWD}/tests:/plans" \ -v "\${PWD}/jmeter-out:/out" \ qainsights/jmeter:5.6 \ -n -t /plans/api.jmx \ -Jthreads=20 -Jrampup=40 -Jhost=staging.example.com \ -l /out/results.jtl \ -e -o /out/report \ -j /out/jmeter.log ``` Ensure `/out/report` does not already contain a previous dashboard (generator expects a suitable empty/new output dir). ### Heap and JVM JMeter scripts honor heap-related environment variables (`HEAP`, `JVM_ARGS` depending on packaging). Size for threads, response size, and listeners ([Heap Estimator](/tools/heap-estimator/)). Align container memory limits **above** `-Xmx` or the JVM will be OOM-killed by cgroups. ### Plugins in images Bake Plugins Manager installs into a derived Dockerfile, or copy `lib/ext` JARs. Distributed workers need the **same** plugins ([distributed testing](/topics/distributed-testing/)). ### User and filesystem Run as non-root when your image supports it; ensure mounted volumes are writable for JTL/report/log. ## CI example (GitHub Actions) From the [CI/CD topic](/topics/ci-cd-load-testing/) pattern: ```yaml - name: Run JMeter run: | mkdir -p jmeter-out docker run --rm \ -v "\${{ github.workspace }}:/work" \ -w /work \ qainsights/jmeter:5.6 \ -n -t tests/load/api.jmx \ -Jthreads=15 -Jhost=\${{ vars.STAGING_HOST }} \ -l jmeter-out/results.jtl \ -e -o jmeter-out/report \ -j jmeter-out/jmeter.log ``` Archive `jmeter-out/` always; gate on dashboard statistics when ready. ## Kubernetes patterns ### Job for a one-shot test ```yaml apiVersion: batch/v1 kind: Job metadata: name: jmeter-smoke spec: backoffLimit: 0 template: spec: restartPolicy: Never containers: - name: jmeter image: qainsights/jmeter:5.6 args: - -n - -t - /plans/api.jmx - -Jthreads=10 - -l - /out/results.jtl - -e - -o - /out/report resources: requests: cpu: "1" memory: 2Gi limits: cpu: "2" memory: 2Gi volumeMounts: - name: plans mountPath: /plans - name: out mountPath: /out volumes: - name: plans configMap: name: jmeter-plans - name: out emptyDir: {} ``` Copy results out with a sidecar, `kubectl cp`, or ship to object storage in an exit script. For durable artifacts, use PVC or upload steps. ### ConfigMaps and secrets - Plans without secrets: ConfigMap or git-synced volume - Hosts and client secrets: Kubernetes Secrets → env → `-J` or templated properties file - Prefer `\${__P}` in the plan ([functions](/topics/functions-and-variables/)) ### Resource isolation JMeter is CPU- and memory-sensitive under many threads. Set requests/limits deliberately. Noisy-neighbor shared nodes distort load generation; use dedicated node pools for serious tests. ### Network Pods must reach the system under test. NetworkPolicies, private DNS, and egress rules often break first-time K8s load tests. Smoke with `curl` from an ephemeral pod before blaming JMeter. ## Distributed JMeter on K8s Official remote mode: workers run `jmeter-server`, controller uses `-R` ([remote testing](/user-manual/remote-test/)). Container caveats: 1. **Same JMeter + Java + plugins** on all pods. 2. **RMI/SSL** since JMeter 4.0 defaults to SSL; distribute keystores or lab-only disable carefully. 3. **Ports**: registry (often 1099), `server.rmi.localport`, reverse `client.rmi.localport` range must be allowed between pods. 4. **CSV data files are not auto-copied** to workers; mount shared volume or identical images with data. 5. Headless controller: `jmeter -n -t plan.jmx -R worker1,worker2 -l ...`. Alternative: **N independent Jobs** each running full CLI load with split CSV slices, then merge JTLs offline (also mentioned as a multi-instance approach in best practices). Simpler networking than RMI. ## Backend Listener from containers If you stream to Influx ([Grafana topic](/topics/grafana-influx-backend-listener/)), ensure pods can reach Influx/Grafana URLs and that cardinality stays low. Do not point production Influx at unbounded unique sampler labels. ## Image hygiene checklist 1. Pin tag **and** digest for release gates. 2. Record JMeter version in the report title or CI log. 3. Include only needed plugins. 4. Scan for CVEs. 5. Fail CI if `jmeter -v` mismatches expected version. ## Common failures | Symptom | Cause | Fix | |---------|-------|-----| | Report missing on host | Forgot volume mount | Mount `/out` | | Permission denied | Non-writable mount | Fix ownership/fsGroup | | OOMKilled | Limit < heap or too many threads | Raise limit or lower threads | | Connection refused to SUT | K8s network | DNS/NetworkPolicy | | Plugin class missing | Image without plugin | Bake JARs | | RMI failures | Ports/SSL | Align with remote testing guide | ## Related reading - [CI/CD load testing](/topics/ci-cd-load-testing/) - [Distributed testing](/topics/distributed-testing/) - [Best practices](/user-manual/best-practices/) - [Heap estimator](/tools/heap-estimator/) - [Properties cheat sheet](/tools/properties-cheatsheet/) ## Frequently asked questions ### Is there an official Apache JMeter Docker image? Treat public images as community/vendor unless you verify Apache provenance. Prefer pinned, scanned images your team controls. ### What is the essential CLI inside a container? `jmeter -n -t plan.jmx -l results.jtl` plus `-e -o report/` when you need the HTML dashboard artifact. ### How do I pass threads and host into a containerized plan? Use `\${__P(threads,10)}` in the plan and docker/K8s args `-Jthreads=50 -Jhost=...`. ### Can I run the JMeter GUI in Docker? Possible with X11/VNC images, but load tests should be non-GUI. Use GUI locally for authoring. ### How do I get reports out of Kubernetes? Mount a PVC, upload to object storage at job end, or `kubectl cp` from the pod before it is deleted. ### Do distributed workers work on Kubernetes? Yes if RMI ports, SSL keystores, identical software, and data mounts are correct. Many teams prefer multiple independent CLI jobs to avoid RMI complexity. Run one dockerized smoke against staging with mounted report output, then add the same command to CI. - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - [Distributed Testing](/topics/distributed-testing/) - [Remote Testing manual](/user-manual/remote-test/) GUI mode in containers; no volume for reports; memory limit below -Xmx; different plugins on different workers. --- Title: JMeter CI/CD Load Testing URL: https://docs.jmeter.ai/topics/ci-cd-load-testing/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter CI/CD Load Testing Integrating Apache JMeter into CI/CD means every relevant change can run a **non-GUI** performance check, publish an HTML report, and optionally **fail the build** when error rate or latency regresses. This guide covers CLI fundamentals, parameterization, dashboard artifacts, performance gates, pipeline patterns (GitHub Actions, Jenkins, generic Docker), data and secrets, and operational pitfalls - aligned with JMeter’s documented CLI flags, properties, best practices, and [dashboard generator](/user-manual/generating-dashboard/). :::tip[Use CLI mode for real load] CI jobs should run JMeter in non-GUI mode and archive the `.jtl` plus generated dashboard report. Keep the GUI out of automated load stages. ::: :::caution[Timeout the process] Always set a job-level timeout around JMeter. A stuck thread group or unreachable host can block an agent indefinitely if the pipeline never cancels the step. ::: ## Why put JMeter in the pipeline? Manual GUI runs do not scale across branches and pull requests. CI integration gives you: - **Repeatability** - same `.jmx`, same CLI flags, same report shape - **Regression detection** - compare error % and percentiles to thresholds - **Artifacts** - HTML dashboard and raw CSV/JTL for later analysis - **Shift-left performance** - catch obvious degradations before production CI is not a replacement for full-scale capacity tests in a dedicated environment. Most pipelines run a **smaller, time-boxed** scenario (smoke or nightly load) because shared runners have limited CPU, memory, and network, and test environments may not match production scale. ## Prerequisites 1. A stable test plan that already works under CLI on a developer machine. 2. JMeter available on the agent (installed package, versioned tarball, or container image). 3. Plan and data files in version control (or fetched as build inputs). 4. Agreement on **what “fail” means** (error %, p95, APDEX thresholds in the report config, etc.). Read [Best Practices](/user-manual/best-practices/) before automating: CLI mode, minimal listeners, CSV results, and property-based parameterization are the foundation of reliable CI runs. ## Non-GUI mode: the only mode for CI ### Core command ```bash jmeter -n -t test-plan.jmx -l results.jtl -e -o report/ ``` | Flag | Role in CI | |------|------------| | `-n` | Non-GUI (required for automation) | | `-t` | Path to the `.jmx` test plan | | `-l` | Sample log path (results file) | | `-e` | Generate HTML dashboard after the test | | `-o` | Dashboard output directory (**must not already exist** as a non-empty report dir - use a clean path per run) | | `-j` | JMeter log file path (optional but useful on agents) | | `-q` | Extra property file(s) | | `-Jname=value` | Define JMeter property `name` | | `-Gname=value` | Define property on remote servers when using distributed mode | | `-r` / `-R` | Remote/distributed engines ([distributed testing](/topics/distributed-testing/)) | Official [best practices](/user-manual/best-practices/) show the lean form: ```bash jmeter -n -t test.jmx -l test.jtl ``` Adding `-e -o report/` is the standard way to attach human-readable results to a build. Use the [CLI command builder](/tools/cli-builder/) to assemble `-n`/`-t`/`-l`, the dashboard flags, `HEAP`, and `-J` properties without guessing. ### Exit codes and sample failures By default, JMeter finishing the test plan is not the same as “all samples succeeded.” Failed assertions and HTTP errors are recorded in the result file and dashboard **error** metrics. Your gate script (or a plugin) must inspect those metrics if you want the pipeline to go red. Do not assume a zero process exit code always means zero business errors without verifying behaviour for your JMeter version and wrappers. ### Headless agent requirements - A compatible **Java** runtime for your JMeter release. - Enough **heap** for the thread count (`HEAP` / `JVM_ARGS` as used by JMeter startup scripts). See the [Heap Estimator](/tools/heap-estimator/). - No reliance on GUI-only features. - Writable workspace for `-l`, `-o`, and logs. ## Parameterizing plans for every environment Hard-coding hostnames and thread counts in XML forces a commit for every environment. Official parameterization guidance ([best practices](/user-manual/best-practices/)): 1. Define Test Plan variables from properties, for example `LOOPS=\${__P(loops,10)}`. 2. Override on the CLI: `jmeter … -Jloops=12`. 3. For many related settings, use property files and `-q`. ### Recommended property surface for CI | Property | Typical use | |----------|-------------| | `host` / `port` / `protocol` | Environment under test | | `threads` | Concurrent users for this pipeline tier | | `rampup` | Seconds to start all threads | | `duration` or loop count | How long the stage runs | | `usersFile` | Path to CSV data on the agent | In the plan: ```text \${__P(threads,5)} \${__P(rampup,30)} \${__P(host,localhost)} ``` Pipeline example: ```bash jmeter -n -t tests/load/api.jmx \ -Jthreads=20 \ -Jrampup=40 \ -Jhost=staging.example.com \ -l target/jmeter/results.jtl \ -e -o target/jmeter/report \ -j target/jmeter/jmeter.log ``` Use **small** defaults in the `.jmx` so a developer double-click or accidental run is safe; let CI inject larger values only on dedicated jobs. ## Dashboard reports as build artifacts The [dashboard generator](/user-manual/generating-dashboard/) processes CSV sample results into HTML graphs and tables: - APDEX (satisfied/tolerated thresholds configurable) - Statistics table with configurable percentiles - Error summary and top errors by sampler - Time-series charts (response times, active threads, throughput, and more) ### Configuration that CI should pin Documented defaults for saveservice fields must remain intact so the generator has the columns it needs (label, latency, response code, success, thread counts, bytes, etc.). If someone customized `jmeter.save.saveservice.*` in `user.properties`, restore the required fields or the report may be incomplete. Customize report behaviour via **copies of properties in `user.properties`** (not by editing packaged defaults alone). Examples from the dashboard docs: - `jmeter.reportgenerator.apdex_satisfied_threshold` (default 500 ms) - `jmeter.reportgenerator.apdex_tolerated_threshold` (default 1500 ms) - `jmeter.reportgenerator.exporter.html.series_filter` to keep only chosen transactions ### What to archive | Artifact | Why | |----------|-----| | `report/` (HTML) | Primary human review in CI UI | | `results.jtl` / CSV | Re-generate report offline; long-term compare | | `jmeter.log` | Diagnose agent/plan failures | | Property file used (`-q`) | Reproducibility | Upload these with your CI “artifacts” feature and retain them on failed runs especially. ## Performance gates (fail the build) A useful gate is **simple, stable, and aligned with SLOs**. ### Metrics people gate on From dashboard statistics and result files: - **Error percentage** (failed samples / samples) - **Mean or percentile response time** (p90/p95/p99 as exported in the statistics table) - **APDEX** (if you configure thresholds deliberately for the environment) - **Minimum throughput** (catch “test did not actually apply load”) ### Example: parse dashboard `statistics.json` The HTML report generation also writes machine-readable statistics (commonly `statistics.json` next to the HTML). Field names can vary slightly by JMeter version - **inspect the file your version produces** and adjust paths. A typical pattern: ```bash # Example gate - verify JSON paths against your JMeter version's statistics.json ERROR_PCT=$(jq -r '.Total.errorPct' report/statistics.json) MEAN_RT=$(jq -r '.Total.meanResTime' report/statistics.json) # errorPct is a percentage value in the statistics file (confirm scale in your file) if awk "BEGIN {exit !($ERROR_PCT > 1)}"; then echo "FAIL: error percentage $ERROR_PCT exceeds 1" exit 1 fi if awk "BEGIN {exit !($MEAN_RT > 500)}"; then echo "FAIL: mean response time $MEAN_RT ms exceeds 500" exit 1 fi echo "PASS: errorPct=$ERROR_PCT meanResTime=$MEAN_RT" ``` If `jq` paths differ in your version, gate on CSV aggregates or a small script that reads the JTL instead - but keep the gate deterministic. ### Tiered quality bars | Pipeline tier | Threads / duration | Gate strictness | |---------------|--------------------|-----------------| | PR smoke | Low threads, 1-2 minutes | Fail on high error % only | | Nightly | Medium load, longer | Error % + p95 | | Pre-release | Closer to prod target | Full SLO set + report review | Use `\${__P(...)}` so one plan serves all tiers. ## GitHub Actions pattern Illustrative workflow step using the [qainsights/jmeter](https://hub.docker.com/r/qainsights/jmeter) image (pin the tag your team standardizes on; this is a community image, not an official Apache release): ```yaml jobs: load: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Run JMeter run: | mkdir -p jmeter-out docker run --rm \ -v "\${{ github.workspace }}:/work" \ -w /work \ qainsights/jmeter:5.6 \ -n -t tests/load/api.jmx \ -Jthreads=15 -Jrampup=30 \ -Jhost=\${{ vars.STAGING_HOST }} \ -l jmeter-out/results.jtl \ -e -o jmeter-out/report \ -j jmeter-out/jmeter.log - name: Performance gate run: | # Adjust jq paths after inspecting jmeter-out/report/statistics.json ERROR_PCT=$(jq -r '.Total.errorPct' jmeter-out/report/statistics.json) awk "BEGIN {exit !($ERROR_PCT > 1)}" && { echo "errorPct $ERROR_PCT"; exit 1; } || true - name: Upload JMeter report if: always() uses: actions/upload-artifact@v4 with: name: jmeter-report path: jmeter-out/ ``` Notes: - `if: always()` on upload preserves reports for failed gates. - Prefer **repository variables/secrets** for hosts and credentials, not commits. - Pin image digests in production pipelines for reproducibility. ## Jenkins pattern Common approaches: 1. **Shell/batch build step** invoking `jmeter -n -t … -l … -e -o …` after installing JMeter on the agent or using a Docker agent. 2. **Pipeline `sh` step** with the same command inside `dir()` / workspace paths. 3. **Archive artifacts** (`report/**`, `*.jtl`, `jmeter.log`). 4. Optional community **Performance** plugins to plot historical trends - treat plugin config as team-specific; the CLI + HTML report path stays portable. Example declarative fragment: ```groovy stage('JMeter') { steps { sh ''' rm -rf jmeter-out && mkdir jmeter-out jmeter -n -t tests/load/api.jmx \ -Jthreads=\${THREADS} -Jhost=\${TARGET_HOST} \ -l jmeter-out/results.jtl \ -e -o jmeter-out/report \ -j jmeter-out/jmeter.log ''' // gate script here } post { always { archiveArtifacts artifacts: 'jmeter-out/**', fingerprint: true } } } ``` ## Generic Docker / Kubernetes runners Patterns that stay close to official CLI behaviour: - Mount the workspace; run the `jmeter` entrypoint with `-n -t …`. - Set `HEAP` or `JVM_ARGS` in the container environment for larger jobs. - Use a **dedicated** runner pool for load so you do not starve compile/test jobs. - For multi-engine load, prefer a controlled lab or [distributed mode](/topics/distributed-testing/) over uncontrolled shared CI workers. Distributed mode in CI is advanced: workers need network access, matching JMeter/Java versions, RMI/SSL setup, and data files present on each worker. Many teams instead run **one solid CLI engine** per job or several independent jobs that merge JTLs later. ## Test data, CSV files, and secrets ### CSV Data Set [Best practices](/user-manual/best-practices/) recommend CSV files for per-user credentials and large datasets. In CI: - Commit **non-sensitive** synthetic data, or - Generate CSV in a pre-step, or - Fetch from a secrets manager into the workspace at runtime Ensure paths in CSV Data Set Config work on the agent (relative paths from the working directory you set). ### Distributed caveat Remote testing docs state **data files are not automatically sent** to workers. For CI distributed runs, copy CSV/payloads to each engine or use a shared mount. ### Secrets - Pass tokens with `-J` from CI secret stores: `-JapiKey=$API_KEY`. - Reference `\${__P(apiKey,)}` in Header Managers. - Never log full command lines that echo secrets; prefer env-specific property files with restricted filesystem permissions. ## Plan design rules that make CI stable Aligned with official lean-test advice: 1. **No View Results Tree** (or any heavy listener) enabled in the committed plan for load jobs. 2. **CLI-first** - developers verify with `-n` before merging plan changes. 3. **Deterministic naming** - sampler labels stable so dashboard series and filters work. 4. **Transaction Controllers** for multi-step APIs so gates can target business transactions. 5. **Assertions** that define failure (status codes, key JSON fields) - without them error % stays near zero while responses are wrong. 6. **Timers** only when the scenario needs think time; document whether the CI tier is stress or paced load. 7. **Version pin** - same JMeter major/minor in CI as local; avoid “latest” floating tags for release gates. ## Scheduling strategies | Job | Purpose | |-----|---------| | On PR (optional path filter) | Smoke: tiny threads, short duration, fail on errors | | Nightly on main | Heavier load against staging | | Pre-deploy | Explicit approval + report link | | Post-deploy canary | Synthetic check (often smaller) | Separate **functional** API tests (correctness) from **load** stages so a performance environment outage does not block unit tests. ## Observability during CI runs For long nightly jobs, consider the [Backend Listener / real-time results](/user-manual/realtime-results/) path into InfluxDB/Grafana. Keep it optional: CI should still produce the static HTML dashboard as the auditable artifact. ## Troubleshooting CI-specific failures | Symptom | Likely cause | What to check | |---------|--------------|---------------| | Job hangs | No timeout; server wait; infinite loop | Job timeout; connect/response timeouts on HTTP Request | | Empty report / generator error | Bad saveservice config; non-empty `-o` dir | Clean output dir; required CSV columns | | Connection errors only in CI | Firewall DNS; wrong `\${__P(host)}` | Print non-secret effective host; curl from agent | | OOM on agent | Threads too high for runner size | Lower `-Jthreads`; raise heap; bigger runner | | Flaky p95 | Shared noisy staging | Dedicated env; longer ramp; median of multiple runs | | Passes CLI locally, fails CI | Path/CSV/cwd differences | Working directory; relative file paths | | “Green” build, broken API | No assertions / no gate | Add Response Assertion; parse statistics | ## Checklist: production-ready JMeter stage 1. Plan runs under `jmeter -n` locally with the same properties CI will use. 2. Listeners disabled; results via `-l`. 3. Hosts, threads, duration from `\${__P}` / `-J`. 4. Secrets from CI secret store. 5. Clean `-o` report directory per run. 6. Archive report + JTL + log always. 7. Gate on documented metrics with version-verified JSON/CSV paths. 8. Job timeout set. 9. JMeter and Java versions pinned. 10. README in `tests/load/` explains how to run the stage locally. ## Related reading on this site - [API Load Testing](/topics/api-load-testing/) - plan design for HTTP APIs - [Dashboard Report](/user-manual/generating-dashboard/) - APDEX and graphs - [Best Practices](/user-manual/best-practices/) - CLI and lean plans - [Functions and Variables](/topics/functions-and-variables/) - `\${__P}` and CSV - [Distributed Testing](/topics/distributed-testing/) - multi-engine scale - [Thread Calculator](/tools/thread-calculator/) - sizing before you burn CI minutes ## Frequently asked questions ### Can I run the JMeter GUI in CI? You should not. Official guidance is to use non-GUI mode for load tests. GUI mode wastes resources, is fragile on headless agents, and can hang without a display. ### What is the minimum CLI command for pipelines? `jmeter -n -t plan.jmx -l results.jtl` runs the test and writes results. Add `-e -o report/` to generate the HTML dashboard as a build artifact. ### How do I change thread count without editing the JMX? Define threads as `\${__P(threads,10)}` in the Thread Group and pass `-Jthreads=50` on the CI command line (documented parameterization pattern). ### How do I fail the build on performance regressions? Generate the dashboard, then script a check on error percentage and/or response-time statistics from the report output or JTL. JMeter recording errors alone does not always fail the process - your gate must enforce policy. ### Should load tests run on every commit? Usually no. Use a short smoke on PR when needed, and heavier jobs on a schedule or pre-release pipeline. Full-scale tests belong in environments sized for them. ### Where should I store the HTML report? As a CI artifact attached to the build (and optionally published to an internal static site). Keep the raw `.jtl` when you may need offline regeneration. ### Can Jenkins and GitHub Actions share the same plan? Yes if both invoke the same CLI contract: same JMeter version, properties, and paths. The portable core is the `.jmx` + `jmeter -n …` command, not a vendor-specific plugin. Add a non-GUI step and archive `report/` on your next pipeline change; then add a single error-percentage gate once `statistics.json` paths are verified for your JMeter version. - [Dashboard Report](/user-manual/generating-dashboard/) - configure APDEX thresholds in user.properties - [Best Practices](/user-manual/best-practices/) - CLI mode, listeners, parameterization - [API Load Testing](/topics/api-load-testing/) - assertions and correlation for meaningful gates Running GUI mode in CI; no job timeout; committing secrets in JMX; gating on flaky shared environments without error-rate floors; floating “latest” JMeter images for release gates. Report generation failures: ensure CSV saveservice fields required by the dashboard are enabled and `-o` points to a fresh directory. Connection failures: verify `-Jhost` and agent egress to the system under test. --- Title: JMeter Distributed Testing Guide URL: https://docs.jmeter.ai/topics/distributed-testing/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Distributed Testing Guide When a single injector cannot generate enough load - or is limited by network or CPU - JMeter can drive **multiple remote engines** from one client. This guide explains the controller-worker model, setup steps, CLI usage, SSL/RMI, data files, result collection, limits, and troubleshooting, grounded in the official [Remote Testing](/user-manual/remote-test/) manual and the [step-by-step tutorial](/user-manual/jmeter-distributed-testing-step-by-step/). :::caution[Security-sensitive setting] Distributed testing uses RMI between the controller and workers. Only run it on trusted networks with explicit firewall rules, matching JMeter versions, and a deliberate SSL/RMI configuration. ::: :::note[Version-specific behavior] Remote startup, RMI defaults, and SSL behaviour can change between JMeter releases. Keep controller and workers on the same JMeter and Java versions. Since JMeter 4.0, RMI transport defaults to SSL and you must provision keys (or consciously disable SSL in non-production lab setups only). ::: ## How distributed testing works JMeter uses a **controller (client) + workers (servers)** architecture (historically called master/slave): | Role | Responsibility | |------|----------------| | **Controller / client** | Holds the test plan start command, sends the plan to workers, starts/stops the test, **collects sample results**, writes the combined result file locally | | **Worker / server** | Runs `jmeter-server`, executes the **full** test plan, streams results back | Documented features of remote mode: - Saving of test samples to the **local** (controller) machine - Management of multiple JMeter engines from one machine - **No need to copy the test plan** to each server - the client sends it ### Critical load math From the official remote testing chapter: > The same test plan is run by all the servers. **JMeter does not distribute the load between servers**; each runs the full test plan. So if you set 1000 Threads and have 6 JMeter servers, you end up injecting **6000 Threads**. Plan thread counts **per worker**, not as a global pool that JMeter will shard for you. ### When not to use remote mode The manual notes that remote mode uses **more resources** than running the same number of independent CLI tests. With many servers, the **client** and its network can become overloaded even though workers still run. Always verify the controller is healthy. Also: do **not** run the JMeter engine on the application server under test if you can avoid it - the engine steals CPU and taints results. Prefer injectors on the **same Ethernet segment** as the app tier without sharing the app hosts. ## Prerequisites (all nodes) Official checklist - every client and server must: 1. Run **exactly the same version of JMeter**. 2. Use the **same Java version** on all systems (mixed versions may work but are discouraged). 3. Have a **valid keystore for RMI over SSL**, or SSL explicitly disabled in a controlled lab. 4. Be reachable on the RMI ports you configure (firewalls allowing client→server and reverse result channels). ### Data files are not auto-copied If the plan uses CSV files, plugins JARs, or other external resources: > these are **not sent across by the client** - make sure they are available in the **appropriate directory on each server**. You may use different `user.properties` / `system.properties` per server (for example unique data partitions or different backend targets). Properties are picked up when the server starts. ## Network and ports | Direction | Purpose | Notes from docs | |-----------|---------|-----------------| | Client → server | Control / RMI | Default registry port **1099** (typical) | | Server → client | Sample results | High-numbered ports; control with `client.rmi.localport` base | | Server local engine port | RMI engine | Dynamic by default; set `server.rmi.localport` for firewall-friendly fixed ports | If firewalls exist between client and servers, allow the chosen ports both ways as required for RMI. The manual suggests monitoring traffic if connections fail. There can be **only one JMeter server per node** unless you use different RMI ports. ## Step-by-step setup Follow the [Distributed Testing Step-by-Step](/user-manual/jmeter-distributed-testing-step-by-step/) tutorial for screenshots, or the full [Remote Testing](/user-manual/remote-test/) reference. ### Step 0 - Configure nodes - Identical JMeter + Java - SSL keystore distributed **or** intentional SSL disable for lab only - CSV/plugin files present on workers - Optional: set `server.rmi.localport` on servers for fixed ports ### Step 1 - Start workers On each worker machine: ```bash # Unix jmeter-server # Windows jmeter-server.bat ``` The server application **starts the RMI registry itself**; you normally do not start `rmiregistry` separately. (Older manual mode with `server.rmi.create=false` exists for special cases - see remote testing “Doing it Manually”.) Optional: `server.exitaftertest=true` so the server exits after one test. The client `-X` flag also requests remote servers to exit at end of test. ### Step 2 - Point the client at workers **Option A - properties file** on the controller: set `remote_hosts` in `jmeter.properties` / overrides to a comma-separated list of worker hosts. **Option B - CLI** (preferred for automation): ```bash jmeter -n -t script.jmx -R host1,host2,host3 -l results.jtl ``` Documented equivalence: `-R` has the same effect as using `-r` with `-Jremote_hosts={serverlist}`. ```bash jmeter -n -t script.jmx -r ``` uses whatever is already in `remote_hosts`. ### Step 3a - GUI check (debug only) Start the controller GUI; **Run** menu includes **Remote Start** / **Remote Stop** for configured hosts. Use this only to validate connectivity - not for real load. ### Step 3b - CLI client (recommended) ```bash jmeter -n -t script.jmx -R server1,server2 -l results.jtl -e -o report/ ``` Useful flags from the manual: | Flag | Meaning | |------|---------| | `-Gproperty=value` | Define a property on **all** servers (repeatable) | | `-X` | Exit remote servers at the end of the test | | `-Jproperty=value` | Property on the **client** (and as usual for plan `\${__P}`) | The command-line client exits when remote servers have stopped. ## SSL for RMI (default since JMeter 4.0) Since JMeter 4.0 the default RMI transport uses **SSL**. You must create keys/certificates. JMeter ships: - `bin/create-rmi-keystore.sh` - `bin/create-rmi-keystore.bat` Run from `bin`; the script generates a keystore with a key named `rmi` (default alias), **valid seven days** in the documented sample flow, default passphrase `changeit`. Answer the keytool prompts (CN should align with alias expectations; docs show using `rmi` as the name). Then: 1. Ensure `rmi_keystore.jks` is in `jmeter/bin` or referenced by `server.rmi.ssl.keystore.file`. 2. **Copy the same keystore to every server and client** in the farm. Default RMI SSL-related properties are described under the [properties reference](/user-manual/properties-reference/) remote section. ### Lab-only SSL disable Some teams temporarily set `server.rmi.ssl.disable=true` in `user.properties` on all nodes for isolated labs. Treat that as **non-production only**; prefer proper keystores for any shared or long-lived environment. ## What the controller aggregates Workers execute samples; results stream back so the controller can: - Write a **combined** result file (`-l`) - Drive listeners in GUI (not recommended under load) - Produce one [HTML dashboard](/user-manual/generating-dashboard/) from the combined log The dashboard docs note a limitation on the “times vs threads” graph in distributed mode (axis reflects threads for one server - see generating-dashboard notes). ### Stripped modes The remote testing manual mentions improvements via **Stripped** sample sending modes to reduce client overload. Prefer current defaults for your version, and still watch controller CPU, disk, and network when many workers send high-rate results. ## Sizing workers and threads 1. Decide **total** target concurrency or RPS. 2. Decide how many injectors you have. 3. Set Thread Group threads ≈ **total / workers** (plus headroom), remembering each worker runs the full group. 4. Size **heap per worker** for its local thread count ([Heap Estimator](/tools/heap-estimator/)). 5. Size the **controller** for result aggregation, not only for zero local threads. 6. Use the [Thread Calculator](/tools/thread-calculator/) for per-engine starting points; validate with pilots. [Best practices](/user-manual/best-practices/) also allow multiple **autonomous** CLI instances without remote mode: run N independent `jmeter -n` processes and **merge sample result files** later for analysis. That avoids RMI complexity when you do not need centralized start/stop. ## Properties that commonly matter Configure overrides in `user.properties` (recommended pattern: copy from `jmeter.properties`, do not edit only the stock file long-term): | Area | Examples (see properties reference for exact names) | |------|-----------------------------------------------------| | Host list | `remote_hosts` | | Server RMI port | `server.rmi.localport` | | Client reverse ports | `client.rmi.localport` | | SSL keystore | `server.rmi.ssl.keystore.file`, alias, password props | | SSL disable | `server.rmi.ssl.disable` (lab) | | Exit after test | `server.exitaftertest` | Unsure which knobs matter? Use the [Properties Cheat Sheet](/tools/properties-cheatsheet/) and the full [Properties Reference](/user-manual/properties-reference/). ## Operational runbook ### Healthy start order 1. Deploy identical JMeter/Java to all nodes. 2. Deploy keystore + data files to workers. 3. Start `jmeter-server` on each worker; confirm logs show RMI up. 4. From controller, start CLI with `-R` and a **small** thread count. 5. Confirm samples arrive in the result file. 6. Scale threads/workers gradually. ### During the test - Watch worker CPU, network, GC. - Watch controller disk I/O for the JTL. - Prefer [Backend Listener](/user-manual/realtime-results/) for live metrics if you need dashboards mid-test. - Avoid View Results Tree on the controller under load. ### After the test - Generate dashboard from the controller’s result file. - Use `-X` or `server.exitaftertest` if you want workers to shut down. - Collect `jmeter-server` logs from workers if anything failed. ## Troubleshooting | Problem | What to check | |---------|----------------| | Connection refused | `jmeter-server` running? host/IP correct? firewall on 1099 / `server.rmi.localport`? | | Workers not listed / not starting | `remote_hosts` / `-R` list; DNS resolution; ping/route | | Serialization / class errors | Identical JMeter versions; same plugins on all nodes | | SSL handshake failures | Keystore present on all nodes; alias/password; clocks; or lab SSL disable consistently | | No samples / incomplete results | Reverse ports blocked (`client.rmi.localport` range); client overloaded | | Different behaviour per worker | Missing CSV on some nodes; different `user.properties` | | Controller overloaded | Too many workers/high sample rate; use stripped modes; fewer result fields; autonomous CLI merge strategy | | “Unknown host” / wrong interface | Bind addresses, multi-homed hosts, VPN interfaces | Debugging tips from the manual include RMI-related system properties for verbose RMI logs when diagnosing refused connections. ## Distributed testing vs alternatives | Approach | Pros | Cons | |----------|------|------| | **Remote mode (`-R`)** | One start/stop; combined results; plan pushed to workers | RMI/SSL complexity; client bottleneck | | **Independent CLI engines** | Simple; no RMI | Manual start; merge JTLs yourself | | **Single powerful injector** | Simplest | Hardware/network ceiling | | **CI single container** | Easy automation | Limited scale ([CI guide](/topics/ci-cd-load-testing/)) | Choose remote mode when you need **central coordination** and many injectors; choose autonomous CLIs when you want operational simplicity. ## Security checklist 1. Trusted network or strict firewall allowlists only. 2. SSL keystores with controlled distribution; rotate when using short-lived certs (documented sample validity is short - regenerate for real use). 3. No `jmeter-server` exposed to the public internet. 4. Test plans treated as code - remote start executes what the client sends. 5. Disable experimental SSL-off settings outside labs. ## Result file and sample sending behaviour Under load, workers generate samples quickly. The controller must: 1. Receive sample events over RMI. 2. Write them to the local result file if `-l` is set. 3. Optionally feed listeners or Backend Listener exporters. That is why the remote testing chapter warns that the **client** can become the bottleneck. Mitigations aligned with official guidance and lean-run practice: - Prefer **CLI** controller with listeners disabled. - Save only required fields (`jmeter.save.saveservice.*`) so each sample is smaller. - Prefer **CSV** over XML results. - Avoid functional mode and full response data on every sample. - Use current stripped sample sending modes when available for your version. - Cap how many workers report to one controller; split farms if needed. - Consider autonomous CLI engines plus offline merge when coordination is not required. If you need live charts without overloading the controller GUI, use the [Backend Listener](/user-manual/realtime-results/) path so metrics stream to InfluxDB/Grafana from the engines or controller according to your plan design - still validate that the extra exporter CPU is acceptable. ## Example lab topology A minimal two-worker lab that matches the docs: | Host | Role | Software | |------|------|----------| | `controller.lab` | Client | Same JMeter + Java; has `.jmx`; runs CLI | | `worker1.lab` | Server | Same JMeter + Java; `jmeter-server`; CSV data present | | `worker2.lab` | Server | Same as worker1 | ```bash # on each worker cd $JMETER_HOME/bin ./jmeter-server # on controller ./jmeter -n -t /plans/api.jmx \ -R worker1.lab,worker2.lab \ -Jthreads=50 \ -Ghost=app.lab \ -l /tmp/results.jtl \ -e -o /tmp/report \ -X ``` If the plan uses `\${__P(threads,)}` for the Thread Group, remember: **each worker** applies that property independently. `-Jthreads=50` sets the client property; workers need the same value via `-Gthreads=50` if they evaluate `__P` for thread count when the engine starts the plan. Match where the property is read - when in doubt, bake conservative defaults into the plan and override consistently with `-G` for remote engines. ## Checklist before first production-scale distributed run 1. Versions identical (JMeter + Java) on all nodes. 2. Keystore distributed; SSL smoke-tested. 3. Firewall rules include control and reverse ports. 4. CSV, keystores for the **app** under test, and plugin JARs on every worker. 5. Small pilot with 1-2 threads per worker succeeds end-to-end. 6. Controller disk has space for the full combined JTL. 7. Heap sized per worker for planned local threads. 8. Runbook includes who starts workers, who starts the client, and how to stop (`shutdown`/`stop` scripts or remote stop). 9. Success criteria defined (error %, latency) before you stare at six worker CPU graphs. 10. Rollback: how to halt generation if the app tier melts down. ## Related documentation - [Remote Testing (full reference)](/user-manual/remote-test/) - [Distributed Testing Step-by-Step](/user-manual/jmeter-distributed-testing-step-by-step/) - [Properties Reference](/user-manual/properties-reference/) - [Best Practices](/user-manual/best-practices/) - multi-machine CLI - [Dashboard Report](/user-manual/generating-dashboard/) - [Real-time Results](/user-manual/realtime-results/) ## Frequently asked questions ### Does JMeter split 1000 threads across 4 workers? No. Each worker runs the full test plan. Four workers with 1000 threads configured means about 4000 threads total. ### Do I need to copy the JMX to every worker? No. The client sends the test plan to the servers. You **do** need to copy external data files and ensure plugins match. ### GUI or CLI for distributed load? CLI. The manual recommends starting remote tests from a non-GUI client for real load; GUI is for checking configuration. ### What is the default RMI port? JMeter/RMI commonly uses **1099** for the server registry connection; result channels use additional ports. Fix ports with `server.rmi.localport` and `client.rmi.localport` when firewalls require it. ### Why did SSL start matter after JMeter 4.0? Since JMeter 4.0, default RMI transport uses SSL and needs a keystore. Use `create-rmi-keystore` scripts and distribute `rmi_keystore.jks`. ### Can workers run different Java versions? It may work but is **discouraged**. Use the same Java and JMeter versions everywhere. ### Is distributed mode always better than one machine? No. Remote mode adds overhead and can overload the client. Sometimes one large injector or several independent CLI runs is simpler and more reliable. Follow the [Step-by-Step Tutorial](/user-manual/jmeter-distributed-testing-step-by-step/) with two VMs and a tiny thread count before scaling out. - [Remote Testing Reference](/user-manual/remote-test/) - SSL, ports, CLI flags - [Properties Reference](/user-manual/properties-reference/) - RMI and networking properties - [Heap Estimator](/tools/heap-estimator/) - size each worker Assuming threads are sharded automatically; forgetting CSV on workers; mixing JMeter versions; load-testing with the controller GUI and View Results Tree enabled. Start workers before the client; read `jmeter-server` logs on each worker; verify reverse ports if samples never appear on the controller. --- Title: JMeter Programmatic and DSL Test Plans URL: https://docs.jmeter.ai/topics/programmatic-dsl-plans/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter DSL / Programmatic Plans (Code-First) Teams leaving GUI-centric workflows for tools like k6 often still need JMeter’s protocol breadth or existing JVM skills. **JMeter 5.6** introduced experimental APIs and Kotlin/Java DSL helpers to build plans programmatically. This guide summarizes the official [Building a Test Plan Programmatically](/user-manual/build-programmatic-test-plan/) chapter and how to combine it with CLI execution, git, and CI. :::note[Experimental in 5.6] The manual states JMeter 5.6 brings **experimental** classes and methods for programmatic plans and invites feedback. APIs may evolve; pin JMeter versions and read release notes when upgrading. ::: ## Why code-first JMeter? | Driver | How programmatic plans help | |--------|----------------------------| | PR review | Diff Java/Kotlin instead of huge XML | | Reuse | Share builders for headers, auth, HTTP defaults | | Generate many variants | Loops in code create samplers/data | | Hybrid teams | GUI for discovery, code for steady-state suites | You can still save/run `.jmx`; code is another authoring front-end to the same engine. ## Core concept: ListedHashTree Official model: - Test elements **do not** form a tree by themselves. - Parent/child relationships live in a **`ListedHashTree`**. - Use **`ListedHashTree`**, not plain `HashTree`, because `HashTree` does **not** honour element order and children may shuffle unexpectedly. ### Low-level API sketch From the manual’s Debug Sampler example pattern: ```java ListedHashTree root = new ListedHashTree(); TestPlan testPlan = new TestPlan(); ListedHashTree testPlanSubtree = root.add(testPlan); ThreadGroup threadGroup = new ThreadGroup(); threadGroup.setName("Search Order Thread Group"); ListedHashTree threadGroupSubtree = testPlanSubtree.add(threadGroup); DebugSampler debugSampler = new DebugSampler(); threadGroupSubtree.add(debugSampler); ``` 1. Create root tree. 2. Add `TestPlan`, keep returned subtree. 3. Add `ThreadGroup` under plan. 4. Add samplers under the thread group subtree. (Your imports and exact setters match the JMeter version JARs on the classpath.) ## Generating code from the GUI The manual documents a **Copy Code** context action on plan elements. It generates code for the element and its children (example shows Kotlin DSL output for an HTTP sampler). Workflow: 1. Build or record a fragment in GUI. 2. Right-click → Copy Code. 3. Paste into your Kotlin/Java project. 4. Refactor into functions/modules. 5. Run via code that produces a tree and invokes the engine, or export/save as jmx if your tooling supports it. This is the fastest bridge for GUI users moving toward code. ## Kotlin DSL The programmatic chapter covers creating a plan with **Kotlin DSL** (`testTree` builder style, class references such as `TestPlan::class`, unary plus for childless elements). Extension functions on `TreeBuilder` factor common patterns (e.g. a `threadGroup` helper with default threads/ramp-up). See the manual sections: - Creating a plan with Kotlin DSL - Extending the Kotlin DSL for syntax details and screenshots of generated code. ## Java DSL Similarly, a **Java DSL** uses `testTree` with builder lambdas: `b.add(Class, consumer)` to configure properties and nest children. Prefer this when the team standardizes on Java without Kotlin. ## How this compares to k6-style DX | Concern | k6 | JMeter programmatic | |---------|----|---------------------| | Language | JS/TS | Java/Kotlin (+ jmx) | | Engine | Go binary | JVM JMeter engine | | Protocols | HTTP-centric strengths | Broad JMeter sampler set | | Maturity of DSL | Central product focus | Experimental helpers in 5.6 | | Execution | `k6 run` | Still `jmeter -n` or embedded engine | You do not have to abandon JMeter to get **reviewable code**; you may adopt DSL authoring while keeping CLI reports and distributed mode. Deep dive comparisons: [JMeter vs alternatives](/topics/jmeter-vs-alternatives/). ## Recommended team workflow 1. **Discover** journeys with recorder/GUI ([recorder](/topics/http-recorder/)). 2. **Copy Code** for HTTP fragments. 3. **Parameterize** with the same property names you use in jmx (`threads`, `host`) for CLI parity. 4. **Store** sources in git; build a small jar or use jbang/maven exec as you prefer. 5. **Execute** load with non-GUI JMeter and HTML dashboard ([best practices](/user-manual/best-practices/)). 6. **Gate** CI on report metrics ([CI/CD](/topics/ci-cd-load-testing/)). If you only need versioned XML, committing cleaned `.jmx` with `\${__P}` is still valid code-adjacent practice. ## Classpath and dependencies Programmatic authoring requires JMeter libraries on the module classpath (`ApacheJMeter_core`, protocol modules you use, etc.). Match versions to the JMeter you run for load. Plugin classes used in code must exist on workers too ([plugins](/topics/plugins-essentials/)). ## Execution options | Mode | Notes | |------|-------| | Generate jmx, run CLI | Familiar ops path `-n -t -l -e -o` | | Embedded engine in JVM | Advanced; ensure shutdown and result collection | | Distributed | Same remote testing rules; plan serialization must include all classes | ## Testing the builder Unit-test that the tree contains expected labels/counts. Smoke-run with 1 thread before performance environments. Experimental APIs deserve characterization tests when you upgrade JMeter. ## Pitfalls 1. Using `HashTree` instead of `ListedHashTree` → order bugs. 2. Mixing GUI-only plugins not on CI classpath. 3. Assuming DSL stability across majors without reading changes. 4. Forgetting lean-run rules (listeners, CLI) because “it’s code now.” 5. Duplicating secrets in source; still use env/`__P` patterns for runtime. ## Related reading - [Build programmatic test plan (manual)](/user-manual/build-programmatic-test-plan/) - [Building a test plan](/user-manual/build-test-plan/) - [Best practices](/user-manual/best-practices/) - [Functions and variables](/topics/functions-and-variables/) - [JMeter vs alternatives](/topics/jmeter-vs-alternatives/) ## Frequently asked questions ### Is the JMeter DSL production-ready? JMeter 5.6 documents it as experimental. Many teams use it successfully but should pin versions and watch release notes. ### Can I keep using .jmx files? Yes. Programmatic APIs are optional. Versioned jmx plus CLI remains fully supported. ### Kotlin or Java DSL? Choose based on team language. Both are documented. Copy Code often emits Kotlin DSL examples in the manual screenshots. ### Does code-first remove the need for non-GUI mode? No. Real load still should run non-GUI with minimal listeners regardless of how the plan was authored. ### How do I migrate from k6 back to JMeter? Rebuild scenarios with HTTP samplers or Copy Code from a recorded flow; map checks to assertions; run CLI reports. Protocol-only k6 scripts map cleanly; browser-level k6 features do not. ### Where is Copy Code? In the JMeter GUI context menu on a tree element (documented with screenshot in the programmatic chapter). Open a small plan in GUI, use Copy Code on an HTTP sampler, and compile that fragment against JMeter 5.6+ libraries. - [Programmatic manual chapter](/user-manual/build-programmatic-test-plan/) - [CI/CD](/topics/ci-cd-load-testing/) - [Best Practices](/user-manual/best-practices/) --- Title: JMeter Troubleshooting Guide URL: https://docs.jmeter.ai/topics/troubleshooting/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Troubleshooting Guide When tests fail, isolate **injector**, **plan**, and **system under test**. This playbook covers frequent symptoms with fixes grounded in [best practices](/user-manual/best-practices/), [remote testing](/user-manual/remote-test/), [functions](/user-manual/functions/), [recorder](/topics/http-recorder/), and [glossary](/user-manual/glossary/) metrics. For **search-friendly, one-error pages** (symptom → cause → fix), start with the [Error Playbooks index](/topics/errors/). :::tip[Reproduce small] Cut to **1 thread**, 1 loop, View Results Tree on, then grow. Load multiplies misconfiguration. ::: ## Dedicated error playbooks | Symptom | Playbook | |---------|----------| | `java.net.ConnectException` | [ConnectException](/topics/errors/connect-exception/) | | Non HTTP response code | [Non HTTP response code](/topics/errors/non-http-response-code/) | | `SSLHandshakeException` | [SSLHandshakeException](/topics/errors/ssl-handshake-exception/) | | `OutOfMemoryError: Java heap space` | [OutOfMemoryError heap](/topics/errors/out-of-memory-heap/) | | Socket closed / connection reset | [Socket closed / reset](/topics/errors/socket-closed-connection-reset/) | | Throughput stuck below target RPS | [Throughput stuck](/topics/errors/throughput-stuck/) | | Works in GUI, fails in CLI | [GUI works, CLI fails](/topics/errors/gui-works-cli-fails/) | | 401 / 403 after recording | [401/403 after recording](/topics/errors/401-403-after-recording/) | ## Quick triage tree 1. **Does GUI one-thread pass?** If no, fix functional/correlation first. 2. **Does CLI one-thread pass?** If no, path/CSV/property differences. 3. **Does small load pass?** If no, server or auth limits. 4. **Does large load fail?** Injector sizing, coordinated omission, SUT capacity. Check `jmeter.log` and the first error sample label/message every time. ## Connection reset / Non HTTP response code **Symptoms:** `Connection reset`, `Non HTTP response code: java.net.ConnectException`, broken pipe. | Check | Action | |-------|--------| | Host/port/protocol | HTTP Request Defaults and `\${__P(host)}` | | Server up / firewall | curl from **same** injector host | | TLS vs plain | `https` vs `http` mismatch | | Connection limits | Server max connections; JMeter HTTP client settings | | Short timeouts | Connect/response timeouts on HTTP Request | | Under load only | Server backlog, LB idle timeouts, injector ephemeral ports | Distributed: workers may lack network path the controller has ([distributed](/topics/distributed-testing/)). ## 401 / 403 after recording **Symptoms:** Recording works while browsing; replay fails auth. | Cause | Fix | |-------|-----| | Missing Cookie Manager | Add [HTTP Cookie Manager](/user-manual/component-reference/) | | CSRF/token hard-coded | [Correlate](/topics/correlation-dynamic-values/) dynamic fields | | Expired bearer token | Re-login or refresh ([JWT/OAuth](/topics/jwt-oauth-sso/)) | | Wrong Header Manager scope | Authorization not applied to failing sampler | | Different user/CSV | Row empty or wrong sharing mode | Best practices also note `unknown_ca` during HTTPS **recording** when the JMeter CA is not trusted ([recorder](/topics/http-recorder/)). ## SSL handshake failures **Symptoms:** `SSLHandshakeException`, PKIX path building failed, handshake_failure. | Cause | Fix | |-------|------| | Untrusted server cert | Import CA into JVM truststore used by JMeter | | SNI / wrong host | Correct server name; virtual host headers | | Protocol mismatch | TLS version disabled on one side | | Client cert required | Configure keystore in HTTP Request / system properties | | Recording MITM | Install `ApacheJMeterTemporaryRootCA.crt` | For **RMI SSL** between controller and workers (JMeter 4.0+), use `create-rmi-keystore` and distribute `rmi_keystore.jks` ([remote testing](/user-manual/remote-test/)). ## Low throughput / cannot reach target RPS Official guidance: wrong thread counts contribute to **coordinated omission** ([best practices](/user-manual/best-practices/)). Checklist: 1. Response time rose under load → need more threads or less target ([Thread Calculator](/tools/thread-calculator/), [CO tool](/tools/coordinated-omission/)). 2. View Results Tree or many listeners still enabled → disable for load. 3. Timers / think time lower throughput (expected). 4. Assertions too heavy. 5. Injector CPU at 100%. 6. Single NIC saturated. 7. Server throttling (check server metrics, not only JMeter). 8. Functional mode or saving full bodies → slow I/O. Prefer CLI: `jmeter -n -t plan.jmx -l results.jtl`. ## OutOfMemoryError / GC thrashing **Symptoms:** `java.lang.OutOfMemoryError: Java heap space`, long GC pauses, agents killed. | Cause | Fix | |-------|-----| | Heap too small | Raise `HEAP`/`-Xmx`; size with [Heap Estimator](/tools/heap-estimator/) | | View Results Tree in load | Disable | | Too many threads per JVM | Split engines ([distributed](/topics/distributed-testing/)) | | Huge responses kept | Save fewer fields; avoid XML results | | Leaky script engines | Prefer JSR223 Groovy with cache; avoid BeanShell hot paths ([best practices](/user-manual/best-practices/)) | | Container limit < Xmx | Align cgroup limit ([Docker](/topics/docker-kubernetes/)) | ## High error % but “green” samples earlier Add **assertions**. Without them, HTTP 500 pages can still be “successful” samples if the transport succeeded. Use Response Assertion on codes and critical body content ([API guide](/topics/api-load-testing/)). ## CLI differs from GUI | Issue | Note | |-------|------| | Relative CSV paths | Working directory differs; use stable paths | | Properties | GUI might have different `user.properties` | | Headless fonts/plugins | Missing plugins in CI image ([plugins](/topics/plugins-essentials/)) | | Mode | Never use GUI for real load | Parameterize with `\${__P}` and pass `-J` in both environments. ## Distributed-only failures | Symptom | Check | |---------|-------| | Connection refused to worker | `jmeter-server` up; port 1099 / `server.rmi.localport` | | SSL handshake RMI | Keystore on all nodes | | Serialization / ClassNotFound | JMeter/plugin version skew | | Missing CSV on worker | Data files not copied automatically | | Incomplete results | Reverse ports / client overload | See [distributed testing](/topics/distributed-testing/) and [remote testing](/user-manual/remote-test/). ## Dashboard / report generation errors From [generating dashboard](/user-manual/generating-dashboard/): - Required saveservice columns must remain enabled. - `-o` output folder issues (non-empty/prior report). - Filter regex excluding everything. Regenerate offline from JTL after fixing properties. ## Backend Listener / Influx empty ([Grafana topic](/topics/grafana-influx-backend-listener/)): URL/token, network, `samplersRegex`, summaryOnly, firewall from injector. ## Variable shows as `\${name}` Undefined variables are returned unchanged ([functions](/user-manual/functions/)). Fix extractors; set defaults; assert. ## Logging and debug tools - `jmeter.log` / `-j` log path - Log Viewer in GUI (hints & tips) - Debug Sampler + Tree (scripting only) - Reduce log level noise under load ## Metrics sanity (glossary) If numbers look “too good,” re-read [glossary](/user-manual/glossary/) definitions for latency vs elapsed, throughput calculation, and percentiles. Confirm you are not reading connect time alone or parent transaction samples incorrectly. ## Escalation checklist before blaming the server 1. One-thread functional pass with assertions. 2. CLI pass same properties. 3. Injector CPU/RAM/network headroom. 4. No heavy listeners. 5. Thread and heap sized. 6. Server-side metrics simultaneous. 7. Reproducible plan version in git. ## Related reading - [Best practices](/user-manual/best-practices/) - [Correlation](/topics/correlation-dynamic-values/) - [HTTP recorder](/topics/http-recorder/) - [Distributed testing](/topics/distributed-testing/) - [Hints and tips](/user-manual/hints-and-tips/) ## Frequently asked questions ### Why do I get connection reset only under load? Often server or load balancer limits, injector port exhaustion, or timeouts. Compare server metrics and run from the same network as the injector. ### Why 401 after a successful recording? Dynamic tokens or cookies were not correlated. Add Cookie Manager and extractors; do not reuse recorded bearer tokens. ### How do I fix OutOfMemoryError in JMeter? Increase heap, reduce threads per JVM, disable View Results Tree, save fewer result fields, and prefer Groovy JSR223 over heavy scripts. ### Why is throughput lower than the thread calculator? Calculators assume stable response times and little think time. Under load, response times rise and listeners or server limits cut throughput. ### What is the first log to read? `jmeter.log` (or the file set with `-j`) plus the first failing sampler in View Results Tree or the JTL error message. ### GUI works but CI fails. Why? Different working directory, missing CSV, missing plugins, wrong `-J` properties, or network policy from the CI runner. Pick your top failing sampler label, reproduce with one thread and Tree view, and apply the matching section above before scaling again. - [Best Practices](/user-manual/best-practices/) - [Correlation](/topics/correlation-dynamic-values/) - [Heap Estimator](/tools/heap-estimator/) - [Coordinated Omission](/tools/coordinated-omission/) --- Title: JMeter Interview Questions and Answers URL: https://docs.jmeter.ai/topics/interview-questions/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter Interview Questions and Answers This page lists common **Apache JMeter** interview questions with concise answers grounded in official behaviour, plus links into deeper topic guides and manual pages on this site. Use it to study or to interview others; for production work, prefer the full guides over memorized one-liners. ## Fundamentals ### What is Apache JMeter? An open-source load and performance testing tool from the Apache Software Foundation. It drives protocols (HTTP and many others), applies assertions, and reports metrics. It is not a browser: it does not run page JavaScript like Chrome. Deep dive: [Getting Started](/getting-started/get-started/), [Beginners path](/topics/jmeter-for-beginners/). ### What is a Test Plan? The root object that holds thread groups, controllers, samplers, listeners, and config elements in a tree. Saved as `.jmx` (XML). Deep dive: [Building a Test Plan](/user-manual/build-test-plan/), [Elements of a Test Plan](/user-manual/test-plan/). ### What is a Thread Group? It defines virtual users (threads), ramp-up, and loop/schedule behaviour for a set of samplers. Deep dive: [Test plan elements](/user-manual/test-plan/), [Thread Calculator](/tools/thread-calculator/). ### What is a Sampler? An element that sends a request (e.g. HTTP Request) and waits for a response, producing a sample result. Deep dive: [Component reference](/user-manual/component-reference/). ### What are Listeners? Elements that display or write results (Tree, Graph, Backend Listener, etc.). Heavy GUI listeners should be off during load; use CLI `-l` files instead. Deep dive: [Listeners](/user-manual/listeners/), [Best practices](/user-manual/best-practices/). ## Execution modes ### GUI vs non-GUI mode? GUI is for building and debugging. Real load should use non-GUI: `jmeter -n -t plan.jmx -l results.jtl`. Deep dive: [Best practices](/user-manual/best-practices/), [CI/CD](/topics/ci-cd-load-testing/). ### How do you generate an HTML report? ```bash jmeter -n -t plan.jmx -l results.jtl -e -o report/ ``` Deep dive: [Generating dashboard](/user-manual/generating-dashboard/). ### How do you parameterize host and threads for CI? Use `\${__P(threads,10)}` and `\${__P(host,localhost)}`, pass `-Jthreads=50 -Jhost=staging`. Deep dive: [Functions and variables](/topics/functions-and-variables/), [CI/CD](/topics/ci-cd-load-testing/). ## Correlation and data ### What is correlation? Extracting dynamic values (tokens, IDs) from responses into variables for later requests. Deep dive: [Correlation](/topics/correlation-dynamic-values/), [Regular expressions](/user-manual/regular-expressions/). ### Variables vs properties? Variables are thread-local; properties are JVM-global and read with `__P` / `__property`. Deep dive: [Functions manual](/user-manual/functions/). ### How do multi-user logins work? CSV Data Set Config with user/pass columns; reference `\${USER}` / `\${PASS}` on samplers. Deep dive: [Best practices](/user-manual/best-practices/). ### How do you send a JWT? Extract access token, set Header Manager `Authorization: Bearer \${accessToken}`. Deep dive: [JWT OAuth SSO](/topics/jwt-oauth-sso/). ## Timers, assertions, controllers ### Why use timers? To model think time and pacing so load is realistic rather than maximum request hammering. ### Why use assertions? To mark samples failed when the business response is wrong, not only when TCP fails. Deep dive: [API load testing](/topics/api-load-testing/). ### What does a Transaction Controller do? Groups child samples into a transaction for reporting (dashboard/statistics). Know parent vs child sample settings. Deep dive: [Dashboard](/user-manual/generating-dashboard/). ## Distributed testing ### How does distributed mode work? Controller sends the plan to workers running `jmeter-server`; each worker runs the **full** thread plan (threads multiply by worker count). Results aggregate on the controller. Deep dive: [Distributed testing](/topics/distributed-testing/), [Remote testing](/user-manual/remote-test/). ### Are CSV files auto-copied to workers? No. Place data files on each worker (or shared mount). ### RMI SSL? Since JMeter 4.0, RMI defaults to SSL; create and distribute a keystore. ## Metrics ### Elapsed vs latency vs connect time? See [glossary](/user-manual/glossary/): elapsed covers full response; latency to first response byte; connect includes TLS handshake where measured. ### What is throughput in JMeter? Requests per unit time over the test window (see glossary formula discussion). ### What is APDEX? Application Performance Index from satisfied/tolerating/frustrated counts based on thresholds. JMeter dashboard supports configurable thresholds. Deep dive: [APDEX SLOs percentiles](/topics/apdex-slo-percentiles/), [Dashboard](/user-manual/generating-dashboard/). ### What is coordinated omission? Measurement bias when the client cannot keep issuing work on schedule as the server slows, making latency look better than reality. Deep dive: [Best practices](/user-manual/best-practices/), [CO tool](/tools/coordinated-omission/). ## Scripting and extensions ### BeanShell vs Groovy? For intensive load, prefer JSR223 + Groovy with compile cache; avoid BeanShell/JavaScript hot paths per best practices. ### Can you build plans as code? JMeter 5.6 adds experimental programmatic/DSL APIs; also treat `.jmx` as code in git. Deep dive: [Programmatic DSL](/topics/programmatic-dsl-plans/), [Build programmatic plan](/user-manual/build-programmatic-test-plan/). ### What are plugins? Community JARs in `lib/ext` (Plugins Manager) for extra protocols and elements. Deep dive: [Plugins essentials](/topics/plugins-essentials/). ## Recording ### How does the HTTP(S) recorder work? JMeter proxy records browser HTTP(S); install temporary CA for HTTPS; filter static assets. Deep dive: [HTTP recorder](/topics/http-recorder/), [Proxy tutorial](/user-manual/jmeter-proxy-step-by-step/). ## Real-time monitoring ### How do you stream live metrics? Backend Listener to InfluxDB/Graphite; visualize in Grafana. Deep dive: [Grafana Influx Backend Listener](/topics/grafana-influx-backend-listener/), [Real-time results](/user-manual/realtime-results/). ## Troubleshooting prompts interviewers love | Prompt | Point to | |--------|----------| | OOM during test | [Troubleshooting](/topics/troubleshooting/), [Heap estimator](/tools/heap-estimator/) | | Low TPS | [Troubleshooting](/topics/troubleshooting/), [Thread calculator](/tools/thread-calculator/) | | SSL errors | [Troubleshooting](/topics/troubleshooting/) | | 401 after record | [Correlation](/topics/correlation-dynamic-values/), [Recorder](/topics/http-recorder/) | ## Scenario questions (how to answer) ### "Design a test for a login + search API" Cover: Thread Group, CSV users, HTTP defaults, login + JSON extract token, header bearer, search sampler, assertions, CLI report, optional Backend Listener. Link knowledge from [API](/topics/api-load-testing/) + [JWT](/topics/jwt-oauth-sso/). ### "How would you run this in CI?" Non-GUI, properties, artifacts, gate on error % / percentiles ([CI/CD](/topics/ci-cd-load-testing/)). ### "How do you scale beyond one machine?" Distributed RMI or multiple CLI engines; identical versions/plugins; data on each node ([distributed](/topics/distributed-testing/)). ### "JMeter vs k6?" Protocol breadth and GUI vs code-first efficiency; fair bake-off criteria ([vs alternatives](/topics/jmeter-vs-alternatives/)). ## Study path (one week) 1. [Beginners path](/topics/jmeter-for-beginners/) 2. [API](/topics/api-load-testing/) + [Correlation](/topics/correlation-dynamic-values/) 3. [Best practices](/user-manual/best-practices/) + [Dashboard](/user-manual/generating-dashboard/) 4. [Distributed](/topics/distributed-testing/) + [CI/CD](/topics/ci-cd-load-testing/) 5. [APDEX](/topics/apdex-slo-percentiles/) + [Troubleshooting](/topics/troubleshooting/) ## Frequently asked questions ### Are these answers enough to pass any interview? They cover common JMeter topics with correct mental models. Deep system design and company-specific tools still need broader performance engineering study. ### Should I memorize every component field? No. Know core concepts and where to look up fields in the [component reference](/user-manual/component-reference/). ### Is GUI mode acceptable for load in interviews? Say no for real load; explain CLI and why listeners distort results. ### What version should I mention? Speak to current lines (e.g. 5.6 features like programmatic DSL) and note you verify against release notes. ### How do I practice quickly? Build a three-sampler API plan, correlate a token, run CLI with HTML report, and break/fix one failure from the troubleshooting guide. Work the one-week study path above and rebuild one plan from memory using only the CLI report as proof. - [Beginners path](/topics/jmeter-for-beginners/) - [Best Practices](/user-manual/best-practices/) - [Troubleshooting](/topics/troubleshooting/) - [JMeter vs alternatives](/topics/jmeter-vs-alternatives/) --- Title: JMeter vs Alternatives URL: https://docs.jmeter.ai/topics/jmeter-vs-alternatives/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter vs Alternatives Choosing a load testing tool depends on team skills, protocols under test, CI style, and how you want to author scenarios. This page is a **hub** that compares **Apache JMeter** with the most common alternatives - **k6**, **Locust**, **Gatling**, **LoadRunner**, and **NeoLoad** - and links to detailed comparison pages for each. It is a decision aid, not a benchmark study; always validate with a proof-of-concept on *your* APIs and infrastructure. When you pick JMeter, this site's [Getting Started](/getting-started/get-started/), [Best Practices](/user-manual/best-practices/), and topic guides help you execute well. ## Quick comparison | Dimension | JMeter | k6 | Locust | Gatling | LoadRunner | NeoLoad | |-----------|--------|-----|--------|---------|------------|---------| | **Primary runtime** | JVM | Go binary; scripts in JS/TS | Python | JVM | Proprietary engine + VuGen IDE | JVM-based controller + recorders | | **Scenario authoring** | GUI + XML `.jmx` (+ DSL options) | Code (JS/TS) | Code (Python classes) | Code (Scala/Java/Kotlin DSL) | GUI recorder + VuGen IDE | GUI recorder + JavaScript | | **Virtual users model** | Thread-oriented (1 VU ≈ thread) | Lightweight VUs (goroutine-style) | Gevent greenlets / async style | Async event-driven | Proprietary Vuser model | Proprietary Vuser model | | **Protocols (typical)** | Broad: HTTP(S), JDBC, JMS, LDAP, FTP, mail | Strong HTTP; WebSocket; gRPC | Primarily HTTP(S) (extend in Python) | HTTP-focused; WebSocket/JMS | Very broad: Citrix, SAP, TruClient | Broad: HTTP(S), SAP, Citrix, JMS | | **GUI for design** | Full test-plan GUI | No design GUI (CLI/cloud UX) | Web UI for running/monitoring | No classic record-and-click GUI | Full IDE with recorder | Full GUI with recorder | | **Distributed load** | Native controller-worker ([remote testing](/topics/distributed-testing/)) | Local + cloud/operator patterns | Built-in master-worker style | OSS local; enterprise grid | Controller + load generators (licensed) | Controller + load generators (licensed) | | **Reporting** | HTML [dashboard](/user-manual/generating-dashboard/), CSV/JTL | CLI summary, cloud dashboards | Web UI + CSV/exports | Rich HTML reports | Built-in enterprise dashboards | Built-in dashboards, trend analysis | | **License (core)** | Apache License 2.0 | AGPL-style + commercial cloud | MIT (Locust) | Apache License 2.0 | Commercial (paid per VUser) | Commercial (paid per VUser) | Licensing and product packaging change over time - **verify current terms** on each project's site before enterprise adoption. The table reflects commonly cited positioning, not legal advice. ## Detailed comparison pages Each tool has a dedicated comparison page with positioning, strengths, trade-offs, when to choose it, architecture implications, CI/CD, reporting, migration guidance, and a fair bake-off checklist: | Comparison | When to read it | |---|---| | **[JMeter vs k6](/topics/jmeter-vs-k6/)** | HTTP/gRPC-focused platforms, developer-owned tests as JS/TS code, threshold-as-code in CI | | **[JMeter vs Locust](/topics/jmeter-vs-locust/)** | Python-first teams, custom protocol logic in Python, master/worker distribution without JVM | | **[JMeter vs Gatling](/topics/jmeter-vs-gatling/)** | JVM teams wanting typed DSL with compile-time checks, HTTP at high VU density per CPU | | **[JMeter vs LoadRunner and NeoLoad](/topics/jmeter-vs-enterprise/)** | Enterprise teams evaluating the switch from paid tools, cost reduction, protocol coverage | | **[GUI vs Code-First Load Testing](/topics/gui-vs-code-first/)** | Choosing an authoring paradigm (GUI vs code), team skills, review workflow, CI/CD fit | ## Apache JMeter in depth ### What JMeter optimizes for JMeter has long optimized for: - **Protocol breadth** beyond HTTP - **Visual test design** for mixed skill teams - **Offline HTML reports** and deep component libraries - **Remote engines** without a mandatory SaaS Core workflow documented throughout the manual: 1. Build a [test plan](/user-manual/build-test-plan/) in the GUI. 2. Use samplers, controllers, timers, assertions ([test plan elements](/user-manual/test-plan/)). 3. Parameterize with [variables, functions, CSV](/topics/functions-and-variables/). 4. Run load with **non-GUI** CLI (`jmeter -n -t ... -l ...`) per [best practices](/user-manual/best-practices/). 5. Analyze the [dashboard](/user-manual/generating-dashboard/) or external time-series via [Backend Listener](/user-manual/realtime-results/). ### Architecture implications Classic Thread Groups map virtual users to **Java threads**. That model is easy to reason about but means: - High concurrency needs careful **heap and CPU** sizing on injectors ([Heap Estimator](/tools/heap-estimator/)). - Undersized thread counts relative to target rate contribute to **coordinated omission** risks called out in best practices. - Large scales often use [distributed testing](/topics/distributed-testing/) or multiple autonomous CLI instances. ### Authoring styles | Style | Notes | |-------|------| | GUI `.jmx` | Default; great for recording and visual debug ([View Results Tree](/user-manual/listeners/) while scripting) | | Programmatic | [Programmatic test plans](/user-manual/build-programmatic-test-plan/) / DSL approaches in modern JMeter for code review workflows | | Recording | [HTTP(S) recorder](/topics/http-recorder/) for browser journeys | | cURL import | [cURL](/user-manual/curl/) for API snippets | ### Strengths - **Many protocols in-box** (HTTP, JDBC, LDAP, JMS, FTP, ...). - **Mature component set** (controllers, extractors, assertions). - **Native remote testing** documented in the official manual. - **Apache 2.0** licensing familiar to enterprises. - Huge community knowledge base and plugin ecosystem (Plugins Manager lives outside core docs). - Strong **CI fit** via CLI ([CI/CD topic](/topics/ci-cd-load-testing/)). ### Trade-offs - Thread-per-VU model can be **heavier** per user than Go/async tools on raw HTTP at extreme scale per CPU. - `.jmx` XML is verbose in code review compared to short JS/Python scripts. - GUI overuse during load distorts results - discipline required (official best practices). - Some modern protocols (gRPC, Kafka) often need **plugins** or other tools. ## Decision guide ### Choose JMeter when - You need **GUI authoring** or [recording](/topics/http-recorder/) for mixed-skill teams. - You test **multiple protocols** JMeter supports natively. - You already own a library of **`.jmx` plans** and trained staff. - You want **native remote engines** documented upstream without buying a grid product on day one. - You need **Apache 2.0** plus offline HTML dashboards from CLI. ### Choose k6 when - Scripts-as-JS and developer ownership matter most. - Workloads are primarily modern HTTP/gRPC APIs. - You accept the k6 product/licensing ecosystem. See the [detailed JMeter vs k6 comparison](/topics/jmeter-vs-k6/). ### Choose Locust when - Python is the team's default and scenarios are code-first. - You will extend behaviour in Python rather than hunt samplers. See the [detailed JMeter vs Locust comparison](/topics/jmeter-vs-locust/). ### Choose Gatling when - You want a typed DSL on the JVM and strong HTTP reports. - Your team is comfortable maintaining code-based simulations. See the [detailed JMeter vs Gatling comparison](/topics/jmeter-vs-gatling/). ### Choose LoadRunner or NeoLoad when - You need **Citrix, SAP, TruClient, or other proprietary enterprise protocols**. - **Commercial support SLAs** are non-negotiable. - **Integrated trend analysis** and executive dashboards are required out-of-box. - **Per-VUser licensing budget** is already allocated. See the [detailed JMeter vs LoadRunner and NeoLoad comparison](/topics/jmeter-vs-enterprise/). ### Choose GUI-based authoring when - Non-programmers build scenarios. - You need [recording](/topics/http-recorder/) for browser journeys. - Rapid prototyping and visual debugging are priorities. See the [detailed GUI vs Code-First comparison](/topics/gui-vs-code-first/). ### Multi-tool reality Many orgs run **more than one** tool: JMeter for legacy protocol packs and recorded journeys; k6/Gatling/Locust for service-level API checks in developer CI. That is rational - optimize for path of least resistance per team. ## Fair bake-off checklist When you trial tools on the same API: 1. Same **workload model** (arrival rate vs closed-loop users). 2. Same **think time** and data cardinality. 3. Same **environment** and monitoring on the server side. 4. Measure injector CPU/RAM, not only server latency. 5. Include **failure modes** (timeouts, 500s) and assertion strictness. 6. Include **team time** to author and maintain the script. 7. Check **license** and support explicitly. A tool that looks fastest in a blog chart can lose if your team cannot maintain scenarios. ## Workload modelling differences to watch Closed-loop tools that wait for a response before the next iteration (classic thread or VU loops) behave differently from open-loop arrival schedulers. If you compare "500 users" in JMeter Thread Groups to "500 VUs" in another tool, confirm: - Whether think time is included. - Whether failed requests still pace the same way. - Whether the tool compensates for coordinated omission. - Whether HTTP connection pools and keep-alive defaults match. JMeter's best practices explicitly warn about **coordinated omission** when thread counts are wrong relative to the target rate. A fair bake-off documents pacing for every tool, not only the one you already know. Use the [Coordinated Omission Calculator](/tools/coordinated-omission/) to quantify the skew. ## Skills and hiring | Team shape | Often smoother fit | |------------|-------------------| | QA engineers strong in GUI tools | JMeter | | Backend engineers writing JS daily | k6 | | Python platform / data eng | Locust | | JVM service teams wanting DSL review | Gatling or JMeter DSL | | Mixed enterprise protocols | JMeter | | Non-developer authors | JMeter (GUI + recorder) | Tool choice is partly a **staffing** decision. The cost of rewriting fifty scenarios usually dwarfs injector license or RAM differences. ## Reporting expectations Stakeholders often ask for HTML they can attach to a release ticket: - **JMeter** - offline [dashboard](/user-manual/generating-dashboard/) from CLI (`-e -o`) with APDEX and percentile tables. - **Gatling** - strong HTML report tradition. - **k6 / Locust** - CLI or web summaries; teams often add Grafana or cloud UIs. If your compliance process requires an artifact produced on an air-gapped runner, confirm the tool can emit a full report without a SaaS account. JMeter's dashboard generator is designed for that offline path. ## Frequently asked questions ### Is JMeter outdated compared to k6? No. JMeter remains actively used and documented for multi-protocol enterprise tests, GUI authoring, and offline reporting. k6 is often preferred for code-centric HTTP workflows - not a universal replacement. See the [detailed JMeter vs k6 comparison](/topics/jmeter-vs-k6/). ### Which tool is "fastest"? It depends on protocol, workload model, and injector tuning. Async/Go tools often achieve higher HTTP VU density per CPU; JMeter may still win total cost of ownership when protocol breadth or existing `.jmx` assets dominate. Benchmark your case. ### Can JMeter do tests-as-code? Yes, via [programmatic test plans](/user-manual/build-programmatic-test-plan/) and by treating `.jmx` as versioned artifacts with CLI execution. See the [GUI vs Code-First comparison](/topics/gui-vs-code-first/) for the broader paradigm discussion. ### Does JMeter support distributed testing without a paid product? Yes. Official **remote testing** supports multiple engines controlled from one client. You operate the machines and network yourself. ### What license is JMeter? Apache License 2.0 for Apache JMeter. Always confirm on the Apache project site. ### Should non-developers use k6 or Locust? They can, but JMeter's GUI and recorder are usually gentler for non-developer authors. Code-first tools shine when authors already write code daily. See the [GUI vs Code-First comparison](/topics/gui-vs-code-first/). ### Is Gatling only Scala? Historically Scala-heavy; Java/Kotlin DSLs are commonly used today. Check current Gatling documentation for first-class language support in your version. See the [detailed JMeter vs Gatling comparison](/topics/jmeter-vs-gatling/). ### Should I switch from LoadRunner to JMeter? Consider it if HTTP is your dominant protocol, you want to reduce per-VUser licensing costs, and you do not need Citrix/SAP/TruClient recorders. See the [detailed JMeter vs LoadRunner and NeoLoad comparison](/topics/jmeter-vs-enterprise/). If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then enforce CLI runs via [best practices](/user-manual/best-practices/). - [JMeter vs k6](/topics/jmeter-vs-k6/) - HTTP/gRPC code-first comparison - [JMeter vs Locust](/topics/jmeter-vs-locust/) - Python-first comparison - [JMeter vs Gatling](/topics/jmeter-vs-gatling/) - JVM typed DSL comparison - [JMeter vs LoadRunner and NeoLoad](/topics/jmeter-vs-enterprise/) - enterprise switch guide - [GUI vs Code-First Load Testing](/topics/gui-vs-code-first/) - authoring paradigm comparison - [Best Practices](/user-manual/best-practices/) - correct technique matters more than tool logos - [Distributed Testing](/topics/distributed-testing/) - how JMeter scales injectors - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with code-first tools Choosing a tool from marketing alone; comparing open-loop vs closed-loop workloads unfairly; ignoring license review; assuming JMeter "distributes" threads across workers without multiplying them; expecting 1:1 conversion between tools. --- Title: JMeter vs k6 URL: https://docs.jmeter.ai/topics/jmeter-vs-k6/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter vs k6 This page compares **Apache JMeter** with **k6**, a developer-first load testing tool whose scripts are written in JavaScript/TypeScript and executed by an efficient Go runtime. It is a decision aid for teams weighing JMeter’s GUI and protocol breadth against k6’s code-as-test and HTTP-centric efficiency. Always validate with a proof-of-concept on *your* APIs and infrastructure. For the broader comparison including Locust and Gatling, see [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/). ## Quick comparison | Dimension | JMeter | k6 | |-----------|--------|-----| | **Primary runtime** | JVM | Go binary; scripts in JS/TS | | **Scenario authoring** | GUI + XML `.jmx` (+ DSL options in modern JMeter) | Code (JS/TS) | | **Virtual users model** | Thread-oriented (1 VU ≈ thread in classic Thread Group) | Lightweight VUs (goroutine-style) | | **Protocols (typical OSS)** | Broad: HTTP(S), JDBC, JMS, LDAP, FTP, mail, etc. | Strong HTTP; WebSocket; gRPC ecosystem focus | | **GUI for design** | Full test-plan GUI | No design GUI (CLI/cloud UX) | | **Recording** | [HTTP(S) Test Script Recorder](/topics/http-recorder/) | Browser recorder / conversions in ecosystem | | **Distributed load** | Native controller-worker ([remote testing](/topics/distributed-testing/)) | Local + cloud/operator patterns (product-dependent) | | **Reporting** | HTML [dashboard](/user-manual/generating-dashboard/), CSV/JTL, listeners | CLI summary, cloud dashboards, integrations | | **License (core)** | Apache License 2.0 | Open-source core under AGPL-style licensing + commercial cloud | Licensing and product packaging change over time - **verify current terms** on each project’s site before enterprise adoption. ## k6 positioning k6 targets developers who want **performance tests as code** in JavaScript/TypeScript, executed by an efficient Go runtime. It is popular in API-centric and SRE-oriented teams, especially where Grafana observability is already standard. ## Strengths of k6 relative to JMeter - **Scripts are ordinary code**: modules, packages, PR review, and version control work the same way as application code. - **Efficient VU implementation** for high-churn HTTP scenarios, often achieving higher concurrent-user density per CPU than thread-per-VU models on raw HTTP. - **First-class CLI UX** and thresholds-as-code patterns in the k6 ecosystem, which map naturally to CI gates. - **Cloud and Kubernetes operator options** for teams that want managed scale (product choice, not open-source requirement). - **Developer ownership**: performance tests live alongside the services they test, reviewed in the same workflow. ## Trade-offs of k6 relative to JMeter - **No full JMeter-like protocol GUI** for JDBC, LDAP, JMS, or other enterprise protocols. k6 is HTTP-centric with ecosystem extensions. - **Teams without JS/TS comfort** face a learning curve, and the code-first model assumes developer authors. - **AGPL/commercial packaging** may matter to legal review - check current terms on the k6 site. - **Migrating large libraries of `.jmx` assets** is non-trivial; there is no 1:1 converter. - **No native JMeter-grade remote testing** experience out of the box; distributed execution patterns are product-dependent. ## When teams choose k6 over JMeter - **HTTP/gRPC-focused platforms** where protocol breadth beyond HTTP is not needed. - **Developers already writing JS/TS in CI** who want performance tests as code. - **Preference for code-only workflows** with threshold objects in source control. - **Grafana-native observability** stacks where k6 metrics fit naturally. - **Teams that reject GUI authoring** and want everything in Git. ## Decision criteria | Need | Lean toward | |------|-------------| | HTTP at huge VU density per CPU | k6 (goroutine-style VUs) | | Scripts in JS/TS with PR review | k6 | | Thresholds as code in CI | k6 | | Non-HTTP protocols (JDBC, LDAP, JMS) | **JMeter** | | GUI recording for mixed-skill teams | **JMeter** | | Apache 2.0 licensing | **JMeter** | ## Architecture implications k6’s Go runtime uses lightweight VUs that are goroutine-style, not Java threads. This means: - **Higher VU density per CPU** on HTTP workloads compared to JMeter’s thread-per-VU model. - **Lower per-VU memory overhead**, but the trade-off is less built-in protocol breadth. - **No JVM heap sizing** concerns - you size the Go binary like any other process. - **Distributed execution** is product-dependent; the open-source core does not have the same documented controller-worker RMI model as JMeter’s [remote testing](/topics/distributed-testing/). ## CI/CD and reporting All tools run headlessly. k6 embeds thresholds in source; JMeter gates often parse dashboard statistics or JTL. Both are valid. k6 reporting is CLI summary, cloud dashboards, or Prometheus/Grafana integrations. If your compliance process requires an **offline HTML artifact** from an air-gapped runner, confirm the tool can emit a full report without a SaaS account. JMeter’s dashboard generator is designed for that offline path; k6 teams often add Grafana or cloud UIs. ## Migrating from JMeter to k6 - **Re-implement scenarios**; do not expect 1:1 `.jmx` conversion perfection. - **Rebuild correlation and data feeds** (CSV → k6 feeders). - **Re-validate think time and workload models** - defaults differ. - **Map JMeter listeners to k6 thresholds** and external dashboards. ## Migrating from k6 to JMeter - **Use the [HTTP(S) recorder](/topics/http-recorder/) or cURL import** for HTTP scenarios. - **Map k6 feeders to CSV Data Set** + [functions](/topics/functions-and-variables/). - **Train the team on CLI-only load runs** per [best practices](/user-manual/best-practices/). - **Use programmatic plans** if you want code review workflows in JMeter. ## Fair bake-off checklist When you trial k6 and JMeter on the same API: 1. Same **workload model** (arrival rate vs closed-loop users). 2. Same **think time** and data cardinality. 3. Same **environment** and monitoring on the server side. 4. Measure **injector CPU/RAM**, not only server latency. 5. Include **failure modes** (timeouts, 500s) and assertion strictness. 6. Include **team time** to author and maintain the script. 7. Check **license** and support explicitly. A tool that looks fastest in a blog chart can lose if your team cannot maintain scenarios. If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then enforce CLI runs via [best practices](/user-manual/best-practices/). - [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/) - hub page with all tool comparisons - [API Load Testing](/topics/api-load-testing/) - HTTP/gRPC load testing with JMeter - [Distributed Testing](/topics/distributed-testing/) - how JMeter scales injectors - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with code-first tools - [Thread Calculator](/tools/thread-calculator/) - size threads for your target RPS Comparing open-loop vs closed-loop workloads unfairly; ignoring license review; assuming k6 replaces JMeter for non-HTTP protocols; expecting 1:1 .jmx conversion. --- Title: JMeter vs Locust URL: https://docs.jmeter.ai/topics/jmeter-vs-locust/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter vs Locust This page compares **Apache JMeter** with **Locust**, a Python-based load testing tool that expresses user behaviour in Python classes and tasks. It is a decision aid for teams weighing JMeter’s GUI and protocol breadth against Locust’s Python-first, code-as-test approach. Always validate with a proof-of-concept on *your* APIs and infrastructure. For the broader comparison including k6 and Gatling, see [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/). ## Quick comparison | Dimension | JMeter | Locust | |-----------|--------|--------| | **Primary runtime** | JVM | Python (gevent greenlets) | | **Scenario authoring** | GUI + XML `.jmx` (+ DSL options in modern JMeter) | Code (Python classes) | | **Virtual users model** | Thread-oriented (1 VU ≈ thread in classic Thread Group) | Gevent greenlets / async style | | **Protocols (typical OSS)** | Broad: HTTP(S), JDBC, JMS, LDAP, FTP, mail, etc. | Primarily HTTP(S) (extend in Python) | | **GUI for design** | Full test-plan GUI | Web UI mainly for **running/monitoring** | | **Recording** | [HTTP(S) Test Script Recorder](/topics/http-recorder/) | Limited vs JMeter proxy tradition | | **Distributed load** | Native controller-worker ([remote testing](/topics/distributed-testing/)) | Built-in master-worker style | | **Reporting** | HTML [dashboard](/user-manual/generating-dashboard/), CSV/JTL, listeners | Web UI + CSV/exports | | **License (core)** | Apache License 2.0 | MIT (Locust) | ## Locust positioning Locust expresses user behaviour in **Python** classes and tasks. A web UI is commonly used to **start tests and watch charts**, while scenarios remain code. It is popular in Python-first organisations where data, backend, and ML teams share the language. ## Strengths of Locust relative to JMeter - **Extremely approachable** if the organisation is Python-first (data, backend, ML). - **Flexible custom clients** in Python for unusual protocols or bespoke request logic. - **Distributed execution** is a known Locust strength (master/worker style), with a straightforward CLI model. - **MIT license** is simple for many organisations and avoids copyleft concerns. - **Scenarios as Python code** integrate naturally with pytest-era engineering culture and existing Python test utilities. ## Trade-offs of Locust relative to JMeter - **You build more yourself** for non-HTTP systems (vs JMeter’s in-box samplers for JDBC, LDAP, JMS, FTP, mail). - **No JMeter-grade [HTTP(S) proxy recorder](/topics/http-recorder/) experience** out of the box. - **Reporting and HTML ecosystems differ**; teams often export metrics to external stacks (Grafana, Prometheus). - **GUI test design for non-coders is not Locust’s center of gravity** - the web UI is for running and monitoring, not designing. - **Python GIL considerations** at extreme concurrency per worker, though gevent greenlets mitigate this for I/O-bound HTTP. ## When teams choose Locust over JMeter - **Python is the shared language** across the testing and development teams. - **Custom protocol logic is easier as Python code** than as JMeter plugins or samplers. - **Load tests live next to pytest-era engineering culture** and share CI patterns. - **Teams want master/worker distribution** without JVM heap sizing concerns. - **MIT licensing** is preferred over copyleft or commercial packaging. ## Decision criteria | Need | Lean toward | |------|-------------| | Python-first team | Locust | | Custom protocol logic in Python | Locust | | Non-HTTP protocols (JDBC, LDAP, JMS) | **JMeter** | | GUI recording for mixed-skill teams | **JMeter** | | Apache 2.0 licensing | **JMeter** | | Master/worker distribution without JVM | Locust | ## Architecture implications Locust uses gevent greenlets for concurrency, which are lightweight and async-style. This means: - **No JVM heap sizing** concerns - Locust runs as a Python process. - **Lower per-VU memory overhead** than JMeter’s thread-per-VU model for I/O-bound HTTP. - **Python GIL** can limit CPU-bound work per worker, though gevent mitigates this for network I/O. - **Distributed execution** uses a master/worker model that is simpler to configure than JMeter’s RMI-based remote testing, but does not have the same breadth of documented controller-worker patterns. ## CI/CD and reporting All tools run headlessly. Locust scenarios are Python code, so they integrate with existing Python CI pipelines and can use the same dependency management (pip, virtualenv) as the application under test. Locust reporting is web UI + CSV/exports. Teams often add Grafana or Prometheus for long-term dashboards. If your compliance process requires an **offline HTML artifact** from an air-gapped runner, confirm the tool can emit a full report without a SaaS account. JMeter’s dashboard generator is designed for that offline path; Locust teams often build custom reporting or export to external stacks. ## Migrating from JMeter to Locust - **Re-implement scenarios** in Python classes; do not expect 1:1 `.jmx` conversion. - **Rebuild correlation and data feeds** (CSV → Python data structures or custom feeders). - **Re-validate think time and workload models** - defaults differ. - **Map JMeter listeners to Locust events and hooks** for custom metrics. - **Train the team on Python test authoring** if they are not already Python-fluent. ## Migrating from Locust to JMeter - **Use the [HTTP(S) recorder](/topics/http-recorder/) or cURL import** for HTTP scenarios. - **Map Python feeders to CSV Data Set** + [functions](/topics/functions-and-variables/). - **Train the team on CLI-only load runs** per [best practices](/user-manual/best-practices/). - **Use programmatic plans** if you want code review workflows in JMeter. ## Fair bake-off checklist When you trial Locust and JMeter on the same API: 1. Same **workload model** (arrival rate vs closed-loop users). 2. Same **think time** and data cardinality. 3. Same **environment** and monitoring on the server side. 4. Measure **injector CPU/RAM**, not only server latency. 5. Include **failure modes** (timeouts, 500s) and assertion strictness. 6. Include **team time** to author and maintain the script. 7. Check **license** and support explicitly. A tool that looks fastest in a blog chart can lose if your team cannot maintain scenarios. If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then enforce CLI runs via [best practices](/user-manual/best-practices/). - [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/) - hub page with all tool comparisons - [Functions and Variables](/topics/functions-and-variables/) - parameterization depth in JMeter - [Distributed Testing](/topics/distributed-testing/) - how JMeter scales injectors - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with code-first tools - [Thread Calculator](/tools/thread-calculator/) - size threads for your target RPS Comparing open-loop vs closed-loop workloads unfairly; ignoring license review; assuming Locust replaces JMeter for non-HTTP protocols; expecting 1:1 .jmx conversion; overlooking Python GIL at extreme concurrency. --- Title: JMeter vs Gatling URL: https://docs.jmeter.ai/topics/jmeter-vs-gatling/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter vs Gatling This page compares **Apache JMeter** with **Gatling**, a JVM-based load testing tool focused on high-performance HTTP load generation with a typed DSL (Scala historically; Java/Kotlin DSLs widely used) and polished HTML reports. It is a decision aid for teams weighing JMeter’s GUI and protocol breadth against Gatling’s async efficiency and report quality. Always validate with a proof-of-concept on *your* APIs and infrastructure. For the broader comparison including k6 and Locust, see [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/). ## Quick comparison | Dimension | JMeter | Gatling | |-----------|--------|---------| | **Primary runtime** | JVM | JVM | | **Scenario authoring** | GUI + XML `.jmx` (+ DSL options in modern JMeter) | Code (Scala/Java/Kotlin DSL) | | **Virtual users model** | Thread-oriented (1 VU ≈ thread in classic Thread Group) | Async event-driven | | **Protocols (typical OSS)** | Broad: HTTP(S), JDBC, JMS, LDAP, FTP, mail, etc. | HTTP-focused; WebSocket/JMS in ecosystem | | **GUI for design** | Full test-plan GUI | No classic record-and-click design GUI | | **Recording** | [HTTP(S) Test Script Recorder](/topics/http-recorder/) | Recorder offerings vary by edition/ecosystem | | **Distributed load** | Native controller-worker ([remote testing](/topics/distributed-testing/)) | OSS local; enterprise features for large grid | | **Reporting** | HTML [dashboard](/user-manual/generating-dashboard/), CSV/JTL, listeners | Rich HTML reports | | **License (core)** | Apache License 2.0 | Apache License 2.0 (Gatling OSS) | ## Gatling positioning Gatling focuses on **high-performance HTTP load generation** with a **typed DSL** and polished HTML reports. Enterprise editions add collaboration and distributed features. It is popular in JVM teams that want code-centric simulations with compile-time checks. ## Strengths of Gatling relative to JMeter - **Async engine efficient** for many concurrent HTTP users per injector, often achieving higher VU density per CPU than thread-per-VU models. - **Scenario-as-code with compile-time checks** in typed DSLs (Scala, Java, Kotlin), which improves maintainability and review. - **Report quality** is a frequent reason teams adopt Gatling - rich HTML reports with clear metrics. - **Apache 2.0 for Gatling OSS** aligns with many compliance needs. - **JVM ecosystem** means teams can leverage existing build tools (Maven, Gradle, sbt) and dependency management. ## Trade-offs of Gatling relative to JMeter - **Steeper ramp for non-developers** than JMeter GUI; the typed DSL assumes developer authors. - **Protocol breadth of JMeter’s sampler catalog is wider** in classic enterprise packs (LDAP, JMS, FTP, etc.). - **Large distributed grids may push teams toward commercial offerings** - evaluate current OSS limits honestly. - **Recording/onboarding path differs** from JMeter’s long-standing proxy tutorial tradition. - **Scala learning curve** for teams unfamiliar with functional programming, though Java/Kotlin DSLs are more accessible. ## When teams choose Gatling over JMeter - **JVM + typed DSL preference** where the team is comfortable with Scala, Java, or Kotlin. - **HTTP-heavy systems at large concurrency per box** where async VUs matter. - **Report aesthetics and code-centric review culture** drive the decision. - **Teams that want compile-time validation** of test scenarios. - **Existing JVM build pipelines** (Maven, Gradle) that can integrate Gatling tasks. ## Decision criteria | Need | Lean toward | |------|-------------| | HTTP at huge VU density per CPU | Gatling (async VUs) | | Typed DSL with compile-time checks | Gatling | | Rich HTML reports | Gatling | | Non-HTTP protocols (JDBC, LDAP, JMS) | **JMeter** | | GUI recording for mixed-skill teams | **JMeter** | | Apache 2.0 licensing | Both (verify current terms) | ## Architecture implications Gatling’s async event-driven model differs from JMeter’s thread-per-VU model: - **Higher VU density per CPU** on HTTP workloads, since async VUs are not tied to OS threads. - **No JVM heap sizing concerns per VU** in the same way as JMeter threads, though the JVM still needs proper sizing. - **No native JMeter-grade remote testing** experience in the OSS edition; distributed grids may require commercial features. - **JVM ecosystem** means teams can leverage existing build tools (Maven, Gradle, sbt) and dependency management. ## CI/CD and reporting All tools run headlessly. Gatling scenarios are code, so they integrate with existing JVM CI pipelines and can use the same build tools as the application under test. Gatling reporting is strong HTML reports. JMeter reporting is offline HTML dashboard from CLI (`-e -o`) with APDEX and percentile tables. If your compliance process requires an **offline HTML artifact** from an air-gapped runner, both tools can emit full reports without a SaaS account, but verify the specific edition and configuration. ## Migrating from JMeter to Gatling - **Re-implement scenarios** in the Gatling DSL; do not expect 1:1 `.jmx` conversion. - **Rebuild correlation and data feeds** (CSV → Gatling feeders). - **Re-validate think time and workload models** - defaults differ. - **Map JMeter listeners to Gatling assertions** and checks. - **Train the team on the Gatling DSL** if they are not already JVM-fluent. ## Migrating from Gatling to JMeter - **Use the [HTTP(S) recorder](/topics/http-recorder/) or cURL import** for HTTP scenarios. - **Map Gatling feeders to CSV Data Set** + [functions](/topics/functions-and-variables/). - **Train the team on CLI-only load runs** per [best practices](/user-manual/best-practices/). - **Use programmatic plans** if you want code review workflows in JMeter. ## Fair bake-off checklist When you trial Gatling and JMeter on the same API: 1. Same **workload model** (arrival rate vs closed-loop users). 2. Same **think time** and data cardinality. 3. Same **environment** and monitoring on the server side. 4. Measure **injector CPU/RAM**, not only server latency. 5. Include **failure modes** (timeouts, 500s) and assertion strictness. 6. Include **team time** to author and maintain the script. 7. Check **license** and support explicitly. A tool that looks fastest in a blog chart can lose if your team cannot maintain scenarios. If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then enforce CLI runs via [best practices](/user-manual/best-practices/). - [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/) - hub page with all tool comparisons - [Generating Dashboard](/user-manual/generating-dashboard/) - JMeter HTML reports and APDEX - [Distributed Testing](/topics/distributed-testing/) - how JMeter scales injectors - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with code-first tools - [Thread Calculator](/tools/thread-calculator/) - size threads for your target RPS Comparing open-loop vs closed-loop workloads unfairly; ignoring license review; assuming Gatling OSS covers large distributed grids without commercial features; expecting 1:1 .jmx conversion; overlooking Scala learning curve. --- Title: JMeter vs LoadRunner and NeoLoad URL: https://docs.jmeter.ai/topics/jmeter-vs-enterprise/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # JMeter vs LoadRunner and NeoLoad This page compares **Apache JMeter** with enterprise load testing tools **LoadRunner** (Micro Focus) and **NeoLoad** (formerly Neotys, now part of Micro Focus). It is a decision aid for enterprise teams weighing paid, full-stack tools against open-source JMeter for protocol breadth, distributed load, reporting, and total cost of ownership. Always validate with a proof-of-concept on *your* APIs and infrastructure. For the broader open-source comparison including k6, Locust, and Gatling, see [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/). ## Quick comparison | Dimension | JMeter | LoadRunner | NeoLoad | |-----------|--------|------------|---------| | **Primary runtime** | JVM | Proprietary engine + VuGen IDE | JVM-based controller + recorders | | **Scenario authoring** | GUI + XML `.jmx` (+ DSL options) | GUI recorder + VuGen IDE (C-based Vuser scripts) | GUI recorder + JavaScript-based scripts | | **Virtual users model** | Thread-oriented (1 VU ≈ thread) | Proprietary Vuser model (compiled C) | Proprietary Vuser model | | **Protocols (typical)** | Broad: HTTP(S), JDBC, JMS, LDAP, FTP, mail, etc. | Very broad: enterprise apps, Citrix, SAP, TruClient, etc. | Broad: HTTP(S), SAP, Citrix, JMS, etc. | | **GUI for design** | Full test-plan GUI | Full IDE with recorder | Full GUI with recorder | | **Distributed load** | Native controller-worker ([remote testing](/topics/distributed-testing/)) | Controller + load generators (licensed) | Controller + load generators (licensed) | | **Reporting** | HTML [dashboard](/user-manual/generating-dashboard/), CSV/JTL, listeners | Built-in enterprise dashboards, analytics | Built-in dashboards, trend analysis | | **License (core)** | Apache License 2.0 | Commercial (paid per Vuser/concurrent) | Commercial (paid per Vuser/concurrent) | | **SaaS option** | No (self-hosted) | LoadRunner Cloud (SaaS) | NeoLoad Cloud (SaaS) | ## Enterprise positioning Enterprise load testing tools like LoadRunner and NeoLoad offer full-stack protocol support (Citrix, SAP, TruClient, etc.), integrated recorders, and commercial support. They are common in large organisations with dedicated performance engineering teams and budget for licensed tools. JMeter is Apache 2.0 licensed and familiar to many enterprises. Its protocol breadth covers JDBC, LDAP, JMS, FTP, and mail in-box - wider than most open-source alternatives for classic enterprise protocols. Native remote engines work without a mandatory SaaS or grid product on day one. ## Strengths of JMeter relative to enterprise tools - **Apache 2.0 licensing** is familiar to enterprises and avoids per-Vuser licensing costs. - **Protocol breadth** covers JDBC, LDAP, JMS, FTP, and mail in-box - wider than most open-source alternatives. - **Native remote testing** documented upstream without buying a grid product on day one. - **Offline HTML dashboards** from CLI (`-e -o`) with APDEX and percentile tables, designed for air-gapped runners. - **No per-VUser licensing** - scale injectors without incremental license costs. - **Large community knowledge base** and plugin ecosystem (Plugins Manager lives outside core docs). - **Strong CI fit** via CLI ([CI/CD topic](/topics/ci-cd-load-testing/)). ## Trade-offs of JMeter relative to enterprise tools - **No built-in recorder for Citrix, SAP, TruClient, or other proprietary enterprise protocols** - these often require commercial tools. - **No commercial support** from a vendor - community support only (though consulting is available). - **No integrated trend analysis** across runs - teams build this with external dashboards. - **No per-VUser licensing model** means you provision and manage your own infrastructure. - **Protocol support for some enterprise apps** (Citrix, SAP GUI) is limited or requires plugins. - **Less polished out-of-box dashboards** compared to commercial enterprise tools. ## When teams switch from LoadRunner / NeoLoad to JMeter - **Cost reduction** is the primary driver - per-VUser licensing can be expensive at scale. - **HTTP/HTTPS is the dominant protocol** and does not require Citrix/SAP/Citrix-specific recorders. - **Teams want open-source flexibility** without vendor lock-in or license audits. - **CI/CD integration** is simpler with CLI-driven open-source tools. - **Existing Java/JVM expertise** in the organisation. - **Protocol needs fit JMeter’s catalog** (HTTP, JDBC, JMS, LDAP, FTP, mail). ## When teams stay with LoadRunner / NeoLoad - **Citrix, SAP, TruClient, or other proprietary protocol testing** is required. - **Commercial support SLAs** are non-negotiable for production-critical tests. - **Integrated trend analysis and executive dashboards** are required out-of-box. - **Per-VUser licensing budget** is already allocated and approved. - **Existing investment in Vuser scripts** and trained staff. ## Decision criteria | Need | Lean toward | |------|-------------| | Apache 2.0, no per-VUser cost | JMeter | | HTTP + JDBC + JMS + LDAP in one tool | JMeter | | Native remote testing without a grid product | JMeter | | Offline HTML dashboards from air-gapped runners | JMeter | | Citrix / SAP / TruClient protocols | LoadRunner / NeoLoad | | Commercial support SLAs | LoadRunner / NeoLoad | | Integrated trend analysis | LoadRunner / NeoLoad | | Per-VUser licensing budget approved | LoadRunner / NeoLoad | ## Total cost of ownership Enterprise tools charge per VUser or concurrent license, which can become expensive at scale. JMeter has no per-VUser cost - you provision and manage your own infrastructure. Consider: - **License costs**: LoadRunner/NeoLoad per-VUser fees vs. JMeter’s Apache 2.0. - **Infrastructure costs**: Both require self-hosted generators; JMeter’s are commodity VMs. - **Training costs**: JMeter GUI is gentler for mixed-skill teams; enterprise tools require certified training. - **Migration costs**: Re-implementing Vuser scripts is non-trivial and time-consuming. - **Support costs**: Commercial tools include support; JMeter relies on community or consulting. ## Architecture implications JMeter’s thread-per-VU model means: - **High concurrency needs careful [heap and CPU sizing](/tools/heap-estimator/) on injectors.** - **Undersized thread counts relative to target rate contribute to [coordinated omission](/tools/coordinated-omission/) risks.** - **Large scales often use [distributed testing](/topics/distributed-testing/) or multiple autonomous CLI instances.** - **Each worker runs the full thread plan** (threads multiply by worker count) - a documented JMeter rule. ## CI/CD and reporting All tools run headlessly. JMeter’s portable core is: ```bash jmeter -n -t plan.jmx -l results.jtl -e -o report/ ``` See [CI/CD load testing](/topics/ci-cd-load-testing/). Code-first tools embed thresholds in source; JMeter gates often parse dashboard statistics or JTL - both valid. If your compliance process requires an **artifact produced on an air-gapped runner**, JMeter’s dashboard generator is designed for that offline path. Commercial tools may require online activation or SaaS connectivity for full reporting - verify before committing. ## Migrating from LoadRunner / NeoLoad to JMeter - **Re-implement scenarios** in JMeter; do not expect 1:1 Vuser script conversion. - **Rebuild correlation and data feeds** (CSV → [CSV Data Set](/topics/functions-and-variables/)). - **Re-validate think time and workload models** - defaults differ. - **Map enterprise protocol needs** to JMeter samplers; identify gaps (Citrix, SAP) early. - **Train the team on CLI-only load runs** per [best practices](/user-manual/best-practices/). - **Use the [HTTP(S) recorder](/topics/http-recorder/) or cURL import** for HTTP scenarios. - **Use programmatic plans** if you want code review workflows in JMeter. ## Migrating from JMeter to LoadRunner / NeoLoad - **Use the commercial tool’s recorder** for HTTP and enterprise protocols. - **Map CSV Data Set to the tool’s data feeders.** - **Train the team on the commercial IDE and Vuser scripting.** - **Budget for per-VUser licensing** at your target scale. ## Fair bake-off checklist When you trial JMeter and an enterprise tool on the same API: 1. Same **workload model** (arrival rate vs closed-loop users). 2. Same **think time** and data cardinality. 3. Same **environment** and monitoring on the server side. 4. Measure **injector CPU/RAM**, not only server latency. 5. Include **failure modes** (timeouts, 500s) and assertion strictness. 6. Include **team time** to author and maintain the script. 7. Check **license** and support explicitly. 8. Include **total cost at target VUser scale** - not just per-VUser rates. A tool that looks cheapest per-VUser can lose if your team cannot maintain scenarios or if protocol gaps require a second tool. If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then enforce CLI runs via [best practices](/user-manual/best-practices/). - [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/) - hub page with all tool comparisons - [Distributed Testing](/topics/distributed-testing/) - how JMeter scales injectors - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with enterprise tools - [Heap Estimator](/tools/heap-estimator/) - JVM heap sizing for JMeter injectors - [Coordinated Omission](/tools/coordinated-omission/) - why thread sizing matters at scale Assuming JMeter covers all enterprise protocols (Citrix, SAP); ignoring total cost of ownership including training and migration; expecting 1:1 Vuser script conversion; comparing open-loop vs closed-loop workloads unfairly; overlooking air-gapped reporting requirements. --- Title: GUI vs Code-First Load Testing URL: https://docs.jmeter.ai/topics/gui-vs-code-first/ --- import RelatedContent from '../../../components/RelatedContent.astro'; # GUI vs Code-First Load Testing Load testing tools fall into two broad **authoring paradigms**: **GUI-based** tools where you build scenarios by clicking through a graphical interface, and **code-first** tools where you write scenarios as code in a programming language. This page compares the two paradigms, their trade-offs, and when to use each. It is not specific to any single tool - JMeter supports both paradigms, while k6, Locust, and Gatling are code-first by design. For tool-specific comparisons, see [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/). ## The two paradigms | Aspect | GUI-based | Code-first | |--------|-----------|------------| | **Authoring** | Click through a test-plan tree, configure elements visually | Write scripts in JS, Python, Scala, or DSL | | **Review** | Export/share `.jmx` or screenshots; diffs are hard | Git diffs, PR review, CI checks | | **Reuse** | Copy/paste elements, templates, recorded snippets | Functions, modules, packages, libraries | | **Debugging** | Visual tree, View Results Tree, listeners | IDE debugger, logs, breakpoints | | **Learning curve** | Gentle for non-programmers | Requires programming comfort | | **Version control** | XML files (verbose diffs) | Source code (clean diffs) | | **Protocol support** | In-box samplers for many protocols | Depends on library ecosystem | | **Recording** | Built-in HTTP(S) proxy recorder | External recorders or converters | ## GUI-based load testing GUI-based tools let you build load test scenarios by interacting with a graphical interface. You add elements (samplers, controllers, timers, assertions) to a test-plan tree, configure their properties in forms, and run the test from the same interface. ### Strengths of GUI-based authoring - **Gentle learning curve for non-programmers** - business analysts and QA engineers can build scenarios without writing code. - **Visual test design** - you see the structure of your test plan as a tree, with clear parent-child relationships. - **Built-in recording** - the [HTTP(S) Test Script Recorder](/topics/http-recorder/) captures browser journeys and turns them into test elements. - **Immediate feedback** - listeners like View Results Tree show request/response details in real time. - **Rapid prototyping** - drag elements, change a few fields, and run immediately. ### Trade-offs of GUI-based authoring - **Verbose version control** - `.jmx` XML files produce noisy diffs that are hard to review in Git. - **No compile-time checks** - typos in variable names or property values are caught at runtime, not at authoring time. - **Merge conflicts** - XML merge conflicts are painful to resolve manually. - **Limited reuse** - sharing logic across test plans often means copy/paste, not functions or modules. - **GUI overuse during load** - running load from the GUI distorts results; discipline is required to switch to CLI for real tests. ### When GUI-based authoring fits - **Mixed-skill teams** where business analysts or QA engineers build scenarios. - **Recording browser journeys** for web application testing. - **Rapid prototyping** and debugging of test logic. - **Teams with large libraries of `.jmx` plans** and trained staff. - **Non-developer authors** who are not comfortable writing code. ## Code-first load testing Code-first tools let you write load test scenarios as code in a programming language. Scripts are plain text files that can be version-controlled, reviewed, and tested like application code. ### Strengths of code-first authoring - **Clean version control** - Git diffs are readable; PR review works naturally. - **Compile-time checks** - typed DSLs (Gatling, JMeter DSL) catch errors before runtime. - **Reuse and abstraction** - functions, modules, packages, and libraries reduce duplication. - **IDE integration** - syntax highlighting, autocomplete, refactoring, and debugging. - **CI/CD integration** - tests run as part of the build pipeline with the same tooling as the application. - **Thresholds as code** - performance gates live in source control alongside the application. ### Trade-offs of code-first authoring - **Requires programming comfort** - non-developers face a learning curve. - **No built-in recorder** - scenarios must be written from scratch or converted from recorded traffic. - **Debugging is log-based** - no visual tree or real-time request/response inspector. - **Setup overhead** - dependency management, build tools, and environment configuration. - **Less approachable for mixed-skill teams** - the barrier to entry is higher. ### When code-first authoring fits - **Developer-owned performance tests** where engineers write and maintain scenarios. - **CI/CD pipelines** where tests must run headlessly and integrate with build tools. - **Teams that want PR review** of test changes and clean Git history. - **Python, JS, or JVM teams** that want performance tests in the same language as the application. - **Code-centric review culture** where scenarios are treated as application code. ## JMeter supports both paradigms JMeter is not locked into one paradigm. It supports: | Style | Paradigm | Notes | |-------|----------|-------| | GUI `.jmx` | GUI-based | Default; great for recording and visual debug ([View Results Tree](/user-manual/listeners/) while scripting) | | Programmatic | Code-first | [Programmatic test plans](/user-manual/build-programmatic-test-plan/) / DSL approaches in modern JMeter for code review workflows | | Recording | GUI-based | [HTTP(S) recorder](/topics/http-recorder/) for browser journeys | | cURL import | Both | [cURL](/user-manual/curl/) for API snippets | This means teams can start with the GUI for prototyping and recording, then migrate to programmatic plans for version control and CI. The [programmatic test plan](/user-manual/build-programmatic-test-plan/) chapter documents how to author JMeter tests as code using the Kotlin DSL, Java DSL, and low-level APIs. ## Decision criteria | Need | Lean toward | |------|-------------| | Non-programmer authors | GUI-based | | Recording browser journeys | GUI-based (JMeter recorder) | | Rapid prototyping | GUI-based | | Clean Git diffs and PR review | Code-first | | Compile-time checks | Code-first (typed DSL) | | CI/CD integration | Code-first | | Reuse across test plans | Code-first (functions/modules) | | Mixed-skill teams | GUI-based (JMeter) | | Developer-owned tests | Code-first | ## Hybrid approaches Many organisations use **both paradigms**: - **JMeter for recording and prototyping**, then programmatic plans for CI. - **GUI for initial debugging**, code-first for committed load tests. - **Different tools per team**: JMeter GUI for QA engineers, k6/Gatling for developer CI. - **JMeter DSL** as a bridge - code-first authoring that still runs on the JMeter engine. ## Fair bake-off checklist When choosing an authoring paradigm: 1. **Who writes the tests?** Developers, QA engineers, or business analysts? 2. **What protocols are needed?** GUI tools often have broader in-box protocol support. 3. **How are tests reviewed?** Do you need Git diffs and PR review, or are screenshots acceptable? 4. **Where do tests run?** Local GUI, CI/CD, or both? 5. **What is the team’s programming comfort?** Can authors write JS/Python/Scala? 6. **What is the reuse strategy?** Copy/paste or shared libraries? 7. **What is the debugging workflow?** Visual tree or IDE debugger? The cost of rewriting fifty scenarios usually dwarfs injector license or RAM differences. Choose the paradigm that matches your team’s skills and workflow. If JMeter fits, start with [Getting Started](/getting-started/get-started/) and a small [web test plan](/user-manual/build-web-test-plan/), then try [programmatic test plans](/user-manual/build-programmatic-test-plan/) for code review workflows. - [JMeter vs Alternatives](/topics/jmeter-vs-alternatives/) - hub page with all tool comparisons - [Programmatic Test Plan](/user-manual/build-programmatic-test-plan/) - code-first JMeter with Kotlin/Java DSL - [HTTP Recorder](/topics/http-recorder/) - GUI-based recording for browser journeys - [CI/CD Load Testing](/topics/ci-cd-load-testing/) - automation parity with code-first tools - [Functions and Variables](/topics/functions-and-variables/) - parameterization in JMeter Assuming GUI tools can’t do code review; assuming code-first tools are always better for mixed-skill teams; ignoring the team’s programming comfort; expecting 1:1 conversion between paradigms; overlooking the value of visual debugging. --- Title: User's Manual: Building a Test Plan URL: https://docs.jmeter.ai/user-manual/build-test-plan/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 2. Building a Test Plan A test plan describes a series of steps JMeter will execute when run. A complete test plan will consist of one or more Thread Groups, logic controllers, sample generating controllers, listeners, timers, assertions, and configuration elements. ### 2.1 Adding and Removing Elements Adding [elements to a test plan](/user-manual/test-plan/) can be done by right-clicking on an element in the tree, and choosing a new element from the "`add`" list. Alternatively, elements can be loaded from file and added by choosing the "`merge`" or "`open`" option. To remove an element, make sure the element is selected, right-click on the element, and choose the "`remove`" option. ### 2.2 Loading and Saving Elements To load an element from file, right click on the existing tree elements to which you want to add the loaded element, and select the "`merge`" option. Choose the file where your elements are saved. JMeter will merge the elements into the tree. To save tree elements, right click on an element and choose the "`Save Selection As …`" option. JMeter will save the element selected, plus all child elements beneath it. In this way, you can save test tree fragments and individual elements for later use. ### 2.3 Configuring Tree Elements Any element in the test tree will present controls in JMeter's right-hand frame. These controls allow you to configure the behavior of that particular test element. What can be configured for an element depends on what type of element it is. :::note The Test Tree itself can be manipulated by dragging and dropping components around the test tree. ::: ### 2.4 Saving the Test Plan Although it is not required, we recommend that you save the Test Plan to a file before running it. To save the Test Plan, select "`Save`" or "`Save Test Plan As …`" from the File menu (with the latest release, it is no longer necessary to select the Test Plan element first). :::note JMeter allows you to save the entire Test Plan tree or only a portion of it. To save only the elements located in a particular "branch" of the Test Plan tree, select the Test Plan element in the tree from which to start the "branch", and then click your right mouse button to access the "`Save Selection As …`" menu item. Alternatively, select the appropriate Test Plan element and then select "`Save Selection As …`" from the Edit menu. ::: ### 2.5 Running a Test Plan To run your test plan, choose "`Start`" (`Control + r`) from the "`Run`" menu item. When JMeter is running, it shows a small green box at the right hand end of the section just under the menu bar. You can also check the "`Run`" menu. If "`Start`" is disabled, and "`Stop`" is enabled, then JMeter is running your test plan (or, at least, it thinks it is). The numbers to the left of the green box are the number of active threads / total number of threads. These only apply to a locally run test; they do not include any threads started on remote systems when using client-server mode. :::note Using GUI mode as described here should only be used when debugging your Test Plan. To run the real load test, use CLI mode. ::: ### 2.6 Stopping a Test There are two types of stop command available from the menu: - `Stop` (`Control + .`) - stops the threads immediately if possible. Many samplers are Interruptible which means that active samples can be terminated early. The stop command will check that all threads have stopped within the default timeout, which is 5000 ms = 5 seconds. [This can be changed using the JMeter property `jmeterengine.threadstop.wait`] If the threads have not stopped, then a message is displayed. The Stop command can be retried, but if it fails, then it is necessary to exit JMeter to clean up. - `Shutdown` (`Control + ,`) - requests the threads to stop at the end of any current work. Will not interrupt any active samples. The modal shutdown dialog box will remain active until all threads have stopped. If Shutdown is taking too long. Close the Shutdown dialog box and select `Run`/`Stop`, or just press `Control + .`. When running JMeter in CLI mode, there is no Menu, and JMeter does not react to keystrokes such as `Control + .`. So JMeter CLI mode will listen for commands on a specific port (default `4445`, see the JMeter property `jmeterengine.nongui.port`). JMeter supports automatic choice of an alternate port if the default port is being used (for example by another JMeter instance). In this case, JMeter will try the next higher port, continuing until it reaches the JMeter property `jmeterengine.nongui.maxport`) which defaults to `4455`. If `maxport` is less than or equal to `port`, port scanning will not take place. The chosen port is displayed in the console window. The commands currently supported are: - `Shutdown` - graceful shutdown - `StopTestNow` - immediate shutdown These commands can be sent by using the `shutdown[.cmd|.sh]` or `stoptest[.cmd|.sh]` script respectively. The scripts are to be found in the JMeter `bin` directory. The commands will only be accepted if the script is run from the same host. ### 2.7 Error reporting JMeter reports warnings and errors to the `jmeter.log` file, as well as some information on the test run itself. JMeter shows the number of warnings/errors found in `jmeter.log` file next to the warning icon (triangle) at the right hand end of its window. Click on the warning icon to show the `jmeter.log` file at the bottom of JMeter's window. Just occasionally there may be some errors that JMeter is unable to trap and log; these will appear on the command console. If a test is not behaving as you expect, please check the log file in case any errors have been reported (e.g. perhaps a syntax error in a function call). Sampling errors (e.g. HTTP 404 - file not found) are not normally reported in the log file. Instead these are stored as attributes of the sample result. The status of a sample result can be seen in the various different Listeners. {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Start with the [Building a Web Test Plan](/user-manual/build-web-test-plan/) tutorial for a hands-on walkthrough. - [Elements of a Test Plan](/user-manual/test-plan/) - detailed component descriptions - [Component Reference](/user-manual/component-reference/) - full element reference - Adding too many listeners in non-GUI mode wastes memory - Not using Timers causes unrealistic request rates {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Elements of a Test Plan URL: https://docs.jmeter.ai/user-manual/test-plan/ --- {/* SYNCED-BODY:START */} ## 3. Elements of a Test Plan This section describes the different parts of a test plan. A minimal test will consist of the Test Plan, a Thread Group and one or more Samplers. ### 3.0 Test Plan The Test Plan object has a checkbox called "`Functional Testing`". If selected, it will cause JMeter to record the data returned from the server for each sample. If you have selected a file in your test listeners, this data will be written to file. This can be useful if you are doing a small run to ensure that JMeter is configured correctly, and that your server is returning the expected results. The consequence is that the file will grow huge quickly, and JMeter's performance will suffer. This option should be off if you are doing stress-testing (it is off by default). If you are not recording the data to file, this option makes no difference. You can also use the `Configuration` button on a listener to decide what fields to save. ### 3.1 Thread Group Thread group elements are the beginning points of any test plan. All controllers and samplers must be under a thread group. Other elements, e.g. Listeners, may be placed directly under the test plan, in which case they will apply to all the thread groups. As the name implies, the thread group element controls the number of threads JMeter will use to execute your test. The controls for a thread group allow you to: - Set the number of threads - Set the ramp-up period - Set the number of times to execute the test Each thread will execute the test plan in its entirety and completely independently of other test threads. Multiple threads are used to simulate concurrent connections to your server application. The ramp-up period tells JMeter how long to take to "ramp-up" to the full number of threads chosen. If 10 threads are used, and the ramp-up period is 100 seconds, then JMeter will take 100 seconds to get all 10 threads up and running. Each thread will start 10 (100/10) seconds after the previous thread was begun. If there are 30 threads and a ramp-up period of 120 seconds, then each successive thread will be delayed by 4 seconds. Ramp-up needs to be long enough to avoid too large a work-load at the start of a test, and short enough that the last threads start running before the first ones finish (unless one wants that to happen). Start with Ramp-up = number of threads and adjust up or down as needed. By default, the thread group is configured to loop once through its elements. Thread Group also allows to specify **Thread lifetime**. Click the checkbox at the bottom of the Thread Group panel to enable/disable extra fields in which you can enter the duration of test and the startup delay You can configure `Duration (seconds)` and `Startup Delay (seconds)` to control the duration of each thread group and the after how much seconds it starts. When the test is started, JMeter will wait `Startup Delay (seconds)` before starting the Threads of the Thread Group and run for the configured `Duration (seconds)` time. ### 3.2 Controllers JMeter has two types of Controllers: Samplers and Logical Controllers. These drive the processing of a test. Samplers tell JMeter to send requests to a server. For example, add an HTTP Request Sampler if you want JMeter to send an HTTP request. You can also customize a request by adding one or more Configuration Elements to a Sampler. For more information, see [Samplers](#samplers). Logical Controllers let you customize the logic that JMeter uses to decide when to send requests. For example, you can add an Interleave Logic Controller to alternate between two HTTP Request Samplers. For more information, see [Logical Controllers](#logic_controller). ### 3.2.1 Samplers Samplers tell JMeter to send requests to a server and wait for a response. They are processed in the order they appear in the tree. Controllers can be used to modify the number of repetitions of a sampler. JMeter samplers include: - FTP Request - HTTP Request (can be used for SOAP or REST Webservice also) - JDBC Request - Java object request - JMS request - JUnit Test request - LDAP Request - Mail request - OS Process request - TCP request Each sampler has several properties you can set. You can further customize a sampler by adding one or more Configuration Elements to the Test Plan. If you are going to send multiple requests of the same type (for example, HTTP Request) to the same server, consider using a Defaults Configuration Element. Each controller has one or more Defaults elements (see below). Remember to add a Listener to your test plan to view and/or store the results of your requests to disk. If you are interested in having JMeter perform basic validation on the response of your request, add an [Assertion](#assertions) to the sampler. For example, in stress testing a web application, the server may return a successful "HTTP Response" code, but the page may have errors on it or may be missing sections. You could add assertions to check for certain HTML tags, common error strings, and so on. JMeter lets you create these assertions using regular expressions. [JMeter's built-in samplers](/user-manual/component-reference/#samplers) ### 3.2.2 Logic Controllers Logic Controllers let you customize the logic that JMeter uses to decide when to send requests. Logic Controllers can change the order of requests coming from their child elements. They can modify the requests themselves, cause JMeter to repeat requests, etc. To understand the effect of Logic Controllers on a test plan, consider the following test tree: - Test Plan The first thing about this test is that the login request will be executed only the first time through. Subsequent iterations will skip it. This is due to the effects of the [Once Only Controller](/user-manual/component-reference/#Once_Only_Controller). After the login, the next Sampler loads the search page (imagine a web application where the user logs in, and then goes to a search page to do a search). This is just a simple request, not filtered through any Logic Controller. After loading the search page, we want to do a search. Actually, we want to do two different searches. However, we want to re-load the search page itself between each search. We could do this by having 4 simple HTTP request elements (load search, search "A", load search, search "B"). Instead, we use the [Interleave Controller](/user-manual/component-reference/#Interleave_Controller) which passes on one child request each time through the test. It keeps the ordering (i.e. it doesn't pass one on at random, but "remembers" its place) of its child elements. Interleaving 2 child requests may be overkill, but there could easily have been 8, or 20 child requests. Note the [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) that belongs to the Interleave Controller. Imagine that "Search A" and "Search B" share the same PATH info (an HTTP request specification includes domain, port, method, protocol, path, and arguments, plus other optional items). This makes sense - both are search requests, hitting the same back-end search engine (a servlet or cgi-script, let's say). Rather than configure both HTTP Samplers with the same information in their PATH field, we can abstract that information out to a single Configuration Element. When the Interleave Controller "passes on" requests from "Search A" or "Search B", it will fill in the blanks with values from the HTTP default request Configuration Element. So, we leave the PATH field blank for those requests, and put that information into the Configuration Element. In this case, this is a minor benefit at best, but it demonstrates the feature. The next element in the tree is another HTTP default request, this time added to the Thread Group itself. The Thread Group has a built-in Logic Controller, and thus, it uses this Configuration Element exactly as described above. It fills in the blanks of any Request that passes through. It is extremely useful in web testing to leave the DOMAIN field blank in all your HTTP Sampler elements, and instead, put that information into an HTTP default request element, added to the Thread Group. By doing so, you can test your application on a different server simply by changing one field in your Test Plan. Otherwise, you'd have to edit each and every Sampler. The last element is a [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager). A Cookie Manager should be added to all web tests - otherwise JMeter will ignore cookies. By adding it at the Thread Group level, we ensure that all HTTP requests will share the same cookies. Logic Controllers can be combined to achieve various results. See the list of [built-in Logic Controllers](/user-manual/component-reference/#logic_controllers). ### 3.2.3 Test Fragments The Test Fragment element is a special type of [controller](#controllers) that exists on the Test Plan tree at the same level as the Thread Group element. It is distinguished from a Thread Group in that it is not executed unless it is referenced by either a [Module Controller](/user-manual/component-reference/#Module_Controller) or an [Include_Controller](/user-manual/component-reference/#Include_Controller). This element is purely for code re-use within Test Plans ### 3.3 Listeners Listeners provide access to the information JMeter gathers about the test cases while JMeter runs. The [Graph Results](/user-manual/component-reference/#Graph_Results) listener plots the response times on a graph. The "View Results Tree" Listener shows details of sampler requests and responses, and can display basic HTML and XML representations of the response. Other listeners provide summary or aggregation information. Additionally, listeners can direct the data to a file for later use. Every listener in JMeter provides a field to indicate the file to store data to. There is also a Configuration button which can be used to choose which fields to save, and whether to use CSV or XML format. :::note Note that all Listeners save the same data; the only difference is in the way the data is presented on the screen. ::: Listeners can be added anywhere in the test, including directly under the test plan. They will collect data only from elements at or below their level. There are several [listeners](/user-manual/component-reference/#listeners) that come with JMeter. ### 3.4 Timers By default, a JMeter thread executes samplers in sequence without pausing. We recommend that you specify a delay by adding one of the available timers to your Thread Group. If you do not add a delay, JMeter could overwhelm your server by making too many requests in a very short amount of time. A timer will cause JMeter to delay a certain amount of time **before** each sampler which is in its [scope](#scoping_rules). If you choose to add more than one timer to a Thread Group, JMeter takes the sum of the timers and pauses for that amount of time before executing the samplers to which the timers apply. Timers can be added as children of samplers or controllers in order to restrict the samplers to which they are applied. To provide a pause at a single place in a test plan, one can use the [Flow Control Action](/user-manual/component-reference/#Flow_Control_Action) Sampler. ### 3.5 Assertions Assertions allow you to assert facts about responses received from the server being tested. Using an assertion, you can essentially "test" that your application is returning the results you expect it to. For instance, you can assert that the response to a query will contain some particular text. The text you specify can be a Perl-style regular expression, and you can indicate that the response is to contain the text, or that it should match the whole response. You can add an assertion to any Sampler. For example, you can add an assertion to a HTTP Request that checks for the text, "`</HTML>`". JMeter will then check that the text is present in the HTTP response. If JMeter cannot find the text, then it will mark this as a failed request. :::note Note that assertions apply to all samplers which are in their [scope](#scoping_rules). To restrict an assertion to a single sampler, add the assertion as a child of the sampler. ::: To view assertion results, add an Assertion Listener to the Thread Group. Failed Assertions will also show up in the Tree View and Table Listeners, and will count towards the error %age for example in the Aggregate and Summary reports. ### 3.6 Configuration Elements A configuration element works closely with a Sampler. Although it does not send requests (except for [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder)), it can add to or modify requests. A configuration element is accessible from only inside the tree branch where you place the element. For example, if you place an HTTP Cookie Manager inside a Simple Logic Controller, the Cookie Manager will only be accessible to HTTP Request Controllers you place inside the Simple Logic Controller (see figure 1). The Cookie Manager is accessible to the HTTP requests "Web Page 1" and "Web Page 2", but not "Web Page 3". Also, a configuration element inside a tree branch has higher precedence than the same element in a "parent" branch. For example, we defined two HTTP Request Defaults elements, "Web Defaults 1" and "Web Defaults 2". Since we placed "Web Defaults 1" inside a Loop Controller, only "Web Page 2" can access it. The other HTTP requests will use "Web Defaults 2", since we placed it in the Thread Group (the "parent" of all other branches). ![Figure 1 - Test Plan Showing Accessibility of Configuration Elements](/images/screenshots/http-config/http-config-example.png) _Figure 1 - Test Plan Showing Accessibility of Configuration Elements_ :::note The [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) Configuration element is different. It is processed at the start of a test, no matter where it is placed. For simplicity, it is suggested that the element is placed only at the start of a Thread Group. ::: ### 3.7 Pre-Processor Elements A Pre-Processor executes some action prior to a Sampler Request being made. If a Pre-Processor is attached to a Sampler element, then it will execute just prior to that sampler element running. A Pre-Processor is most often used to modify the settings of a Sample Request just before it runs, or to update variables that aren't extracted from response text. See the [**scoping rules**](/user-manual/test-plan/#scoping_rules) for more details on when Pre-Processors are executed. ### 3.8 Post-Processor Elements A Post-Processor executes some action after a Sampler Request has been made. If a Post-Processor is attached to a Sampler element, then it will execute just after that sampler element runs. A Post-Processor is most often used to process the response data, often to extract values from it. See the [**scoping rules**](/user-manual/test-plan/#scoping_rules) for more details on when Post-Processors are executed. ### 3.9 Execution order 1. Configuration elements 2. Pre-Processors 3. Timers 4. Sampler 5. Post-Processors (unless SampleResult is `null`) 6. Assertions (unless SampleResult is `null`) 7. Listeners (unless SampleResult is `null`) :::note Please note that Timers, Assertions, Pre- and Post-Processors are only processed if there is a sampler to which they apply. Logic Controllers and Samplers are processed in the order in which they appear in the tree. Other test elements are processed according to the scope in which they are found, and the type of test element. [Within a type, elements are processed in the order in which they appear in the tree]. ::: For example, in the following test plan: - Controller The order of execution would be: ``` Pre-Processor 1 Timer 1 Timer 2 Sampler 1 Post-Processor 1 Post-Processor 2 Assertion 1 Pre-Processor 1 Timer 1 Timer 2 Sampler 2 Post-Processor 1 Post-Processor 2 Assertion 1 ``` ### 3.10 Scoping Rules The JMeter test tree contains elements that are both hierarchical and ordered. Some elements in the test trees are strictly hierarchical (Listeners, Config Elements, Post-Processors, Pre-Processors, Assertions, Timers), and some are primarily ordered (controllers, samplers). When you create your test plan, you will create an ordered list of sample request (via Samplers) that represent a set of steps to be executed. These requests are often organized within controllers that are also ordered. Given the following test tree: ![Example test tree](/images/screenshots/scoping1.png) _Example test tree_ The order of requests will be, One, Two, Three, Four. Some controllers affect the order of their subelements, and you can read about these specific controllers in [the component reference](/user-manual/component-reference/). Other elements are hierarchical. An Assertion, for instance, is hierarchical in the test tree. If its parent is a request, then it is applied to that request. If its parent is a Controller, then it affects all requests that are descendants of that Controller. In the following test tree: ![Hierarchy example](/images/screenshots/scoping2.png) _Hierarchy example_ Assertion #1 is applied only to Request One, while Assertion #2 is applied to Requests Two and Three. Another example, this time using Timers: ![complex example](/images/screenshots/scoping3.png) _complex example_ In this example, the requests are named to reflect the order in which they will be executed. Timer #1 will apply to Requests Two, Three, and Four (notice how order is irrelevant for hierarchical elements). Assertion #1 will apply only to Request Three. Timer #2 will affect all the requests. Hopefully these examples make it clear how configuration (hierarchical) elements are applied. If you imagine each Request being passed up the tree branches, to its parent, then to its parent's parent, etc., and each time collecting all the configuration elements of that parent, then you will see how it works. :::note The Configuration elements Header Manager, Cookie Manager and Authorization manager are treated differently from the Configuration Default elements. The settings from the Configuration Default elements are merged into a set of values that the Sampler has access to. However, the settings from the Managers are not merged. If more than one Manager is in the scope of a Sampler, only one Manager is used, but there is currently no way to specify _which_ is used. ::: ### 3.11 Properties and Variables JMeter _properties_ are defined in `jmeter.properties` (see [Getting Started - Configuring JMeter](/getting-started/get-started/#configuring_jmeter) for more details). Properties are global to jmeter, and are mostly used to define some of the defaults JMeter uses. For example the property `remote_hosts` defines the servers that JMeter will try to run remotely. Properties can be referenced in test plans - see [Functions - read a property](/user-manual/functions/#__property) - but cannot be used for thread-specific values. JMeter _variables_ are local to each thread. The values may be the same for each thread, or they may be different. If a variable is updated by a thread, only the thread copy of the variable is changed. For example the [Regular Expression Extractor](/user-manual/component-reference/#Regular_Expression_Extractor) Post-Processor will set its variables according to the sample that its thread has read, and these can be used later by the same thread. For details of how to reference variables and functions, see [Functions and Variables](/user-manual/functions/) Note that the values defined by the [Test Plan](/user-manual/component-reference/#Test_Plan) and the [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) configuration element are made available to the whole test plan at startup. If the same variable is defined by multiple UDV elements, then the last one takes effect. Once a thread has started, the initial set of variables is copied to each thread. Other elements such as the [User Parameters](/user-manual/component-reference/#User_Parameters) Pre-Processor or [Regular Expression Extractor](/user-manual/component-reference/#Regular_Expression_Extractor) Post-Processor may be used to redefine the same variables (or create new ones). These redefinitions only apply to the current thread. The [setProperty](/user-manual/functions/#__setProperty) function can be used to define a JMeter property. These are global to the test plan, so can be used to pass information between threads - should that be needed. :::note Both variables and properties are case-sensitive. ::: ### 3.12 Using Variables to parameterise tests Variables don't have to vary - they can be defined once, and if left alone, will not change value. So you can use them as short-hand for expressions that appear frequently in a test plan. Or for items which are constant during a run, but which may vary between runs. For example, the name of a host, or the number of threads in a thread group. When deciding how to structure a Test Plan, make a note of which items are constant for the run, but which may change between runs. Decide on some variable names for these - perhaps use a naming convention such as prefixing them with `C_` or `K_` or using uppercase only to distinguish them from variables that need to change during the test. Also consider which items need to be local to a thread - for example counters or values extracted with the Regular Expression Post-Processor. You may wish to use a different naming convention for these. For example, you might define the following on the Test Plan: ``` HOST www.example.com THREADS 10 LOOPS 20 ``` You can refer to these in the test plan as `\${HOST}` `\${THREADS}` etc. If you later want to change the host, just change the value of the `HOST` variable. This works fine for small numbers of tests, but becomes tedious when testing lots of different combinations. One solution is to use a property to define the value of the variables, for example: ``` HOST \${__P(host,www.example.com)} THREADS \${__P(threads,10)} LOOPS \${__P(loops,20)} ``` You can then change some or all of the values on the command-line as follows: ``` jmeter … -Jhost=www3.example.org -Jloops=13 ``` {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a Web Test Plan URL: https://docs.jmeter.ai/user-manual/build-web-test-plan/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 4. Building a Web Test Plan {/* CUSTOM-INTRO:START */} :::tip[Use CLI mode for real load] After the web flow is validated, save the plan and run it with `jmeter -n`. GUI listeners should stay disabled during the real load run. ::: :::caution[Avoid View Results Tree in load tests] View Results Tree helps inspect recorded requests and assertions, but it should be disabled before sustained web load tests. ::: {/* CUSTOM-INTRO:END */} In this section, you will learn how to create a basic [Test Plan](/user-manual/build-test-plan/) to test a Web site. You will create five users that send requests to two pages on the JMeter Web site. Also, you will tell the users to run their tests twice. So, the total number of requests is (5 users) x (2 requests) x (repeat 2 times) = 20 HTTP requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [HTTP Request](/user-manual/component-reference/#HTTP_Request), [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults), and [Graph Results](/user-manual/component-reference/#Graph_Results). For a more advanced Test Plan, see [Building an Advanced Web Test Plan](/user-manual/build-adv-web-test-plan/). ## 4.1 Adding Users The first step you want to do with every JMeter Test Plan is to add a [Thread Group](/user-manual/test-plan/#thread_group) element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and how many requests they should send. Go ahead and add the ThreadGroup element by first selecting the Test Plan, clicking your right mouse button to get the Add menu, and then select Add → ThreadGroup. You should now see the Thread Group element under Test Plan. If you do not see the element, then "expand" the Test Plan tree by clicking on the Test Plan element. Next, you need to modify the default properties. Select the Thread Group element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 4.1 below) ![Figure 4.1. Thread Group with Default Values](/images/screenshots/webtest/threadgroup.png) _Figure 4.1. Thread Group with Default Values_ Start by providing a more descriptive name for our Thread Group. In the name field, enter JMeter Users. Next, increase the number of users (called threads) to 5. In the next field, the Ramp-Up Period, leave the default value of 1 seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a Ramp-Up Period of 5 seconds, JMeter will finish starting all of your users by the end of the 5 seconds. So, if we have 5 users and a 5 second Ramp-Up Period, then the delay between starting users would be 1 second (5 users / 5 seconds = 1 user per second). If you set the value to 0, then JMeter will immediately start all of your users. Finally enter a value of 2 in the Loop Count field. This property tells JMeter how many times to repeat your test. If you enter a loop count value of 1, then JMeter will run your test only once. To have JMeter repeatedly run your Test Plan, select the Forever checkbox. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: See Figure 4.2 for the completed JMeter Users Thread Group. ![Figure 4.2. JMeter Users Thread Group](/images/screenshots/webtest/threadgroup2.png) _Figure 4.2. JMeter Users Thread Group_ ## 4.2 Adding Default HTTP Request Properties Now that we have defined our users, it is time to define the tasks that they will be performing. In this section, you will specify the default settings for your HTTP requests. And then, in section 4.3, you will add HTTP Request elements which use some of the default settings you specified here. Begin by selecting the JMeter Users (Thread Group) element. Click your right mouse button to get the Add menu, and then select Add → Config Element → HTTP Request Defaults. Then select this new element to view its Control Panel (see Figure 4.3). ![Figure 4.3. HTTP Request Defaults](/images/screenshots/webtest/http-defaults1.png) _Figure 4.3. HTTP Request Defaults_ Like most JMeter elements, the [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) Control Panel has a name field that you can modify. In this example, leave this field with the default value. Skip to the next field, which is the Web Server's Server Name/IP. For the Test Plan that you are building, all HTTP requests will be sent to the same Web server, jmeter.apache.org. Enter this domain name into the field. This is the only field that we will specify a default, so leave the remaining fields with their default values. :::note The HTTP Request Defaults element does not tell JMeter to send an HTTP request. It simply defines the default values that the HTTP Request elements use. ::: See Figure 4.4 for the completed HTTP Request Defaults element ![Figure 4.4. HTTP Defaults for our Test Plan](/images/screenshots/webtest/http-defaults2.png) _Figure 4.4. HTTP Defaults for our Test Plan_ ## 4.3 Adding Cookie Support Nearly all web testing should use cookie support, unless your application specifically doesn't use cookies. To add cookie support, simply add an [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager) to each [Thread Group](/user-manual/test-plan/#thread_group) in your test plan. This will ensure that each thread gets its own cookies, but shared across all [HTTP Request](/user-manual/component-reference/#HTTP_Request) objects. ![Figure 4.5. HTTP Cookie Manager](/images/screenshots/webtest/http-cookie-manager.png) _Figure 4.5. HTTP Cookie Manager_ To add the [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager), simply select the [Thread Group](/user-manual/test-plan/#thread_group), and choose Add → Config Element → HTTP Cookie Manager, either from the Edit Menu, or from the right-click pop-up menu. ## 4.4 Adding HTTP Requests In our Test Plan, we need to make two HTTP requests. The first one is for the JMeter home page (http://jmeter.apache.org/), and the second one is for the Changes page (http://jmeter.apache.org/changes.html). :::note JMeter sends requests in the order that they appear in the tree. ::: Start by adding the first [HTTP Request](/user-manual/component-reference/#HTTP_Request) to the JMeter Users element (Add → Sampler → HTTP Request). Then, select the HTTP Request element in the tree and edit the following properties (see Figure 4.6): 1. Change the Name field to "Home Page". 2. Set the Path field to "/". Remember that you do not have to set the Server Name field because you already specified this value in the HTTP Request Defaults element. ![Figure 4.6. HTTP Request for JMeter Home Page](/images/screenshots/webtest/http-request1.png) _Figure 4.6. HTTP Request for JMeter Home Page_ Next, add the second HTTP Request and edit the following properties (see Figure 4.7: 1. Change the Name field to "Changes". 2. Set the Path field to "/changes.html". ![Figure 4.7. HTTP Request for JMeter Changes Page](/images/screenshots/webtest/http-request2.png) _Figure 4.7. HTTP Request for JMeter Changes Page_ ## 4.5 Adding a Listener to View Store the Test Results The final element you need to add to your Test Plan is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your HTTP requests in a file and presenting a visual model of the data. Select the JMeter Users element and add a [Graph Results](/user-manual/component-reference/#Graph_Results) listener (Add → Listener → Backend Listener). ## 4.6 Logging in to a web-site It's not the case here, but some web-sites require you to login before permitting you to perform certain actions. In a web-browser, the login will be shown as a form for the user name and password, and a button to submit the form. The button generates a POST request, passing the values of the form items as parameters. To do this in JMeter, add an HTTP Request, and set the method to POST. You'll need to know the names of the fields used by the form, and the target page. These can be found out by inspecting the code of the login page. [If this is difficult to do, you can use the [JMeter Proxy Recorder](/user-manual/component-reference/#HTTP_Proxy_Server) to record the login sequence.] Set the path to the target of the submit button. Click the Add button twice and enter the username and password details. Sometimes the login form contains additional hidden fields. These will need to be added as well. ![Figure 4.8. Sample HTTP login request](/images/screenshots/webtest/http_login.png) _Figure 4.8. Sample HTTP login request_ ## 4.7 choose the same user or different users When creating a Test Plan, on each Thread Group iteration, we can choose to simulate the same user running multiple iterations, or different users running one iteration. You can configure this behaviour on Thread Group element, and have HTTP Cache Manager, HTTP Cookie Manager, HTTP Authorization Manager controlled by this setting. ![Figure 4.9. Choose the same user or different users](/images/screenshots/webtest/threadgroup3.png) _Figure 4.9. Choose the same user or different users_ You can choose to clear the cookies/cache content/authorization in the CookieManager/CacheManager/Authorization Manager, or choose to be controlled by the Thread Group. ![Figure 4.10. Use Thread Group to control CookieManager](/images/screenshots/webtest/threadgroup4.png) _Figure 4.10. Use Thread Group to control CookieManager_ ![Figure 4.11. Use Thread Group to control CacheManager](/images/screenshots/webtest/threadgroup5.png) _Figure 4.11. Use Thread Group to control CacheManager_ ![Figure 4.12. Use Thread Group to control Authorization Manager](/images/screenshots/webtest/threadgroup6.png) _Figure 4.12. Use Thread Group to control Authorization Manager_ {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Try the [Advanced Web Test Plan](/user-manual/build-adv-web-test-plan/) to handle session management and URL rewriting. - [HTTP Request Defaults](/user-manual/component-reference/) - configure common request parameters once - [Best Practices](/user-manual/best-practices/) - optimize thread counts and listener usage - If responses show 403/401, check that your HTTP Request includes required cookies or auth headers - Use [View Results Tree](/user-manual/listeners/) during debugging, but remove it for load tests {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Building an Advanced Web Test Plan URL: https://docs.jmeter.ai/user-manual/build-adv-web-test-plan/ --- {/* SYNCED-BODY:START */} ## 5. Building an Advanced Web Test Plan In this section, you will learn how to create advanced [Test Plans](/user-manual/build-test-plan/) to test a Web site. For an example of a basic Test Plan, see [Building a Web Test Plan](/user-manual/build-web-test-plan/). ## 5.1 Handling User Sessions With URL Rewriting If your web application uses URL rewriting rather than cookies to save session information, then you'll need to do a bit of extra work to test your site. To respond correctly to URL rewriting, JMeter needs to parse the HTML received from the server and retrieve the unique session ID. Use the appropriate [HTTP URL Re-writing Modifier](/user-manual/component-reference/#HTTP_URL_Re_writing_Modifier) to accomplish this. Simply enter the name of your session ID parameter into the modifier, and it will find it and add it to each request. If the request already has a value, it will be replaced. If "Cache Session Id" is checked, then the last found session id will be saved, and will be used if the previous HTTP sample does not contain a session id. #### URL Rewriting Example Download [this example](../demos/URLRewritingExample.jmx). In Figure 1 is shown a test plan using URL rewriting. Note that the URL Re-writing modifier is added to the SimpleController, thus assuring that it will only affect requests under that SimpleController. ![Figure 1 - Test Tree](/images/screenshots/url_rewrite_example_a.png) _Figure 1 - Test Tree_ In Figure 2, we see the URL Re-writing modifier GUI, which just has a field for the user to specify the name of the session ID parameter. There is also a checkbox for indicating that the session ID should be part of the path (separated by a ";"), rather than a request parameter ![Figure 2 - Request parameters](/images/screenshots/url_rewrite_example_b.png) _Figure 2 - Request parameters_ ## 5.2 Using a Header Manager The [HTTP Header Manager](/user-manual/component-reference/#HTTP_Header_Manager) lets you customize what information JMeter sends in the HTTP request header. This header includes properties like "User-Agent", "Pragma", "Referer", etc. The [HTTP Header Manager](/user-manual/component-reference/#HTTP_Header_Manager), like the [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager), should probably be added at the Thread Group level, unless for some reason you wish to specify different headers for the different [HTTP Request](/user-manual/component-reference/#HTTP_Request) objects in your test. {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a Simple Database Test Plan URL: https://docs.jmeter.ai/user-manual/build-db-test-plan/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 6. Building a Database Test Plan In this section, you will learn how to create a basic [Test Plan](/user-manual/build-test-plan/) to test a database server. You will create fifty users that send 2 SQL requests to the database server. Also, you will tell the users to run their tests 100 times. So, the total number of requests is (50 users) x (2 requests) x (repeat 100 times) = 10'000 JDBC requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [JDBC Request](/user-manual/component-reference/#JDBC_Request), [Summary Report](/user-manual/component-reference/#Summary_Report). :::note This example uses the MySQL database driver. To use this driver, its containing `.jar` file (ex. `mysql-connector-java-X.X.X-bin.jar`) must be copied to the JMeter `./lib` directory (see [JMeter's Classpath](/getting-started/get-started/#classpath) for more details). ::: ## 6.1 Adding Users The first step you want to do with every JMeter Test Plan is to add a [Thread Group](/user-manual/test-plan/#thread_group) element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and how many requests they should send. Go ahead and add the ThreadGroup element by first selecting the Test Plan, clicking your right mouse button to get the `Add` menu, and then select **Add → ThreadGroup**. You should now see the Thread Group element under Test Plan. If you do not see the element, then _expand_ the Test Plan tree by clicking on the Test Plan element. Next, you need to modify the default properties. Select the Thread Group element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 6.1 below) ![Figure 6.1. Thread Group with Default Values](/images/screenshots/jdbctest/threadgroup1.png) _Figure 6.1. Thread Group with Default Values_ Start by providing a more descriptive name for our Thread Group. In the name field, enter `JDBC Users`. :::note You will need a valid database, database table, and user-level access to that table. In the example shown here, the database is '`cloud`' and the table name is '`vm_instance`'. ::: Next, increase the number of users to `50`. In the next field, the Ramp-Up Period, leave the value of `10` seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a Ramp-Up Period of 10 seconds, JMeter will finish starting all of your users by the end of the 10 seconds. So, if we have 50 users and a 10 second Ramp-Up Period, then the delay between starting users would be 200 milliseconds (10 seconds / 50 users = 0.2 second per user). If you set the value to 0, then JMeter will immediately start all of your users. Finally, enter a value of `100` in the Loop Count field. This property tells JMeter how many times to repeat your test. To have JMeter repeatedly run your Test Plan, select the Forever checkbox. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: See Figure 6.2 for the completed JDBC Users Thread Group. ![Figure 6.2. JDBC Users Thread Group](/images/screenshots/jdbctest/threadgroup2.png) _Figure 6.2. JDBC Users Thread Group_ ## 6.2 Adding JDBC Requests Now that we have defined our users, it is time to define the tasks that they will be performing. In this section, you will specify the JDBC requests to perform. Begin by selecting the `JDBC Users` element. Click your right mouse button to get the **Add** menu, and then select **Add → Config Element → JDBC Connection Configuration**. Then, select this new element to view its Control Panel (see Figure 6.3). Set up the following fields (these assume we will be using a MySQL database called '`cloud`'): - Variable name (here: `myDatabase`) bound to pool. This needs to uniquely identify the configuration. It is used by the JDBC Sampler to identify the configuration to be used. - Database URL: `jdbc:mysql://ipOfTheServer:3306/cloud` - JDBC Driver class: `com.mysql.cj.jdbc.Driver` - Username: _the username of database_ - Password: _password for the username_ The other fields on the screen can be left as the defaults. JMeter creates a database connection pool with the configuration settings as specified in the Control Panel. The pool is referred to in JDBC Requests in the '`Variable Name`' field. Several different JDBC Configuration elements can be used, but they must have unique names. Every JDBC Request must refer to a JDBC Configuration pool. More than one JDBC Request can refer to the same pool. ![Figure 6.3. JDBC Configuration](/images/screenshots/jdbctest/jdbc-config.png) _Figure 6.3. JDBC Configuration_ Selecting the JDBC Users element again. Click your right mouse button to get the **Add** menu, and then select **Add → Sampler → JDBC Request**. Then, select this new element to view its Control Panel (see Figure 6.4). ![Figure 6.4. JDBC Request](/images/screenshots/jdbctest/JDBCRequest.png) _Figure 6.4. JDBC Request_ In our Test Plan, we will make two JDBC requests. The first one is for select all 'Running' VM instances, and the second is to select 'Expunging' VM instance (obviously you should change these to examples appropriate for your particular database). These are illustrated below. :::note JMeter sends requests in the order that you add them to the tree. ::: Start by editing the following properties (see Figure 6.5): - Change the Name to '`VM Running`'. - Enter the Pool Name: '`myDatabase`' (same as in the configuration element) - Enter the SQL Query String field. - Enter the Parameter values field with '`Running`' value. - Enter the Parameter types with '`VARCHAR`'. ![Figure 6.5. JDBC Request for the first SQL request](/images/screenshots/jdbctest/JDBCRequest2.png) _Figure 6.5. JDBC Request for the first SQL request_ Next, add the second JDBC Request and edit the following properties (see Figure 6.6): - Change the Name to '`VM Expunging`'. - Change the value of Parameter values to '`Expunging`'. ![Figure 6.6. JDBC Request for the second request](/images/screenshots/jdbctest/JDBCRequest3.png) _Figure 6.6. JDBC Request for the second request_ ## 6.3 Adding a Listener to View/Store the Test Results The final element you need to add to your Test Plan is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your JDBC requests in a file and presenting the results. Select the _JDBC Users_ element and add a [Summary Report](/user-manual/component-reference/#Summary_Report) listener (**Add → Listener → Summary Report**). Save the test plan, and run the test with the menu **Run → Start** or `Ctrl + R` The listener shows the results. ![Figure 6.7. Graph results Listener](/images/screenshots/jdbctest/jdbc-results.png) _Figure 6.7. Graph results Listener_ {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Add [Assertions](/user-manual/test-plan/) to validate that SQL responses contain expected data. - [Component Reference](/user-manual/component-reference/) - JDBC Request sampler configuration details - [Listeners](/user-manual/listeners/) - view query results and response times - Forgetting to copy the database driver JAR to JMeter's `lib/` directory - Not setting the JDBC Connection Configuration before the JDBC Request sampler in the test tree {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Building an FTP Test Plan URL: https://docs.jmeter.ai/user-manual/build-ftp-test-plan/ --- {/* SYNCED-BODY:START */} ## 7. Building an FTP Test Plan In this section, you will learn how to create a basic [Test Plan](/user-manual/build-test-plan/) to test an FTP site. You will create four users that send requests for two files on a FTP site. Also, you will tell the users to run their tests twice. So, the total number of requests is (4 users) x (2 requests) x (repeat 2 times) = 16 FTP requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [FTP Request](/user-manual/component-reference/#FTP_Request), [FTP Request Defaults](/user-manual/component-reference/#FTP_Request_Defaults), and [View Results in Table](/user-manual/component-reference/#View_Results_in_Table). ## 7.1 Adding Users The first step you want to do with every JMeter Test Plan is to add a [Thread Group](/user-manual/test-plan/#thread_group) element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and the how many requests they should send. Go ahead and add the Thread Group element by first selecting the Test Plan, clicking your right mouse button to get the Add menu, and then select **Add** → **ThreadGroup.** You should now see the **Thread Group** element under **Test Plan.** If you do not see the element, then "expand" the Test Plan tree by clicking on the **Test Plan** element. Next, you need to modify the default properties. Select the **Thread Group** element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 7.1 below) ![Figure 7.1. Thread Group with Default Values](/images/screenshots/webtest/threadgroup.png) _Figure 7.1. Thread Group with Default Values_ Start by providing a more descriptive name for our **Thread Group.** In the name field, enter 'FTP Users'. Next, increase the number of users to 4. In the next field, the _Ramp-Up_ Period, leave the default value of 0 seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a _Ramp-Up_ Period of 5 seconds, JMeter will finish starting all of your users by the end of the 5 seconds. So, if we have 5 users and a 5 second _Ramp-Up_ Period, then the delay between starting users would be 1 second (5 users / 5 seconds = 1 user per second). If you set the value to 0, then JMeter will immediately start all of your users. Finally, enter a value of 2 in the _Loop Count_ field. This property tells JMeter how many times to repeat your test. To have JMeter repeatedly run your **Test Plan,** select the _Forever_ checkbox. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: See Figure 7.2 for the completed FTP Users Thread Group. ![Figure 7.2. FTP Users Thread Group](/images/screenshots/ftptest/threadgroup2.png) _Figure 7.2. FTP Users Thread Group_ ## 7.2 Adding Default FTP Request Properties Now that we have defined our users, it is time define the tasks that they will be performing. In this section, you will specify the default settings for your FTP requests. And then, in section 7.3, you will add **FTP Request** elements which use some of the default settings you specified here. Begin by selecting the FTP Users element. Click your right mouse button to get the Add menu, and then select **Add** → **Config Element** → FTP Request Defaults. Then, select this new element to view its Control Panel (see Figure 7.3). ![Figure 7.3. FTP Request Defaults](/images/screenshots/ftptest/ftp-defaults.png) _Figure 7.3. FTP Request Defaults_ Like most JMeter elements, the [FTP Request Defaults](/user-manual/component-reference/#FTP_Request_Defaults) Control Panel has a name field that you can modify. In this example, leave this field with the default value. Skip to the next field, which is the FTP Server's Server Name/IP. For the Test Plan that you are building, all FTP requests will be sent to the same FTP server, ftp.domain.com in this case. Enter this domain name into the field. This is the only field that we will specify a default, so leave the remaining fields with their default values. :::note The FTP Request Defaults element does not tell JMeter to send an FTP request. It simply defines the default values that the FTP Request elements use. ::: See Figure 7.4 for the completed FTP Request Defaults element ![Figure 7.4. FTP Defaults for our Test Plan](/images/screenshots/ftptest/ftp-defaults2.png) _Figure 7.4. FTP Defaults for our Test Plan_ ## 7.3 Adding FTP Requests In our **Test Plan**, we need to make two **FTP requests**. :::note JMeter sends requests in the order that they appear in the tree. ::: Start by adding the first [FTP Request](/user-manual/component-reference/#FTP_Request) to the FTP Users element (**Add** → **Sampler** → **FTP Request**). Then, select the **FTP Request** element in the tree and edit the following properties (see Figure 7.5): 1. Change the _Name_ to "File1". 2. Change the _Remote File_ field to "/directory/file1.txt". 3. Change the _Username_ field to "anonymous". 4. Change the _Password_ field to "anonymous@test.com". :::note You do not have to set the _Server Name_ field because you already specified this value in the **FTP Request Defaults** element. ::: ![Figure 7.5. FTP Request for file1](/images/screenshots/ftptest/ftp-request.png) _Figure 7.5. FTP Request for file1_ Next, add the second **FTP Request** and edit the following properties (see Figure 7.6: 1. Change the _Name_ to "File2". 2. Change the _Remote File_ field to "/directory/file2.txt". 3. Change the _Username_ field to "anonymous". 4. Change the _Password_ field to "anonymous@test.com". ![Figure 7.6. FTP Request for file2](/images/screenshots/ftptest/ftp-request2.png) _Figure 7.6. FTP Request for file2_ ## 7.4 Adding a Listener to View/Store the Test Results The final element you need to add to your **Test Plan** is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your **FTP requests** in a file and presenting a visual model of the data. Select the FTP Users element and add a [View Results in Table](/user-manual/component-reference/#View_Results_in_Table) listener (**Add** → **Listener** → **View Results in Table**). Run your test and view the results. ![Figure 7.7. View Results in Table Listener](/images/screenshots/ftptest/ftp-results.png) _Figure 7.7. View Results in Table Listener_ {/* SYNCED-BODY:END */} --- Title: User's Manual: Building an LDAP Test Plan URL: https://docs.jmeter.ai/user-manual/build-ldap-test-plan/ --- {/* SYNCED-BODY:START */} ## 8a. Building an LDAP Test Plan In this section, you will learn how to create a basic Test Plan to test an LDAP server. You will create four users that send requests for four tests on the LDAP server. Also, you will tell the users to run their tests 4 times. So, the total number of requests is (4 users) x (4 requests) x (repeat 4 times) = 64 LDAP requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [LDAP Request](/user-manual/component-reference/#LDAP_Request), [LDAP Request Defaults](/user-manual/component-reference/#LDAP_Request_Defaults), and [View Results in Table](/user-manual/component-reference/#View_Results_in_Table) . This example assumes that the LDAP Server is available at ldap.test.com. ## 8a.1 Adding Users The first step you want to do with every JMeter Test Plan is to add a Thread Group element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and the how many requests they should send. Go ahead and add the ThreadGroup element by first selecting the Test Plan, clicking your right mouse button to get the **Add** menu, and then select **Add → ThreadGroup**. You should now see the Thread Group element under Test Plan. If you do not see the element, then "expand" the Test Plan tree by clicking on the Test Plan element. ![Figure 8a.1. Thread Group and final test tree](/images/screenshots/ldaptest/threadgroup.png) _Figure 8a.1. Thread Group and final test tree_ ## 8a.2 Adding Login Config Element Begin by selecting the `LDAP Users` element. Click your right mouse button to get the Add menu, and then select **Add → Config Element → Login Config Element**. Then, select this new element to view its Control Panel. Like most JMeter elements, the `Login Config Element`'s Control Panel has a name field that you can modify. In this example, leave this field with the default value. ![Figure 8a.2 Login Config Element for our Test Plan](/images/screenshots/ldaptest/login-config-element.png) _Figure 8a.2 Login Config Element for our Test Plan_ :::note Enter Username field to "your LDAP Username", The password field to "your LDAP Password" These values will be used by the LDAP Requests. ::: ## 8a.3 Adding LDAP Request Defaults Begin by selecting the `LDAP Users` element. Click your right mouse button to get the **Add** menu, and then select **Add → Config Element → LDAP Request Defaults**. Then, select this new element to view its Control Panel. Like most JMeter elements, the `LDAP Request Defaults` Control Panel has a name field that you can modify. In this example, leave this field with the default value. ![Figure 8a.3 LDAP Defaults for our Test Plan](/images/screenshots/ldaptest/requestdefaults.png) _Figure 8a.3 LDAP Defaults for our Test Plan_ :::note Enter `DN` field to "`your LDAP Root Distinguished Name`". Enter LDAP Server's `Servername` field to "`ldap.test.com`". The `port` to `389`. These values are default for the LDAP Requests. ::: ## 8a.4 Adding LDAP Requests In our Test Plan, we need to make four LDAP requests. 1. Inbuilt Add Test 2. Inbuilt Search Test 3. Inbuilt Modify Test 4. Inbuilt Delete Test JMeter sends requests in the order that you add them to the tree. Start by adding the first LDAP Request to the LDAP Users element (**Add → Sampler → LDAP Request**). Then, select the LDAP Request element in the tree and edit the following properties 1. Rename to "`Add`" this element 2. Select the `Add Test` radio button in `Test Configuration` group ![Figure 8a.4.1 LDAP Request for Inbuilt Add test](/images/screenshots/ldaptest/add.png) _Figure 8a.4.1 LDAP Request for Inbuilt Add test_ You do not have to set the `Servername` field, `port` field, `Username`, `Password` and `DN` because you already specified this value in the `Login Config Element` and `LDAP Request Defaults.` Next, add the second LDAP Request and edit the following properties 1. Rename to "`Search`" this element 2. Select the `Search Test` radio button in `Test Configuration` group Next, add the Third LDAP Request and edit the following properties ![Figure 8a.4.2 LDAP Request for Inbuilt Search test](/images/screenshots/ldaptest/search.png) _Figure 8a.4.2 LDAP Request for Inbuilt Search test_ 1. Rename to "`Modify`" this element 2. Select the `Modify Test` radio button in `Test Configuration` group Next, add the fourth LDAP Request and edit the following properties ![Figure 8a.4.3 LDAP Request for Inbuilt Modify test](/images/screenshots/ldaptest/modify.png) _Figure 8a.4.3 LDAP Request for Inbuilt Modify test_ 1. Rename to "`Delete`" this element 2. Select the `Delete Test` radio button in `Test Configuration` group ![Figure 8a.4.4 LDAP Request for Inbuilt Delete test](/images/screenshots/ldaptest/delete.png) _Figure 8a.4.4 LDAP Request for Inbuilt Delete test_ ## 8a.5 Adding a Response Assertion You can add a Response Assertion element. This element will check the received response data by verifying if the response text is "`successful`". (**Add → Assertion → Response Assertion**). :::note Note: A this position in the tree, the Response Assertion will be executed for each LDAP Request. ::: 1. Select `Text Response` Radio button in `Response Field to Test` group 2. Select `Substring` Radio button in `Pattern Matching Rules` group 3. Click on `Add` button and add the string "`successful`" in `Pattern to Test` field ![Figure 8a.5 LDAP Response Assertion](/images/screenshots/ldaptest/responseassertion.png) _Figure 8a.5 LDAP Response Assertion_ ## 8a.6 Adding a Listener to View/Store the Test Results The final element you need to add to your Test Plan is a Listener. This element is responsible for storing all of the results of your LDAP requests in a file and presenting a visual model of the data. Select the LDAP Users element and add a View Results in Table (**Add → Listener → View Results in Table**) ![Figure 8a.6 View Results in Table Listener](/images/screenshots/ldaptest/viewtable.png) _Figure 8a.6 View Results in Table Listener_ {/* SYNCED-BODY:END */} --- Title: User's Manual: Building an Extended LDAP Test Plan URL: https://docs.jmeter.ai/user-manual/build-ldapext-test-plan/ --- {/* SYNCED-BODY:START */} ## 8b. Building an Extended LDAP Test Plan In this section, you will learn how to create a basic Test Plan to test an LDAP server. As the Extended LDAP Sampler is highly configurable, this also means that it takes some time to build a correct testplan. You can however tune it exactly up to your needs. You will create 1 user that send requests for nine tests on the LDAP server. Also, you will tell the users to run their tests one time. So, the total number of requests is `(1 user) x (9 requests) x (repeat 1 time) = 9` LDAP requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [Adding LDAP Extended Request Defaults](/user-manual/component-reference/#Adding_LDAP_Extended_Request_Defaults), [Adding LDAP Requests](/user-manual/component-reference/#Adding_LDAP_Requests), and [Adding a Listener to View/Store the Test Results](/user-manual/component-reference/#Adding_a_Listener_to_View_Store_the_Test_Results) This example assumes that the LDAP Server is available at `ldap.test.com`. For the less experienced LDAP users, I build a [small LDAP tutorial](/ldapops-tutor/) which shortly explains the several LDAP operations that can be used in building a complex testplan. Take care when using LDAP special characters in the distinguished name, in that case (e.g. you want to use a `+` sign in a distinguished name) you need to escape the character by adding an "`\`" sign before that character. Extra exception: if you want to add a `\` character in a distinguished name (in an add or rename operation), you need to use 4 backslashes. Examples: **`cn=dolf\+smits`** : to add/search an entry with the name like `cn=dolf+smits` **`cn=dolf \\ smits`** : to search an entry with the name `cn=dolf \ smits` **`cn=c:\\\\log.txt`** : to add an entry with a name like `cn=c:\log.txt` ### 8b.1 Adding Users The first step you want to do with every JMeter Test Plan is to add a Thread Group element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and the how many requests they should send. Go ahead and add the `Thread Group` element by first selecting the `Test Plan`, clicking your right mouse button to get the `Add` menu, and then select `Add`→`Threads (Users)`→`Thread Group`. You should now see the `Thread Group` element under `Test Plan`. If you do not see the element, then "expand" the Test Plan tree by clicking on the Test Plan element. ![Figure 8b.1. Thread Group with Default Values](/images/screenshots/ldaptest/extthreadgroup.png) _Figure 8b.1. Thread Group with Default Values_ ### 8b.2 Adding LDAP Extended Request Defaults Begin by selecting the LDAP Ext Users element. Click your right mouse button to get the `Add` menu, and then select `Add`→`Config Element`→`LDAP Extended Request Defaults`. Then, select this new element to view its Control Panel. Like most JMeter elements, the `LDAP Extended Request Defaults` Control Panel has a name field that you can modify. In this example, leave this field with the default value. ![Figure 8b.2 LDAP Defaults for our Test Plan](/images/screenshots/ldaptest/extrequestdefaults.png) _Figure 8b.2 LDAP Defaults for our Test Plan_ For each of the different operations, some default values can be filled in. In All cases, when a default is filled in, this is used for the LDAP extended requests. For each request, you can override the defaults by filling in the values in the LDAP extended request sampler. When no value is entered which is necessary for a test, the test will fail in an unpredictable way! We will not enter any default values here, as we will build a very small testplan, so we will explain all the different fields when we add the LDAP Extended samplers. ### 8b.3 Adding LDAP Requests In our Test Plan, we want to use all 9 LDAP requests. 1. Thread bind 2. Search Test 3. Compare Test 4. Single bind/unbind Test 5. Add Test 6. Modify Test 7. Rename entry (moddn) 8. Delete Test 9. Thread unbind JMeter sends requests in the order that you add them to the tree. Adding a requests always start by: Adding the `LDAP Extended Request` to the LDAP Ext Users element (`Add`→ `Sampler`→`LDAP Ext Request`). Then, select the `LDAP Ext Request` element in the tree and edit the following properties. #### 8b.3.1 Adding a Thread bind Request 1. Rename the element: "`1. Thread bind`" 2. Select the "`Thread bind`" button. 3. Enter the hostname value from the LDAP server in the Servername field 4. Enter the portnumber from the LDAP server (`636` : ldap over SSL) in the port field 5. _(Optional)_ Enter the baseDN in the DN field, this baseDN will be used as the starting point for searches, add, deletes, etc. take care that this must be the uppermost shared level for all your request, e.g. when all information is stored under `ou=Users, dc=test, dc=com`, you can use this value in the basedn. 6. _(Optional)_ Enter the distinguished name from the user you want to use for authentication. When this field is kept empty, an anonymous bind will be established. 7. _(Optional)_ Enter the password for the user you want to authenticate with, an empty password will also lead to an anonymous bind. 8. _(Optional)_ Enter a value for the connection timeout with LDAP 9. _(Optional)_ Check the box Use Secure LDAP Protocol if you access with LDAP over SSL (ldaps) 10. _(Optional)_ Check the box TrustAll if you want the client to trust all certificates ![Figure 8b.3.1. Thread Bind example](/images/screenshots/ldaptest/extthreadbind.png) _Figure 8b.3.1. Thread Bind example_ #### 8b.3.2 Adding a search Request 1. Rename the element: "`2. Search Test`" 2. Select the "`Search Test`" button. 3. _(Optional)_ enter the searchbase under which you want to perform the search, relative to the basedn, used in the thread bind request. When left empty, the basedn is used as a search base, this files is important if you want to use a "base-entry" or "one-level" search (see below) 4. Enter the searchfilter, any decent LDAP search filter will do, but for now, use something simple, like `(sn=Doe)` or `(cn=*)` 5. _(Optional)_ Enter the scope in the scope field, it has three options: 1. baseobject search only the given searchbase is used, only for checking attributes or existence. 2. onelevel search Only search in one level below given searchbase is used 3. subtree search Searches for object at any point below the given basedn 6. _(Optional)_ Size limit, specifies the maximum number of returned entries, 7. _(Optional)_ Time limit, specifies the maximum number of milliseconds, the SERVER can use for performing the search. It is NOT the maximum time the application will wait. When a very large returnset is returned, from a very fast server, over a very slow line, you may have to wait for ages for the completion of the search request, but this parameter will not influence this. 8. _(Optional)_ Attributes you want in the search answer. This can be used to limit the size of the answer, especially when an object has very large attributes (like `jpegPhoto`). There are three possibilities: 1. Leave empty (the default setting must also be empty) This will return all attributes. 2. Put in one empty value (`""`), it will request a non-existent attributes, so in reality it returns no attributes 3. Put in the attributes, separated by a semi-colon. It will return only the requested attributes 9. _(Optional)_ Return object. Checked will return all java-object attributes, it will add these to the requested attributes, as specified above. Unchecked will mean no java-object attributes will be returned. 10. _(Optional)_ Dereference aliases. Checked will mean it will follow references, Unchecked says it will not. 11. _(Optional)_ Parse the search results. Checked will mean it gets all results in response data, Unchecked says it will not. ![Figure 8b.3.2. search request example](/images/screenshots/ldaptest/extsearch.png) _Figure 8b.3.2. search request example_ #### 8b.3.3 Adding a Compare Request 1. Rename the element: "`3. Compare Test`" 2. Select the "`Compare`" button. 3. enter the entryname form the object on which you want the compare operation to work, relative to the basedn, e.g. "`cn=jdoe,ou=Users`" 4. Enter the compare filter, this must be in the form "`attribute=value`", e.g. "`mail=jdoe@test.com`" ![Figure 8b.3.3. Compare example](/images/screenshots/ldaptest/extcompare.png) _Figure 8b.3.3. Compare example_ #### 8b.3.4 Adding a Single bind/unbind 1. Rename the element: "`4. Single bind/unbind Test`" 2. Select the "`Single bind/unbind`" button. 3. Enter the FULL distinguished name from the user you want to use for authentication. E.g. `cn=jdoe,ou=Users,dc=test,dc=com` When this field is kept empty, an anonymous bind will be established. 4. Enter the password for the user you want to authenticate with, an empty password will also lead to an anonymous bind. **Take care**: This single bind/unbind is in reality two separate operations but cannot easily be split! ![Figure 8b.3.4. Single bind/unbind example](/images/screenshots/ldaptest/extsbind.png) _Figure 8b.3.4. Single bind/unbind example_ #### 8b.3.5 Adding an Add Request 1. Rename the element: "`5. Add Test`" 2. Select the "`Add`" button. 3. Enter the distinguished name for the object to add, relative to the basedn. 4. Add a line in the "`add test`" table, fill in the attribute and value. When you need the same attribute more than once, just add a new line, add the attribute again, and a different value. All necessary attributes and values must be specified to pass the test, see picture! (sometimes the server adds the attribute "`objectClass=top`", this might give a problem. ![Figure 8b.3.5. Add request example](/images/screenshots/ldaptest/extadd.png) _Figure 8b.3.5. Add request example_ #### 8b.3.6 Adding a Modify Request 1. Rename the element: "`6. Modify Test`" 2. Select the "`Modify test`" button. 3. Enter the distinguished name for the object to modify, relative to the basedn. 4. Add a line in the "`modify test`" table, with the "`add`" button. 5. You need to enter the attribute you want to modify, (optional) a value, and the opcode. The meaning of this opcode: **`add`** : this will mean that the attribute value (not optional in this case) will be added to the attribute. When the attribute is not existing, it will be created and the value added When it is existing, and defined multi-valued, the new value is added. when it is existing, but single valued, it will fail. **`replace`** : This will overwrite the attribute with the given new value (not optional here) When the attribute is not existing, it will be created and the value added When it is existing, old values are removed, the new value is added. **`delete`** : When no value is given, all values will be removed When a value is given, only that value will be removed when the given value is not existing, the test will fail 6. _(Optional)_ Add more modifications in the "`modify test`" table. All modifications which are specified must succeed, to let the modification test pass. When one modification fails, NO modifications at all will be made and the entry will remain unchanged. ![Figure 8b.3.6. Modify example](/images/screenshots/ldaptest/extmod.png) _Figure 8b.3.6. Modify example_ #### 8b.3.7 Adding a Rename Request (moddn) 1. Rename the element: "`7. Rename entry (moddn)`" 2. Select the "`Rename Entry`" button. 3. Enter the name of the entry, relative to the baseDN, in the "`old entry name`"-Field. that is, if you want to rename "`cn=Little John Doe,ou=Users`", and you set the baseDN to "`dc=test,dc=com`", you need to enter "`cn=John Junior Doe,ou=Users`" in the `old entry name`-Field. 4. Enter the new name of the entry, relative to the baseDN, in the "`new distinguished name`"-Field. when you only change the RDN, it will simply rename the entry when you also add a different subtree, e.g. you change from `cn=john doe,ou=Users` to `cn=john doe,ou=oldusers`, it will move the entry. You can also move a complete subtree (If your LDAP server supports this!), e.g. `ou=Users,ou=retired`, to `ou=oldusers,ou=users`, this will move the complete subtree, plus all retired people in the subtree to the new place in the tree. ![Figure 8b.3.7. Rename example](/images/screenshots/ldaptest/extmoddn.png) _Figure 8b.3.7. Rename example_ #### 8b.3.8 Adding a Delete Request 1. Rename the element: "`8. Delete Test`" 2. Select the "`Delete`" button. 3. Enter the name of the entry, relative to the baseDN, in the `Delete`-Field. that is, if you want to remove "`cn=John Junior Doe,ou=Users,dc=test,dc=com`", and you set the baseDN to "`dc=test,dc=com`", you need to enter "`cn=John Junior Doe,ou=Users`" in the `Delete`-field. ![Figure 8b.3.8. Delete example](/images/screenshots/ldaptest/extdel.png) _Figure 8b.3.8. Delete example_ #### 8b.3.9 Adding an unbind Request 1. Rename the element: "`9. Thread unbind`" 2. Select the "`Thread unbind`" button. This will be enough as it just closes the current connection. The information which is needed is already known by the system ![Figure 8b.3.9. Unbind example](/images/screenshots/ldaptest/extthreadunbind.png) _Figure 8b.3.9. Unbind example_ ### 8b.4 Adding a Listener to View/Store the Test Results The final element you need to add to your Test Plan is a Listener. This element is responsible for storing all of the results of your LDAP requests in a file and presenting a visual model of the data. Select the Thread group element and add a `View Results Tree` (`Add`→`Listener`→`View Results Tree`) ![Figure 8b.4. View Result Tree Listener](/images/screenshots/ldaptest/extviewtree.png) _Figure 8b.4. View Result Tree Listener_ In this listener you have three tabs to view, the sampler result, the request and the response data. 1. The sampler result just contains the response time, the returncode and return message 2. The request gives a short description of the request that was made, in practice no relevant information is contained here. 3. The response data contains the full details of the sent request, as well the full details of the received answer, this is given in a (self defined) xml-style. [The full description can be found here.](/ldapanswer-xml/) {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a SOAP WebService Test Plan URL: https://docs.jmeter.ai/user-manual/build-ws-test-plan/ --- {/* SYNCED-BODY:START */} ## 9. Building a WebService Test Plan In this section, you will learn how to create a [Test Plan](/user-manual/build-test-plan/) to test a WebService. You will create five users that send requests to One page. Also, you will tell the users to run their tests twice. So, the total number of requests is (5 users) x (1 requests) x (repeat 2 times) = 10 HTTP requests. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [HTTP Request](/user-manual/component-reference/#HTTP_Request), and [Aggregate Graph](/user-manual/component-reference/#Aggregate_Graph). If the sampler appears to be getting an error from the webservice, double check the SOAP message and make sure the format is correct. In particular, make sure the `xmlns` attributes are exactly the same as the WSDL. If the xml namespace is different, the webservice will likely return an error. ## 9.1 Creating WebService Test Plan In our Test Plan, we will use a .NET webservice. We won't go into the details of writing a webservice. If you don't know how to write a webservice, google for webservice and familiarize yourself with writing webservices for Java and .NET. It should be noted there is a significant difference between how .NET and Java implement webservices. The topic is too broad to cover in the user manual. Please refer to other sources to get a better idea of the differences. :::note JMeter sends requests in the order that they appear in the tree. ::: Start by using menu **File → Templates…** and select template "`Building a SOAP Webservice Test Plan`". Then, click "`Create`" button. ![Figure 9.1.0. Webservice Template](/images/screenshots/ws_template.png) _Figure 9.1.0. Webservice Template_ Change the following: 1. In "`HTTP Request Defaults`" change "`Server Name of IP`" 2. In "`Soap Request`", change "`Path:`" ![Figure 9.1.1 Webservice Path](/images/screenshots/ws_http_request.png) _Figure 9.1.1 Webservice Path_ Next, select "`HTTP Header Manager`" and update "`SOAPAction`" header to match your webservice. Some webservices may not use SOAPAction in this case remove it. Currently, only .NET uses SOAPAction, so it is normal to have a blank SOAPAction for all other webservices. The list includes JWSDP, Weblogic, Axis, The Mind Electric Glue, and gSoap. ![Figure 9.1.2 Webservice Headers](/images/screenshots/ws_header.png) _Figure 9.1.2 Webservice Headers_ The last step is to paste the SOAP message in the "`Body Data`" text area. ![Figure 9.1.3 Webservice Body](/images/screenshots/ws_http_request.png) _Figure 9.1.3 Webservice Body_ ## 9.2 Adding Users The [Thread Group](/user-manual/test-plan/#thread_group) tells JMeter the number of users you want to simulate, how often the users should send requests, and the how many requests they should send. Select the Thread Group element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 9.2 below) ![Figure 9.2. Thread Group with Default Values](/images/screenshots/webtest/threadgroup.png) _Figure 9.2. Thread Group with Default Values_ Start by providing a more descriptive name for our Thread Group. In the name field, enter JMeter Users. Next, increase the number of users (called threads) to 10. In the next field, the Ramp-Up Period, leave the default value of 0 seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a Ramp-Up Period of 5 seconds, JMeter will finish starting all of your users by the end of the 5 seconds. So, if we have 5 users and a 5 second Ramp-Up Period, then the delay between starting users would be 1 second (5 users / 5 seconds = 1 user per second). If you set the value to 0, then JMeter will immediately start all of your users. Finally, clear the checkbox labeled "`Forever`", and enter a value of `2` in the Loop Count field. This property tells JMeter how many times to repeat your test. If you enter a loop count value of `0`, then JMeter will run your test only once. To have JMeter repeatedly run your Test Plan, select the `Forever` checkbox. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: See Figure 9.2 for the completed JMeter Users Thread Group. ![Figure 9.3. JMeter Users Thread Group](/images/screenshots/webtest/threadgroup2.png) _Figure 9.3. JMeter Users Thread Group_ ## 9.3 Adding a Listener to View Store the Test Results The final element you need to add to your Test Plan is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your HTTP requests in a file and presenting a visual model of the data. Select the JMeter Users element and add a [Aggregate Graph](/user-manual/component-reference/#Aggregate_Graph) listener (**Add → Listener → Aggregate Graph**). Next, you need to specify a directory and filename of the output file. You can either type it into the filename field, or select the Browse button and browse to a directory and then enter a filename. ![Figure 9.4. Graph Results Listener](/images/screenshots/ws_listener.png) _Figure 9.4. Graph Results Listener_ ## 9.4 Rest Webservice Testing a REST Webservice is very similar as you only need to modify in HTTP Request - `Method`: to select the one you want to test - `Body Data`: which can be JSON, XML or any custom text You may also need to modify "`HTTP Header Manager`" to select the correct "`Content-Type`" {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a JMS (Java Messaging Service) Point-to-Point Test Plan URL: https://docs.jmeter.ai/user-manual/build-jms-point-to-point-test-plan/ --- {/* SYNCED-BODY:START */} ## 10. Building a JMS Point-to-Point Test Plan :::note Make sure the required jar files are in JMeter's `lib` directory. If they are not, shutdown JMeter, copy the jar files over and restart JMeter. See [Getting Started](/getting-started/get-started/#libraries_activemq) for details. ::: In this section, you will learn how to create a [Test Plan](/user-manual/build-test-plan/) to test a JMS Point-to-Point messaging solution. The setup of the test is 1 threadgroup with 5 threads sending 4 messages each through a request queue. A fixed reply queue will be used for monitoring the reply messages. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [JMS Point-to-Point](/user-manual/component-reference/#JMS_Point_to_Point), and [Graph Results](/user-manual/component-reference/#Graph_Results). General notes on JMS: There are currently two JMS samplers. One uses JMS topics and the other uses queues. Topic messages are commonly known as pub/sub messaging. Topic messaging is generally used in cases where a message is published by a producer and consumed by multiple subscribers. A JMS sampler needs the JMS implementation jar files; for example, from Apache ActiveMQ. See [here](/getting-started/get-started/#libraries_activemq) for the list of jars provided by ActiveMQ. ## 10.1 Adding a Thread Group The first step you want to do with every JMeter Test Plan is to add a [Thread Group](/user-manual/test-plan/#thread_group) element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and the how many requests they should send. Go ahead and add the ThreadGroup element by first selecting the Test Plan, clicking your right mouse button to get the **Add** menu, and then select **Add → ThreadGroup**. You should now see the Thread Group element under Test Plan. If you do not see the element, then "expand" the Test Plan tree by clicking on the Test Plan element. Next, you need to modify the default properties. Select the Thread Group element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 10.1 below) ![Figure 10.1. Thread Group with Default Values](/images/screenshots/webtest/threadgroup.png) _Figure 10.1. Thread Group with Default Values_ Start by providing a more descriptive name for our Thread Group. In the name field, enter `Point-to-Point`. Next, increase the number of users (called threads) to `5`. In the next field, the Ramp-Up Period, leave set the value to 0 seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a Ramp-Up Period of 5 seconds, JMeter will finish starting all of your users by the end of the 5 seconds. So, if we have 5 users and a 5 second Ramp-Up Period, then the delay between starting users would be 1 second (5 users / 5 seconds = 1 user per second). If you set the value to 0, then JMeter will immediately start all of your users. Clear the checkbox labeled "`Forever`", and enter a value of `4` in the Loop Count field. This property tells JMeter how many times to repeat your test. If you enter a loop count value of `0`, then JMeter will run your test only once. To have JMeter repeatedly run your Test Plan, select the `Forever` checkbox. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: ## 10.2 Adding JMS Point-to-Point Sampler Start by adding the sampler [JMS Point-to-Point](/user-manual/component-reference/#JMS_Point_to_Point) to the Point-to-Point element (**Add → Sampler → JMS Point-to-Point**). Then, select the JMS Point-to-Point sampler element in the tree. In building the example a configuration will be provided that works with ActiveMQ 3.0. | | | | | --- | --- | --- | | JMS Resources | | QueueConnectionFactory | `ConnectionFactory` | This is the default JNDI entry for the connection factory within ActiveMQ. | | JNDI Name Request Queue | `Q.REQ` | This is equal to the JNDI name defined in the JNDI properties. | | JNDI Name Reply Queue | `Q.RPL` | This is equal to the JNDI name defined in the JNDI properties. | | Message Properties | | Communication Style | `Request Response` | This means that you need at least a service running outside of JMeter and that will respond to the requests. This service must listen to the Request Queue and send messages to the queue referenced by the `message.getJMSReplyTo()` | | Content | `test` | This is just the content of the message. | | JMS Properties | | Nothing needed for ActiveMQ. | | JNDI Properties | | InitialContextFactory | `org.apache.activemq.jndi.ActiveMQInitialContextFactory` | The standard InitialContextFactory for ActiveMQ | | Properties | | `queue.Q.REQ` | `example.A` | This defines a JNDI name `Q.REQ` for the request queue that points to the queue `example.A` | | `queue.Q.RPL` | `example.B` | This defines a JNDI name `Q.RPL` for the reply queue that points to the queue `example.B` | | Provider URL | | Provider URL | `tcp://localhost:61616` | This defines the URL of the ActiveMQ messaging system. | ## 10.3 Adding a Listener to View Store the Test Results The final element you need to add to your Test Plan is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your JMS requests in a file and presenting a visual model of the data. Select the Thread Group element and add a [Graph Results](/user-manual/component-reference/#Graph_Results) listener (**Add → Listener → Graph Results**). Next, you need to specify a directory and filename of the output file. You can either type it into the filename field, or select the Browse button and browse to a directory and then enter a filename. ![Figure 10.2. Graph Results Listener](/images/screenshots/graph_results.png) _Figure 10.2. Graph Results Listener_ {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a JMS (Java Messaging Service) Test Plan URL: https://docs.jmeter.ai/user-manual/build-jms-topic-test-plan/ --- {/* SYNCED-BODY:START */} ## 11. Building a JMS Topic Test Plan :::note JMS requires some optional jars to be downloaded. Please refer to [Getting Started](/getting-started/get-started/) for full details. ::: In this section, you will learn how to create a [Test Plan](/user-manual/build-test-plan/) to test JMS Providers. You will create five subscribers and one publisher. You will create 2 thread groups and set each one to 10 iterations. The total messages is (6 threads) x (1 message) x (repeat 10 times) = 60 messages. To construct the Test Plan, you will use the following elements: [Thread Group](/user-manual/test-plan/#thread_group), [JMS Publisher](/user-manual/component-reference/#JMS_Publisher), [JMS Subscriber](/user-manual/component-reference/#JMS_Subscriber), and [Graph Results](/user-manual/component-reference/#Graph_Results). General notes on JMS: There are currently two JMS samplers. One uses JMS topics and the other uses queues. Topic messages are commonly known as pub/sub messaging. Topic messaging is generally used in cases where a message is published by a producer and consumed by multiple subscribers. Queue messaging is generally used for transactions where the sender expects a response. Messaging systems are quite different from normal HTTP requests. In HTTP, a single user sends a request and gets a response. Messaging system can work in synchronous and asynchronous mode. A JMS sampler needs the JMS implementation jar files; for example, from Apache ActiveMQ. See [here](/getting-started/get-started/#libraries_activemq) for the list of jars provided by ActiveMQ. ## 11.1 Adding Users The first step is add a [Thread Group](/user-manual/test-plan/#thread_group) element. The Thread Group tells JMeter the number of users you want to simulate, how often the users should send requests, and how many requests they should send. Go ahead and add the ThreadGroup element by first selecting the Test Plan, clicking your right mouse button to get the **Add** menu, and then select **Add → ThreadGroup**. You should now see the Thread Group element under Test Plan. If you do not see the element, then "expand" the Test Plan tree by clicking on the Test Plan element. Next, you need to modify the default properties. Select the Thread Group element in the tree, if you have not already selected it. You should now see the Thread Group Control Panel in the right section of the JMeter window (see Figure 11.1 below) ![Figure 11.1. Thread Group with Default Values](/images/screenshots/webtest/threadgroup.png) _Figure 11.1. Thread Group with Default Values_ Start by providing a more descriptive name for our Thread Group. In the name field, enter `Subscribers`. Next, increase the number of users (called threads) to `5`. In the next field, the Ramp-Up Period, set the value to `0` seconds. This property tells JMeter how long to delay between starting each user. For example, if you enter a Ramp-Up Period of 5 seconds, JMeter will finish starting all of your users by the end of the 5 seconds. So, if we have 5 users and a 5 second Ramp-Up Period, then the delay between starting users would be 1 second (5 users / 5 seconds = 1 user per second). If you set the value to 0, JMeter will immediately start all users. Clear the checkbox labeled "`Forever`", and enter a value of `10` in the Loop Count field. This property tells JMeter how many times to repeat your test. If you enter a loop count value of `0`, then JMeter will run your test only once. To have JMeter repeatedly run your Test Plan, select the `Forever` checkbox. Repeat the process and add another thread group. For the second thread group, enter "`Publisher`" in the name field, set the number of threads to `1`, and set the iteration to `10`. :::note In most applications, you have to manually accept changes you make in a Control Panel. However, in JMeter, the Control Panel automatically accepts your changes as you make them. If you change the name of an element, the tree will be updated with the new text after you leave the Control Panel (for example, when selecting another tree element). ::: ## 11.2 Adding JMS Subscriber and Publisher Make sure the required jar files are in JMeter's `lib` directory. If they are not, shutdown JMeter, copy the jar files over and restart JMeter. Start by adding the sampler [JMS Subscriber](/user-manual/component-reference/#JMS_Subscriber) to the Subscribers element (**Add → Sampler → JMS Subscriber**). Then, select the JMS Subscriber element in the tree and edit the following properties: 1. Change the Name field to "`Sample Subscriber`" 2. If the JMS provider uses the `jndi.properties` file, check the box 3. Enter the name of the InitialContextFactory class. For example, with ActiveMQ 5.4, the value is "`org.apache.activemq.jndi.ActiveMQInitialContextFactory`" 4. Enter the provider URL. This is the URL for the JNDI server, if there is one. For example, with ActiveMQ 5.4 on local machine with default port, the value is "`tcp://localhost:61616`" 5. Enter the name of the connection factory. Please refer to the documentation of the JMS provider for the information. For ActiveMQ, the default is "`ConnectionFactory`" 6. Enter the name of the message topic. For ActiveMQ Dynamic Topics (create topics dynamically), example value is "`dynamicTopics/MyStaticTopic1`" :::note Note: Setup at startup mean that JMeter starting to listen on the Destination at beginning of test without name change possibility. Setup on Each sample mean that JMeter (re)starting to listen before run each JMS Subscriber sample, this last option permit to have Destination name with some JMeter variables ::: 7. If the JMS provider requires authentication, check "`required`" and enter the username and password. For example, Orion JMS requires authentication, while ActiveMQ and MQSeries does not 8. Enter `10` in "`Number of samples to aggregate`". For performance reasons, the sampler will aggregate messages, since small messages will arrive very quickly. If the sampler didn't aggregate the messages, JMeter wouldn't be able to keep up. 9. If you want to read the response, check the box 10. There are two client implementations for subscribers. If the JMS provider exhibits zombie threads with one client, try the other. ![Figure 11.2. JMS Subscriber](/images/screenshots/jms/jms_sub.png) _Figure 11.2. JMS Subscriber_ Next add the sampler [JMS Publisher](/user-manual/component-reference/#JMS_Publisher) to the Publisher element (**Add → Sampler → JMS Publisher**). Then, select the JMS Publisher element in the tree and edit the following properties: 1. Change the Name field to "`Sample Publisher`". 2. If the JMS provider uses the `jndi.properties` file, check the box 3. Enter the name of the InitialContextFactory class. For example, with ActiveMQ 5.4, the value is "`org.apache.activemq.jndi.ActiveMQInitialContextFactory`" 4. Enter the provider URL. This is the URL for the JNDI server, if there is one. For example, with ActiveMQ 5.4 on local machine with default port, the value is "`tcp://localhost:61616`" 5. Enter the name of the connection factory. Please refer to the documentation of the JMS provider for the information. For ActiveMQ, the default is "`ConnectionFactory`" 6. Enter the name of the message topic. For ActiveMQ Dynamic Topics (create topics dynamically), example value is "`dynamicTopics/MyStaticTopic1`". :::note Note: Setup at startup mean that JMeter starting connection with the Destination at beginning of test without name change possibility. Setup on Each sample mean that JMeter (re)starting the connection before run each JMS Publisher sample, this last option permit to have Destination name with some JMeter variables ::: 7. If the JMS provider requires authentication, check "`required`" and enter the username and password. For example, Orion JMS requires authentication, while ActiveMQ and MQSeries does not 8. Enter `10` in "`Number of samples to aggregate`". For performance reasons, the sampler will aggregate messages, since small messages will arrive very quickly. If the sampler didn't aggregate the messages, JMeter wouldn't be able to keep up. 9. Select the appropriate configuration for getting the message to publish. If you want the sampler to randomly select the message, place the messages in a directory and select the directory using browse. 10. Select the message type. If the message is in object format or map message, make sure the message is generated correctly. ![Figure 11.3. JMS Publisher](/images/screenshots/jms/jms_pub.png) _Figure 11.3. JMS Publisher_ ## 11.3 Adding a Listener to View Store the Test Results The final element you need to add to your Test Plan is a [Listener](/user-manual/component-reference/#listeners). This element is responsible for storing all of the results of your HTTP requests in a file and presenting a visual model of the data. Select the Test Plan element and add a [Graph Results](/user-manual/component-reference/#Graph_Results) listener (**Add → Listener → Graph Results**). Next, you need to specify a directory and filename of the output file. You can either type it into the filename field, or select the Browse button and browse to a directory and then enter a filename. ![Figure 11.4. Graph Results Listener](/images/screenshots/graph_results.png) _Figure 11.4. Graph Results Listener_ {/* SYNCED-BODY:END */} --- Title: User's Manual: Building a Test Plan Programmatically URL: https://docs.jmeter.ai/user-manual/build-programmatic-test-plan/ --- {/* SYNCED-BODY:START */} ## Building a Test Plan Programmatically :::note JMeter 5.6 brings experimental classes and methods to build test plans programmatically, so please feel free to provide your feedback. ::: In this section, you will learn how to create a [Test Plan](/user-manual/build-test-plan/) with JMeter APIs. The Test Plan is a collection of elements arranged in a tree-like manner. However, in JMeter APIs, the elements do not form a tree. Parent-child relationships are stored in a separate structure: `ListedHashTree`. ## Creating a plan with low-level APIs Let us create `Test Plan => Thread Group => Debug Sampler` plan ``` ListedHashTree root = new ListedHashTree(); // (1) TestPlan testPlan = new TestPlan(); ListedHashTree testPlanSubtree = root.add(testPlan); // (2) TestPlan threadGroup = new ThreadGroup(); threadGroup.setName("Search Order Thread Group"); ListedHashTree threadGroupSubtree = testPlanSubtree.add(threadGroup); // (3) DebugSampler debugSampler = new DebugSampler(); threadGroupSubtree.add(debugSampler); ``` - Firstly, we create the tree at `(1)` - Then we create elements, and add them to the tree in `(2)` - Note how adding element returns the subtree, so we add `threadGroup` under `testPlan` in `(2)` :::note Don't confuse `ListedHashTree` with `HashTree`. `HashTree` does not honour element order, so the generated elements might shuffle unexpectedly. ::: ## Generating code from UI To aid with creating code, JMeter implements `Copy Code` context action, so you could generate code for any element in the plan. It would generate code for the element and its children. ![Copy Code context action](/images/screenshots/copy_code/http_sampler_copy_code.png) _Copy Code context action_ Here's the generated code (Kotlin DSL): ``` org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy::class { props { it[arguments] = org.apache.jmeter.config.Arguments().apply { props { it[arguments] = listOf( org.apache.jmeter.protocol.http.util.HTTPArgument().apply { props { it = "World" it[metadata] = "=" it[useEquals] = true it[argumentName] = "user" } }, org.apache.jmeter.protocol.http.util.HTTPArgument().apply { props { it[alwaysEncode] = true it = "test_value" it[metadata] = "=" it[useEquals] = true it[argumentName] = "test" } }, ) it[name] = "User Defined Variables" it[guiClass] = "org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel" it[testClass] = "org.apache.jmeter.config.Arguments" } } it[domain] = "example.com" it[path] = "/api/v1/login" it[method] = "GET" it[followRedirects] = true it[useKeepalive] = true it[proxy.scheme] = "https" it[proxy.host] = "localhost" it[proxy.port] = "8080" it[proxy.username] = "secret" it[proxy.password] = "password1" it[name] = "/login" it[guiClass] = "org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui" } org.apache.jmeter.extractor.RegexExtractor::class { props { it[guiClass] = "org.apache.jmeter.extractor.gui.RegexExtractorGui" it[name] = "extract user id" it[referenceName] = "regexVar" it[regularExpression] = "hello\\s+?world" it[template] = "\$1\$" } } org.apache.jmeter.protocol.http.control.HeaderManager::class { props { it[headers] = listOf( org.apache.jmeter.protocol.http.control.Header().apply { props { it[headerName] = "Accept" it = "text/plain" } }, org.apache.jmeter.protocol.http.control.Header().apply { props { it[headerName] = "User-Agent" it = "JMeter" } }, org.apache.jmeter.protocol.http.control.Header().apply { props { it[headerName] = "X-JMeter-Thread" it = "Thread \\${__threadNum}" } }, ) it[guiClass] = "org.apache.jmeter.protocol.http.gui.HeaderPanel" it[name] = "HTTP Header Manager" } } } ``` ## Creating a plan with Kotlin DSL JMeter 5.6 introduces Kotlin DSL which might make it easier to create and maintain test plans as the structure of the code would resemble the structure of the generated test plan tree ```java import org.apache.jmeter.sampler.DebugSampler import org.apache.jmeter.testelement.TestPlan import org.apache.jmeter.threads.ThreadGroup import org.apache.jmeter.treebuilder.dsl.testTree val root = testTree { // (1) TestPlan::class { // (2) ThreadGroup::class { name = "Search Order Thread Group" +DebugSampler::class // (3) +DebugSampler() // (4) } } } ``` - Firstly, we create a `TreeBuilder` at `(1)` - Then we add elements to the tree in `(2)`, and populate its children - Note how adding element returns the subtree, so we add `threadGroup` under `testPlan` in `(2)` - If no children needed, the element can be appended to the tree with a unary plus operator as in `(3)` - By default, JMeter uses no-argument constructors to create elements, however, you can add `TestElement` instances to the tree as well, see `(4)` ## Extending Kotlin DSL As you use the DSL for test plan generation, you might want to factor out the common patterns. For instance, imagine you want factor out `Thread Group` creation so it always has a `Summariser` element. ```java import kotlin.time.Duration.Companion.seconds import org.apache.jmeter.sampler.DebugSampler import org.apache.jmeter.testelement.TestPlan import org.apache.jmeter.threads.ThreadGroup import org.apache.jmeter.treebuilder.dsl.testTree fun TreeBuilder.threadGroup( // (1) name: String, numThreads: Int = 10, rampUp: Duration = 3.seconds, body: Action<ThreadGroup> ) { ThreadGroup::class { // (2) this.name = name this.numThreads = numThreads this.rampUp = rampUp.inWholeSeconds.toInt() +Summariser::class body(this) // (3) } } fun buildTree() { val root = testTree { TestPlan::class { threadGroup(name = "Search Order Thread Group", rampUp = 1.seconds) { // (4) +DebugSampler::class } } } ``` - Firstly, you can factor test element creation logic as an extension function for `TreeBuilder` as in `(1)`. It uses regular DSL to add an element (see `(2)`), and then it calls the lambda body in `(3)` to fill thread group children. - You can use the extension by calling it when you need it in the test plan, see `(4)` - Note how named parameters, and default values keep the code readable ## Creating a plan with Java DSL JMeter 5.6 introduces Java DSL which might make it easier to create and maintain test plans as the structure of the code would resemble the structure of the generated test plan tree ```java import org.apache.jmeter.sampler.DebugSampler import org.apache.jmeter.testelement.TestPlan import org.apache.jmeter.threads.ThreadGroup import static org.apache.jmeter.treebuilder.dsl.TreeBuilders.testTree ListedHashTree root = testTree(b -> { // (1) b.add(TestPlan.class, tp -> { // (2) b.add(ThreadGroup.class, tg -> { tg.setName("Search Order Thread Group"); b.add(DebugSampler.class); // (3) b.add(new DebugSampler()); // (4) }); }); }); ``` - Firstly, we create a `TreeBuilder` at `(1)`. Note how this builder reference should be used to append all the elements - Then we add elements to the tree in `(2)`, and populate its children. The lambda parameters correspond to the added elements, so you can configure their properties - Note how adding element returns the subtree, so we add `threadGroup` under `testPlan` in `(2)` - If no children needed, you could omit the lambda parameter as in `(3)` - By default, JMeter uses no-argument constructors to create elements, however, you can add `TestElement` instances to the tree as well, see `(4)` {/* SYNCED-BODY:END */} --- Title: User's Manual: Listeners URL: https://docs.jmeter.ai/user-manual/listeners/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 12. Introduction to listeners {/* CUSTOM-INTRO:START */} :::caution[Avoid View Results Tree in load tests] Listeners that render or retain detailed sample data can consume significant memory. Keep View Results Tree for debugging only and use `.jtl` files plus dashboard reports for real load runs. ::: {/* CUSTOM-INTRO:END */} A listener is a component that shows the results of the samples. The results can be shown in a tree, tables, graphs or simply written to a log file. To view the contents of a response from any given sampler, add either of the Listeners "`View Results Tree`" or "`View Results in table`" to a test plan. To view the response time graphically, add graph results. The [listeners](/user-manual/component-reference/#listeners) section of the components page has full descriptions of all the listeners. :::note Different listeners display the response information in different ways. However, they all write the same raw data to the output file - if one is specified. ::: The "`Configure`" button can be used to specify which fields to write to the file, and whether to write it as CSV or XML. CSV files are much smaller than XML files, so use CSV if you are generating lots of samples. The file name can be specified using either a relative or an absolute path name. Relative paths are resolved relative to the current working directory (which defaults to the `bin/` directory). JMeter also supports paths relative to the directory containing the current test plan (JMX file). If the path name begins with "`~/`" (or whatever is in the `jmeter.save.saveservice.base_prefix` JMeter property), then the path is assumed to be relative to the JMX file location. If you only wish to record certain samples, add the Listener as a child of the sampler. Or you can use a Simple Controller to group a set of samplers, and add the Listener to that. The same filename can be used by multiple samplers - but make sure they all use the same configuration! ## 12.1 Default Configuration The default items to be saved can be defined in the `jmeter.properties` (or `user.properties`) file. The properties are used as the initial settings for the Listener Config pop-up, and are also used for the log file specified by the `-l` command-line flag (commonly used for CLI mode test runs). To change the default format, find the following line in `jmeter.properties`: ``` jmeter.save.saveservice.output_format= ``` The information to be saved is configurable. For maximum information, choose "`xml`" as the format and specify "`Functional Test Mode`" on the Test Plan element. If this box is not checked, the default saved data includes a time stamp (the number of milliseconds since midnight, January 1, 1970 UTC), the data type, the thread name, the label, the response time, message, and code, and a success indicator. If checked, all information, including the full response data will be logged. The following example indicates how to set properties to get a vertical bar ("`|`") delimited format that will output results like:. ``` timeStamp|time|label|responseCode|threadName|dataType|success|failureMessage 02/06/03 08:21:42|1187|Home|200|Thread Group-1|text|true| 02/06/03 08:21:42|47|Login|200|Thread Group-1|text|false|Test Failed: expected to contain: password etc. ``` The corresponding `jmeter.properties` that need to be set are shown below. One oddity in this example is that the `output_format` is set to `csv`, which typically indicates comma-separated values. However, the `default_delimiter` was set to be a vertical bar instead of a comma, so the csv tag is a misnomer in this case. (Think of CSV as meaning character separated values) ``` jmeter.save.saveservice.output_format=csv jmeter.save.saveservice.assertion_results_failure_message=true jmeter.save.saveservice.default_delimiter=| ``` The full set of properties that affect result file output is shown below. ``` #--------------------------------------------------------------------------- # Results file configuration #--------------------------------------------------------------------------- # This section helps determine how result data will be saved. # The commented out values are the defaults. # legitimate values: xml, csv, db. Only xml and csv are currently supported. #jmeter.save.saveservice.output_format=csv # true when field should be saved; false otherwise # assertion_results_failure_message only affects CSV output #jmeter.save.saveservice.assertion_results_failure_message=true # # legitimate values: none, first, all #jmeter.save.saveservice.assertion_results=none # #jmeter.save.saveservice.data_type=true #jmeter.save.saveservice.label=true #jmeter.save.saveservice.response_code=true # response_data is not currently supported for CSV output #jmeter.save.saveservice.response_data=false # Save ResponseData for failed samples #jmeter.save.saveservice.response_data.on_error=false #jmeter.save.saveservice.response_message=true #jmeter.save.saveservice.successful=true #jmeter.save.saveservice.thread_name=true #jmeter.save.saveservice.time=true #jmeter.save.saveservice.subresults=true #jmeter.save.saveservice.assertions=true #jmeter.save.saveservice.latency=true #jmeter.save.saveservice.connect_time=true #jmeter.save.saveservice.samplerData=false #jmeter.save.saveservice.responseHeaders=false #jmeter.save.saveservice.requestHeaders=false #jmeter.save.saveservice.encoding=false #jmeter.save.saveservice.bytes=true #jmeter.save.saveservice.sent_bytes=true #jmeter.save.saveservice.url=false #jmeter.save.saveservice.filename=false #jmeter.save.saveservice.hostname=false #jmeter.save.saveservice.thread_counts=true #jmeter.save.saveservice.sample_count=false #jmeter.save.saveservice.idle_time=true # Timestamp format - this only affects CSV output files # legitimate values: none, ms, or a format suitable for SimpleDateFormat #jmeter.save.saveservice.timestamp_format=ms #jmeter.save.saveservice.timestamp_format=yyyy/MM/dd HH:mm:ss.SSS # For use with Comma-separated value (CSV) files or other formats # where the fields' values are separated by specified delimiters. # Default: #jmeter.save.saveservice.default_delimiter=, # For TAB, since JMeter 2.3 one can use: #jmeter.save.saveservice.default_delimiter=\t # Only applies to CSV format files: # Print field names as first line in CSV #jmeter.save.saveservice.print_field_names=true # Optional list of JMeter variable names whose values are to be saved in the result data files. # Use commas to separate the names. For example: #sample_variables=SESSION_ID,REFERENCE # N.B. The current implementation saves the values in XML as attributes, # so the names must be valid XML names. # JMeter sends the variable to all servers # to ensure that the correct data is available at the client. # Optional xml processing instruction for line 2 of the file: #jmeter.save.saveservice.xml_pi=<?xml-stylesheet type="text/xsl" href="sample.xsl"?> # Prefix used to identify filenames that are relative to the current base #jmeter.save.saveservice.base_prefix=~/ # AutoFlush on each line written in XML or CSV output # Setting this to true will result in less test results data loss in case of Crash # but with impact on performances, particularly for intensive tests (low or no pauses) # Since JMeter 2.10, this is false by default #jmeter.save.saveservice.autoflush=false # Put the start time stamp in logs instead of the end sampleresult.timestamp.start=true # Whether to use System.nanoTime() - otherwise only use System.currentTimeMillis() #sampleresult.useNanoTime=true # Use a background thread to calculate the nanoTime offset # Set this to ≤ 0 to disable the background thread #sampleresult.nanoThreadSleep=5000 ``` The date format to be used for the `timestamp_format` is described in **SimpleDateFormat**. The timestamp format is used for both writing and reading files. If the format is set to "`ms`", and the column does not parse as a long integer, JMeter (2.9+) will try the following formats: - `yyyy/MM/dd HH:mm:ss.SSS` - `yyyy/MM/dd HH:mm:ss` - `yyyy-MM-dd HH:mm:ss.SSS` - `yyyy-MM-dd HH:mm:ss` - `MM/dd/yy HH:mm:ss` (this is for compatibility with previous versions; it is not recommended as a format) Matching is now also strict (non-lenient). JMeter 2.8 and earlier used lenient mode which could result in timestamps with incorrect dates (times were usually correct). ### 12.1.1 Sample Variables JMeter supports the `sample_variables` property to define a list of additional JMeter variables which are to be saved with each sample in the JTL files. The values are written to CSV files as additional columns, and as additional attributes in XML files. See above for an example. ### 12.1.2 Sample Result Save Configuration Listeners can be configured to save different items to the result log files (JTL) by using the Config popup as shown below. The defaults are defined as described in the [Listener Default Configuration](#defaults) section above. Items with (CSV) after the name only apply to the CSV format; items with (XML) only apply to XML format. CSV format cannot currently be used to save any items that include line-breaks. ![**Configuration dialogue**](/images/screenshots/sample_result_config.png) _**Configuration dialogue**_ Note that cookies, method and the query string are saved as part of the "`Sampler Data`" option. ## 12.2 CLI mode (batch) test runs When running in CLI mode, the `-l` flag can be used to create a top-level listener for the test run. This is in addition to any Listeners defined in the test plan. The configuration of this listener is controlled by entries in the file `jmeter.properties` as described in the previous section. This feature can be used to specify different data and log files for each test run, for example: ``` jmeter -n -t testplan.jmx -l testplan_01.jtl -j testplan_01.log jmeter -n -t testplan.jmx -l testplan_02.jtl -j testplan_02.log ``` Note that JMeter logging messages are written to the file `jmeter.log` by default. This file is recreated each time, so if you want to keep the log files for each run, you will need to rename it using the `-j` option as above. JMeter supports variables in the log file name. If the filename contains paired single-quotes, then the name is processed as a `SimpleDateFormat` format applied to the current date, for example: `log_file='jmeter_'yyyyMMddHHmmss'.tmp'`. This can be used to generate a unique name for each test run. ## 12.3 Resource usage :::note Listeners can use a lot of memory if there are a lot of samples. ::: Most of the listeners currently keep a copy of every sample they display, apart from: - Simple Data Writer - BeanShell/JSR223 Listener - Mailer Visualizer - Monitor Results - Summary Report The following Listeners no longer need to keep copies of every single sample. Instead, samples with the same elapsed time are aggregated. Less memory is now needed, especially if most samples only take a second or two at most. - Aggregate Report - Aggregate Graph To minimize the amount of memory needed, use the Simple Data Writer, and use the CSV format. ## 12.4 CSV Log format The CSV log format depends on which data items are selected in the configuration. Only the specified data items are recorded in the file. The order of appearance of columns is fixed, and is as follows: - `timeStamp` - in milliseconds since 1/1/1970 - `elapsed` - in milliseconds - `label` - sampler label - `responseCode` - e.g. `200`, `404` - `responseMessage` - e.g. `OK` - `threadName` - `dataType` - e.g. `text` - `success` - `true` or `false` - `failureMessage` - if any - `bytes` - number of bytes in the sample - `sentBytes` - number of bytes sent for the sample - `grpThreads` - number of active threads in this thread group - `allThreads` - total number of active threads in all groups - `URL` - `Filename` - if `Save Response to File` was used - `latency` - time to first response - `connect` - time to establish connection - `encoding` - `SampleCount` - number of samples (1, unless multiple samples are aggregated) - `ErrorCount` - number of errors (0 or 1, unless multiple samples are aggregated) - `Hostname` - where the sample was generated - `IdleTime` - number of milliseconds of 'Idle' time (normally 0) - `Variables`, if specified ## 12.5 XML Log format 2.1 The format of the updated XML (2.1) is as follows (line breaks will be different): ``` <?xml version="1.0" encoding="UTF-8"?> <testResults version="1.2"> -- HTTP Sample, with nested samples <httpSample t="1392" lt="351" ts="1144371014619" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Listen 1-1" dt="text" de="iso-8859-1" by="12407"> <httpSample t="170" lt="170" ts="1144371015471" s="true" lb="http://www.apache.org/style/style.css" rc="200" rm="OK" tn="Listen 1-1" dt="text" de="ISO-8859-1" by="1002"> <responseHeader class="java.lang.String">HTTP/1.1 200 OK Date: Fri, 07 Apr 2006 00:50:14 GMT ⋮ Content-Type: text/css </responseHeader> <requestHeader class="java.lang.String">MyHeader: MyValue</requestHeader> <responseData class="java.lang.String">body, td, th { font-size: 95%; font-family: Arial, Geneva, Helvetica, sans-serif; color: black; background-color: white; } ⋮ </responseData> <cookies class="java.lang.String"></cookies> <method class="java.lang.String">GET</method> <queryString class="java.lang.String"></queryString> <url>http://www.apache.org/style/style.css</url> </httpSample> <httpSample t="200" lt="180" ts="1144371015641" s="true" lb="http://www.apache.org/images/asf_logo_wide.gif" rc="200" rm="OK" tn="Listen 1-1" dt="bin" de="ISO-8859-1" by="5866"> <responseHeader class="java.lang.String">HTTP/1.1 200 OK Date: Fri, 07 Apr 2006 00:50:14 GMT ⋮ Content-Type: image/gif </responseHeader> <requestHeader class="java.lang.String">MyHeader: MyValue</requestHeader> <responseData class="java.lang.String">http://www.apache.org/asf.gif</responseData> <responseFile class="java.lang.String">Mixed1.html</responseFile> <cookies class="java.lang.String"></cookies> <method class="java.lang.String">GET</method> <queryString class="java.lang.String"></queryString> <url>http://www.apache.org/asf.gif</url> </httpSample> <responseHeader class="java.lang.String">HTTP/1.1 200 OK Date: Fri, 07 Apr 2006 00:50:13 GMT ⋮ Content-Type: text/html; charset=ISO-8859-1 </responseHeader> <requestHeader class="java.lang.String">MyHeader: MyValue</requestHeader> <responseData class="java.lang.String"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ⋮ <html> <head> ⋮ </head> <body> ⋮ </body> </html> </responseData> <cookies class="java.lang.String"></cookies> <method class="java.lang.String">GET</method> <queryString class="java.lang.String"></queryString> <url>http://www.apache.org/</url> </httpSample> -- non HTTP Sample <sample t="0" lt="0" ts="1144372616082" s="true" lb="Example Sampler" rc="200" rm="OK" tn="Listen 1-1" dt="text" de="ISO-8859-1" by="10"> <responseHeader class="java.lang.String"></responseHeader> <requestHeader class="java.lang.String"></requestHeader> <responseData class="java.lang.String">Listen 1-1</responseData> <responseFile class="java.lang.String">Mixed2.unknown</responseFile> <samplerData class="java.lang.String">ssssss</samplerData> </sample> </testResults> ``` Note that the sample node name may be either "`sample`" or "`httpSample`". ## 12.6 XML Log format 2.2 The format of the JTL files is identical for 2.2 and 2.1. Format 2.2 only affects JMX files. ## 12.7 Sample Attributes The sample attributes have the following meaning: | | | | --- | --- | | `by` | Bytes | | `sby` | Sent Bytes | | `de` | Data encoding | | `dt` | Data type | | `ec` | Error count (0 or 1, unless multiple samples are aggregated) | | `hn` | Hostname where the sample was generated | | `it` | Idle Time = time not spent sampling (milliseconds) (generally 0) | | `lb` | Label | | `lt` | Latency = time to initial response (milliseconds) - not all samplers support this | | `ct` | Connect Time = time to establish the connection (milliseconds) - not all samplers support this | | `na` | Number of active threads for all thread groups | | `ng` | Number of active threads in this group | | `rc` | Response Code (e.g. `200`) | | `rm` | Response Message (e.g. `OK`) | | `s` | Success flag (`true`/`false`) | | `sc` | Sample count (1, unless multiple samples are aggregated) | | `t` | Elapsed time (milliseconds) | | `tn` | Thread Name | | `ts` | timeStamp (milliseconds since midnight Jan 1, 1970 UTC) | | `varname` | Value of the named variable | :::note JMeter allows additional variables to be saved with the test plan. Currently, the variables are saved as additional attributes. The testplan variable name is used as the attribute name. See [Sample variables](#sample_variables) (above) for more information. ::: ## 12.8 Saving response data As shown above, the response data can be saved in the XML log file if required. However, this can make the file rather large, and the text has to be encoded so that it is still valid XML. Also, images cannot be included. Only sample responses with the type `TEXT` can be saved. Another solution is to use the Post-Processor [Save_Responses_to_a_file](/user-manual/component-reference/#Save_Responses_to_a_file). This generates a new file for each sample, and saves the file name with the sample. The file name can then be included in the sample log output. The data will be retrieved from the file if necessary when the sample log file is reloaded. ## 12.9 Loading (reading) response data To view an existing results file, you can use the File "`Browse…`" button to select a file. If necessary, just create a dummy testplan with the appropriate Listener in it. Results can be read from XML or CSV format files. When reading from CSV results files, the header (if present) is used to determine which fields were saved. **In order to interpret a header-less CSV file correctly, the appropriate JMeter properties must be set.** :::note JMeter does not clear any current data before loading the new file thus allowing files to be merged. If you want to clear the current data, use the menu item: **Run → Clear → (Ctrl+Shift+E)** or **Run → Clear All → (Ctrl+E)** before loading the file. ::: ## 12.10 Saving Listener GUI data JMeter is capable of saving any listener as a PNG file. To do so, select the listener in the left panel. Click **Edit → Save Node As Image**. A file dialog will appear. Enter the desired name and save the listener. The Listeners which generate output as tables can also be saved using Copy/Paste. Select the desired cells in the table, and use the OS Copy short-cut (normally `Ctrl + C`). The data will be saved to the clipboard, from where it can be pasted into another application, e.g. a spreadsheet or text editor. ![Figure 1 - **Edit → Save Node As Image**](/images/screenshots/save_image.png) _Figure 1 - **Edit → Save Node As Image**_ {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Set up [Real-time Results](/user-manual/realtime-results/) to stream listener data to InfluxDB or Graphite. - [Dashboard Report](/user-manual/generating-dashboard/) - generate rich HTML reports from listener CSV output - [Component Reference](/user-manual/component-reference/) - detailed configuration for each listener type - Leaving View Results Tree active during load tests causes memory exhaustion - Not configuring result file output loses data if JMeter crashes mid-test {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Remote (Distributed) Testing URL: https://docs.jmeter.ai/user-manual/remote-test/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 13. Remote Testing {/* CUSTOM-INTRO:START */} :::caution[Security-sensitive setting] Remote testing exposes control channels between machines. Restrict network access, use trusted test plans, and review RMI SSL settings before enabling workers. ::: :::note[Version-specific behavior] Remote testing requires compatible JMeter and Java versions across controller and workers. Re-check RMI and SSL defaults after upgrades. ::: {/* CUSTOM-INTRO:END */} In the event that your JMeter client machine is unable, performance-wise, to simulate enough users to stress your server or is limited at network level, an option exists to control multiple, remote JMeter engines from a single JMeter client. By running JMeter remotely, you can replicate a test across many low-end computers and thus simulate a larger load on the server. One instance of the JMeter client can control any number of remote JMeter instances, and collect all the data from them. This offers the following features: - Saving of test samples to the local machine - Management of multiple JMeterEngines from a single machine - No need to copy the test plan to each server - the client sends it to all the servers :::note Note: The same test plan is run by all the servers. JMeter does not distribute the load between servers, each runs the full test plan. So if you set 1000 Threads and have 6 JMeter server, you end up injecting 6000 Threads. ::: However, remote mode does use more resources than running the same number of CLI mode tests independently. If many server instances are used, the client JMeter can become overloaded, as can the client network connection. This has been improved by switching to Stripped modes (see below) but you should always check that your client is not overloaded. Note that while you can execute the JMeterEngine on your application server, you need to be mindful of the fact that this will be adding processing overhead on the application server and thus your testing results will be somewhat tainted. The recommended approach is to have one or more machines on the same Ethernet segment as your application server that you configure to run the JMeter Engine. This will minimize the impact of the network on the test results without impacting the performance of the application server itself. **Step 0: Configure the nodes** Make sure that all the nodes (client and servers) : - are running exactly the same version of JMeter. - are using the same version of Java on all systems. Using different versions of Java may work but is discouraged. - have a [valid keystore for RMI over SSL](#setup_ssl), or you have disabled the use of SSL. If the test uses any data files, note that these are not sent across by the client so make sure that these are available in the appropriate directory on each server. If necessary you can define different values for properties by editing the `user.properties` or `system.properties` files on each server. These properties will be picked up when the server is started and may be used in the test plan to affect its behaviour (e.g. connecting to a different remote server). Alternatively use different content in any datafiles used by the test (e.g. if each server must use unique ids, divide these between the data files) **Step 1: Start the servers** To run JMeter in remote node, start the JMeter server component on all machines you wish to run on by running the `JMETER_HOME/bin/jmeter-server` (unix) or `JMETER_HOME/bin/jmeter-server.bat` (windows) script. Note that there can only be one JMeter server on each node unless different RMI ports are used. The JMeter server application starts the RMI registry itself; there is no need to start RMI registry separately. By default, RMI uses a dynamic port for the JMeter server engine. This can cause problems for firewalls, so you can define the JMeter property `server.rmi.localport` to control this port number. it will be used as the local port number for the server engine. **Step 2: Add the server IP to your client's Properties File** Edit the properties file _on the controlling JMeter machine_. In `JMETER_HOME/bin/jmeter.properties`, find the property named "`remote_hosts`" and add the value of your running JMeter server's IP address. Multiple such servers can be added, comma-delimited. Note that you can use the `-R` [command line option](/getting-started/get-started/#override) instead to specify the remote host(s) to use. This has the same effect as using `-r` and `-Jremote_hosts={serverlist}`. E.g. ``` jmeter -Rhost1,127.0.0.1,host2 ``` If you define the JMeter property `server.exitaftertest=true`, then the server will exit after it runs a single test. See also the `-X` flag (described below) **Step 3a: Start the JMeter Client from a GUI client to check configuration** Now you are ready to start the controlling JMeter client. For MS-Windows, start the client with the script "`bin/jmeter.bat`". For UNIX, use the script "`bin/jmeter`". You will notice that the Run menu contains two new sub-menus: "Remote Start" and "Remote Stop" (see figure 1). These menus contain the client that you set in the properties file. Use the remote start and stop instead of the normal JMeter start and stop menu items. ![Figure 1 - Run Menu](/images/screenshots/remote/run-menu00.png) _Figure 1 - Run Menu_ **Step 3b: Start the JMeter from a CLI mode Client** GUI mode should only be used for debugging, as a better alternative, you should start the test on remote server(s) from a CLI mode (command-line) client. The command to do this is: ``` jmeter -n -t script.jmx -r ``` or ``` jmeter -n -t script.jmx -R server1,server2,… ``` Other flags that may be useful: **`-Gproperty=value`** : define a property in all the servers (may appear more than once) **`-X`** : Exit remote servers at the end of the test. The first example will start the test on whatever servers are defined in the JMeter property `remote_hosts`; The second example will define `remote_hosts` from the list of servers and then start the test on the remote servers. The command-line client will exit when all the remote servers have stopped. ### 13.1 Setting up SSL :::note Since JMeter 4.0 the default transport mechanism for RMI will use SSL. SSL needs keys and certificates to work. You will have to create those keys yourself. ::: The simplest setup is to use one key/cert pair for all JMeter servers and clients you want to connect. JMeter comes with a script to generate a keystore that contains one key (and its corresponding certificate) named `rmi`. The script is located in the `bin` directory and is available for Windows systems (called `bin/create-rmi-keystore.bat`) and Unix like systems (called `bin/create-rmi-keystore.sh`). It will generate a key-pair, that is valid for seven days, with a default passphrase of value '`changeit`'. It is advised to call it from inside the `bin` directory. When you run the script, it will ask you some questions about some names it will embed in the certificate. You can type in whatever you want, as long the keystore tool accepts it. That value has to match the property `server.rmi.ssl.keystore.alias`, which defaults to `rmi`. A sample session to create the keystore is shown below. ```bash $ cd jmeter/bin $ ./create-rmi-keystore.sh What is your first and last name? [Unknown]: rmi What is the name of your organizational unit? [Unknown]: My unit name What is the name of your organization? [Unknown]: My organisation name What is the name of your City or Locality? [Unknown]: Your City What is the name of your State or Province? [Unknown]: Your State What is the two-letter country code for this unit? [Unknown]: XY Is CN=rmi, OU=My unit name, O=My organisation name, L=Your City, ST=Your State, C=XY correct? [no]: yes Copy the generated rmi_keystore.jks to jmeter/bin folder or reference it in property 'server.rmi.ssl.keystore.file' ``` The [defaults settings for RMI](/user-manual/properties-reference/#remote) should work with this setup. Copy the file `bin/rmi_keystore.jks` to every JMeter server and client you want to use for your distributed testing setup. ### 13.2 Doing it Manually In some cases, the jmeter-server script may not work for you (if you are using an OS platform not anticipated by the JMeter developers). Here is how to start the JMeter servers (step 1 above) with a more manual process: **Step 1a: Start the RMI Registry** Since JMeter 2.3.1, the RMI registry is started by the JMeter server, so this section does not apply in the normal case. To revert to the previous behaviour, define the JMeter property `server.rmi.create=false` on the server host systems and follow the instructions below. JMeter uses Remote Method Invocation (RMI) as the remote communication mechanism. Therefore, you need to run the RMI Registry application (which is named "`rmiregistry`") that comes with the JDK and is located in the "`bin`" directory. Before running `rmiregistry`, make sure that the following jars are in your system classpath: - `JMETER_HOME/lib/ext/ApacheJMeter_core.jar` - `JMETER_HOME/lib/jorphan.jar` - `JMETER_HOME/lib/logkit-2.0.jar` The rmiregistry application needs access to certain JMeter classes. Run `rmiregistry` with no parameters. By default the application listens to port `1099`. **Step 1b: Start the JMeter Server** Once the RMI Registry application is running, start the JMeter Server. Use the "`-s`" option with the jmeter startup script ("`jmeter -s`"). Steps 2 and 3 remain the same. ### 13.3 Tips JMeter/RMI requires a connection from the client to the server. This will use the port you chose, default `1099`. JMeter/RMI also requires a reverse connection in order to return sample results from the server to the client. These will use high-numbered ports. These ports can be controlled by jmeter property called `client.rmi.localport` in `jmeter.properties`. If this is non-zero, it will be used as the base for local port numbers for the client engine. At the moment JMeter will open up to three ports beginning with the port defined in `client.rmi.localport`. If there are any firewalls or other network filters between JMeter client and server, you will need to make sure that they are set up to allow the connections through. If necessary, use monitoring software to show what traffic is being generated. If you're running Suse Linux, these tips may help. The default installation may enable the firewall. In that case, remote testing will not work properly. The following tips were contributed by Sergey Ten. If you see connections refused, turn on debugging by passing the following options. ``` rmiregistry -J-Dsun.rmi.log.debug=true \ -J-Dsun.rmi.server.exceptionTrace=true \ -J-Dsun.rmi.loader.logLevel=verbose \ -J-Dsun.rmi.dgc.logLevel=verbose \ -J-Dsun.rmi.transport.logLevel=verbose \ -J-Dsun.rmi.transport.tcp.logLevel=verbose \ ``` Since JMeter 2.3.1, the RMI registry is started by the server; however the options can still be passed in from the JMeter command line. For example: "`jmeter -s -Dsun.rmi.loader.logLevel=verbose`" (i.e. omit the `-J` prefixes). Alternatively the properties can be defined in the `system.properties` file. The solution to the problem is to remove the loopbacks `127.0.0.1` and `127.0.0.2` from `/etc/hosts`. What happens is `jmeter-server` can't connect to rmiregistry if `127.0.0.2` loopback is not available. Use the following settings to fix the problem. Replace ``` `dirname $0`/jmeter -s "$@" ``` With ``` HOST="-Djava.rmi.server.hostname=[computer_name][computer_domain] \ -Djava.security.policy=`dirname $0`/[policy_file]" \ `dirname $0`/jmeter $HOST -s "$@" ``` Also create a policy file and add `[computer_name][computer_domain]` line to `/etc/hosts`. In order to better support SSH-tunneling of the RMI communication channels used in remote testing, since JMeter 2.6: - a new property "`client.rmi.localport`" can be set to control the RMI port used by the RemoteSampleListenerImpl - To support tunneling RMI traffic over an SSH tunnel as the remote endpoint using a port on the local machine, loopback interface is now allowed to be used if it has been specified directly using the Java System Property "`java.rmi.server.hostname`" parameter. ### 13.4 Using a different port By default, JMeter uses the standard RMI port `1099`. It is possible to change this. For this to work successfully, all the following need to agree: - On the server, start `rmiregistry` using the new port number - On the server, start JMeter with the property `server_port` defined - On the client, update the `remote_hosts` property to include the new remote `host:port` settings Since JMeter 2.1.1, the jmeter-server scripts provide support for changing the port. For example, assume you want to use port `1664` (perhaps `1099` is already used). On Windows (in a DOS box) ``` C:\JMETER> SET SERVER_PORT=1664 C:\JMETER> JMETER-SERVER [other options] ``` On Unix: ```bash $ SERVER_PORT=1664 jmeter-server [other options] ``` [N.B. use upper case for the environment variable] In both cases, the script starts rmiregistry on the specified port, and then starts JMeter in server mode, having defined the "`server_port`" property. The chosen port will be logged in the server `jmeter.log` file (`rmiregistry` does not create a log file). ### 13.5 Using a different sample sender Listeners in the test plan send their results back to the client JMeter which writes the results to the specified files By default, samples are sent back synchronously as they are generated. This can affect the maximum throughput of the server test; the sample result has to be sent back before the thread can continue. There are some JMeter properties that can be set to alter this behaviour. **`mode`** : sample sending mode - default is `StrippedBatch` since 2.9. This should be set on the client node. **`Standard`** : send samples synchronously as soon as they are generated **`Hold`** : hold samples in an array until the end of a run. This may use a lot of memory on the server and is discouraged. **`DiskStore`** : store samples in a disk file (under `java.io.temp`) until the end of a run. The serialised data file is deleted on JVM exit. **`StrippedDiskStore`** : remove responseData from successful samples, and use DiskStore sender to send them. **`Batch`** : send saved samples when either the count (`num_sample_threshold`) or time (`time_threshold`) exceeds a threshold, at which point the samples are sent synchronously. The thresholds can be configured on the server using the following properties: **`num_sample_threshold`** : number of samples to accumulate, default `100` **`time_threshold`** : time threshold, default 60000 ms = 60 seconds See also the Asynch mode, described below. **`Statistical`** : send a summary sample when either the count or time exceeds a threshold. The samples are summarised by thread group name and sample label. The following fields are accumulated: - `elapsed time` - `latency` - `bytes` - `sample count` - `error count` Other fields that vary between samples are lost. **`Stripped`** : remove responseData from successful samples **`StrippedBatch`** : remove responseData from successful samples, and use Batch sender to send them. **`Asynch`** : samples are temporarily stored in a local queue. A separate worker thread sends the samples. This allows the test thread to continue without waiting for the result to be sent back to the client. However, if samples are being created faster than they can be sent, the queue will eventually fill up, and the sampler thread will block until some samples can be drained from the queue. This mode is useful for smoothing out peaks in sample generation. The queue size can be adjusted by setting the JMeter property `asynch.batch.queue.size` (default `100`) on the server node. **`StrippedAsynch`** : remove responseData from successful samples, and use Async sender to send them. **`Custom implementation`** : set the mode parameter to your custom sample sender class name. This must implement the interface `SampleSender` and have a constructor which takes a single parameter of type `RemoteSampleListener`. :::note `Stripped` mode family strips `responseData` so this means that some Elements that rely on the previous `responseData` being available will not work. This is not really a problem as there is always a more efficient way to implement this feature. ::: The following properties apply to the `Batch` and `Statistical` modes: **`num_sample_threshold`** : number of samples in a batch (default `100`) **`time_threshold`** : number of milliseconds to wait (default 60 seconds) ### 13.6 Dealing with nodes that failed starting For large-scale tests there is a chance that some part of remote servers will be unavailable or down. For example, when you use automation script to allocate many cloud machines and use them as generators, some of requested machines might fail booting because of cloud's issues. Since JMeter 2.13 there are new properties to control this behaviour. First what you might want is to retry initialization attempts in hope that failed nodes just slightly delayed their boot. To enable retries, you should set `client.tries` property to total number of connection attempts. By default it does only one attempt. To control retry delay, set the `client.retries_delay` property to number of milliseconds to sleep between attempts. Finally, you might still want to run the test with those generators that succeeded initialization and skipping failed nodes. To enable that, set the `client.continue_on_fail=true` property. ### 13.7 Using a security-manager When running JMeter in a distributed environment you have to be aware, that JMeter is basically a remote execution agent on both the server and client side. This could be used by a malicious party to gain further access, once it has compromised one of the JMeter clients or servers. To mitigate this Java has the concept of a security manager that gets asked by the JVM before potential dangerous actions are executed. Those actions could be resolving host names, creating or reading files or executing commands in the OS. The security manager can be enabled by setting the Java system properties `java.security.manager` and `java.security.policy`. Be sure to have a look at the [Quick Tour of Controlling Applications](https://docs.oracle.com/javase/tutorial/security/tour2/index.html). Using the new mechansism of `setenv.sh` (or `setenv.bat` under Windows) you can enable the security manager by adding the following code snippet to `\${JMETER_HOME}/bin/setenv.sh`: ``` JVM_ARGS=" \ -Djava.security.manager \ -Djava.security.policy=\${JMETER_HOME}/bin/java.policy \ -Djmeter.home=\${JMETER_HOME} \ " ``` The JVM will now add the policies defined in the file `\${JMETER_HOME}/bin/java.policy` to the possibly globally defined policies. If you want your definition to be the only source for policies, use two equal signs instead of one when setting the property `java.security.policy`. The policies will be dependent upon your use case and it might take a while to find the correct restricted and allowed actions. Java can help you find the needed policies with the property `java.security.debug`. Set it to `access` and it will log all permissions, that it gets asked to allow. Simply add the following line to your `setenv.sh`: ``` JVM_ARGS="\${JVM_ARGS} -Djava.security.debug=access" ``` It might look a bit strange, that we define a Java system property `jmeter.home` with the value of `\${JMETER_HOME}`. This variable will be used in the example `java.policy` to limit the file system access and allow it only to read JMeters configuration and libraries and restrict write access to specific locations, only. The following policy definition file has been used for a simple remote test. You will probably have to tweak the policies, when you run more complex scenarios. The test plans are somewhere placed inside the users home directory under a directory called `jmeter-testplans`. The sample `java.policy` looks like: ``` grant codeBase "file:\${jmeter.home}/bin/*" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/jorphan.jar" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/log4j-api-2.11.1.jar" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/log4j-slf4j-impl-2.11.1.jar" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/slf4j-api-1.7.25.jar" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/log4j-core-2.11.1.jar" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/ext/*" { permission java.security.AllPermission; }; grant codeBase "file:\${jmeter.home}/lib/httpclient-4.5.6.jar" { permission java.net.SocketPermission "*", "connect,resolve"; }; grant codeBase "file:\${jmeter.home}/lib/darcula.jar" { permission java.lang.RuntimePermission "modifyThreadGroup"; }; grant codeBase "file:\${jmeter.home}/lib/xercesImpl-2.12.0.jar" { permission java.io.FilePermission "\${java.home}/lib/xerces.properties", "read"; }; grant codeBase "file:\${jmeter.home}/lib/groovy-all-2.4.15.jar" { permission groovy.security.GroovyCodeSourcePermission "/groovy/script"; permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect"; permission java.lang.RuntimePermission "getProtectionDomain"; }; grant { permission java.io.FilePermission "\${jmeter.home}/backups", "read,write"; permission java.io.FilePermission "\${jmeter.home}/backups/*", "read,write,delete"; permission java.io.FilePermission "\${jmeter.home}/bin/upgrade.properties", "read"; permission java.io.FilePermission "\${jmeter.home}/lib/ext/-", "read"; permission java.io.FilePermission "\${jmeter.home}/lib/ext", "read"; permission java.io.FilePermission "\${jmeter.home}/lib/-", "read"; permission java.io.FilePermission "\${user.home}/jmeter-testplans/-", "read,write"; permission java.io.SerializablePermission "enableSubclassImplementation"; permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.dynalink.support"; permission java.lang.RuntimePermission "accessClassInPackage.sun.awt"; permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; permission java.lang.RuntimePermission "accessClassInPackage.sun.swing"; permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "createClassLoader"; permission java.lang.RuntimePermission "createSecurityManager"; permission java.lang.RuntimePermission "getClassLoader"; permission java.lang.RuntimePermission "getenv.*"; permission java.lang.RuntimePermission "nashorn.createGlobal"; permission java.util.PropertyPermission "*", "read"; }; ``` :::note The usage of `java.security.AllPermission` is an easy way to make your test plans work, but it might be a dangerous shortcut on your path to security. ::: {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Follow the [Distributed Testing Step-by-Step](/user-manual/jmeter-distributed-testing-step-by-step/) tutorial for a guided setup. - [Real-time Results](/user-manual/realtime-results/) - monitor distributed tests with Backend Listener - [Dashboard Report](/user-manual/generating-dashboard/) - generate HTML reports from distributed test CSV files - Running different JMeter versions on controller and worker nodes causes serialization errors - Not disabling SSL for RMI in non-production environments causes connection failures {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Generating Dashboard Report URL: https://docs.jmeter.ai/user-manual/generating-dashboard/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 14. Generating Report Dashboard JMeter supports dashboard report generation to get graphs and statistics from a test plan. This chapter describes how to configure and use the generator. ### 14.1 Overview The dashboard generator is a modular extension of JMeter. Its default behavior is to read and process samples from CSV files to generate HTML files containing graph views. It can generate the report at end of a load test or on demand. This report provides the following metrics: - [APDEX](https://en.wikipedia.org/wiki/Apdex) (Application Performance Index) table that computes for every transaction the APDEX based on configurable values for tolerated and satisfied thresholds - A request summary graph showing the Success and failed requests (Transaction Controller Sample Results are not taken into account) percentage: ![dashboard/report_apdex_and_summary.png](/images/screenshots/dashboard/report_apdex_and_summary.png) - A Statistics table providing in one table a summary of all metrics per transaction including 3 configurable percentiles: ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - An error table providing a summary of all errors and their proportion in the total requests: ![dashboard/report_errors.png](/images/screenshots/dashboard/report_errors.png) - A Top 5 Errors by Sampler table providing for every Sampler (excluding Transaction Controller by default) the top 5 Errors: ![dashboard/top_5_errors_by_sampler.png](/images/screenshots/dashboard/top_5_errors_by_sampler.png) - Zoomable chart where you can check/uncheck every transaction to show/hide it for: - Response times Over Time (Includes Transaction Controller Sample Results): ![dashboard/report_response_times_over_time.png](/images/screenshots/dashboard/report_response_times_over_time.png) - Response times Percentiles Over Time (successful responses only): ![dashboard/response_time_percentiles_over_time.png](/images/screenshots/dashboard/response_time_percentiles_over_time.png) - Active Threads Over Time: ![dashboard/report_active_threads_over_time.png](/images/screenshots/dashboard/report_active_threads_over_time.png) - Bytes throughput Over Time (Ignores Transaction Controller Sample Results): ![dashboard/report_bytes_throughput_over_time.png](/images/screenshots/dashboard/report_bytes_throughput_over_time.png) - Latencies Over Time (Includes Transaction Controller Sample Results): ![dashboard/report_latencies_over_time.png](/images/screenshots/dashboard/report_latencies_over_time.png) - Connect Time Over Time (Includes Transaction Controller Sample Results): ![dashboard/report_connect_time_over_time.png](/images/screenshots/dashboard/report_connect_time_over_time.png) - Hits per second (Ignores Transaction Controller Sample Results): ![dashboard/report_hits_per_second.png](/images/screenshots/dashboard/report_hits_per_second.png) - Response codes per second (Ignores Transaction Controller Sample Results): ![dashboard/report_codes_per_second.png](/images/screenshots/dashboard/report_codes_per_second.png) - Transactions per second (Includes Transaction Controller Sample Results): ![dashboard/report_transactions_per_second.png](/images/screenshots/dashboard/report_transactions_per_second.png) - Response Time vs Request per second (Ignores Transaction Controller Sample Results): ![dashboard/report_response_time_vs_request.png](/images/screenshots/dashboard/report_response_time_vs_request.png) - Latency vs Request per second (Ignores Transaction Controller Sample Results): ![dashboard/report_latencies_vs_request.png](/images/screenshots/dashboard/report_latencies_vs_request.png) - Response time Overview (Excludes Transaction Controller Sample Results): ![dashboard/response_time_overview.png](/images/screenshots/dashboard/response_time_overview.png) - Response times percentiles (Includes Transaction Controller Sample Results): ![dashboard/report_response_time_percentiles.png](/images/screenshots/dashboard/report_response_time_percentiles.png) - Times vs Threads (Includes Transaction Controller Sample Results): ![dashboard/report_time_vs_threads.png](/images/screenshots/dashboard/report_time_vs_threads.png) :::note In distributed mode, this graph shows a horizontal axis the number of threads for 1 server. It's a current limitation ::: - Response Time Distribution (Includes Transaction Controller Sample Results): ![dashboard/report_response_time_distribution.png](/images/screenshots/dashboard/report_response_time_distribution.png) ### 14.2 Configuring Dashboard Generation Dashboard generation uses JMeter properties to customize the report. Some properties are used for general settings and others are used for a particular graph configuration or exporter configuration. :::note All report generator properties can be found in file `reportgenerator.properties`. To customize these properties, you should copy them in `user.properties` file and modify them. ::: #### 14.2.1 Requirements ##### 14.2.1.1 Filtering configuration Ensure you set property `jmeter.reportgenerator.exporter.html.series_filter` to keep only the transactions you want in the report if you don't want everything. In the example below you must only modify `Search|Order`, keep the rest: ``` jmeter.reportgenerator.exporter.html.series_filter=^(Search|Order)(-success|-failure)?$ ``` ##### 14.2.1.2 Save Service configuration To enable the generator to operate, the CSV file generated by JMeter must include certain required data which **are correct by default in the last live version** of JMeter. If you modified those settings, check that your JMeter configuration follows these settings (these are the defaults): ``` jmeter.save.saveservice.bytes = true # Only available with HttpClient4 #jmeter.save.saveservice.sent_bytes=true jmeter.save.saveservice.label = true jmeter.save.saveservice.latency = true jmeter.save.saveservice.response_code = true jmeter.save.saveservice.response_message = true jmeter.save.saveservice.successful = true jmeter.save.saveservice.thread_counts = true jmeter.save.saveservice.thread_name = true jmeter.save.saveservice.time = true jmeter.save.saveservice.connect_time = true jmeter.save.saveservice.assertion_results_failure_message = true # the timestamp format must include the time and should include the date. # For example the default, which is milliseconds since the epoch: jmeter.save.saveservice.timestamp_format = ms # Or the following would also be suitable # jmeter.save.saveservice.timestamp_format = yyyy/MM/dd HH:mm:ss ``` ##### 14.2.1.3 Transaction Controller configuration If you use `Transaction Controller`s, to ensure most accurate results: - uncheck the box (**this is the default configuration**): `Generate parent sample` ![transactioncontroller.png](/images/screenshots/transactioncontroller.png) - If `Transaction Controller` is used as a Container to represent a request for an HTML Page that will trigger Ajax calls and you only want in your report the Transaction Controller, then Right click on the node and Apply Naming Policy ![apply_naming_policy1.png](/images/screenshots/apply_naming_policy1.png) You will obtain this: ![apply_naming_policy2.png](/images/screenshots/apply_naming_policy2.png) #### 14.2.2 General settings :::note All properties must be prefixed with ``` jmeter.reportgenerator. ``` ::: | Name | Required | Description | |------|----------|-------------| | report_title | No | Title used in the generated report. Default: "Apache JMeter Dashboard" | | date_format | No | Default date format from [SimpleDateFormat Java API](http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) with Locale.ENGLISH. Default Date format is `yyyyMMddHHmmss` Useful when you would like to generate a report after the load test, and the results file contains timestamp in another time zone. In this case the date format must include the time zone (zzz). :::note If `jmeter.save.saveservice.timestamp_format` does not contain year then use 1970 as year ::: Example: `dd/MM/yyyy HH:mm:ss zzz` | | start_date | No | Start date of the range of data to use for report. Date format is defined by date_format property. Default: not filled which means data range will be used from the beginning | | end_date | No | End date of the range of data to use for report. Date format is defined by date_format property. Default: not filled which means data range will be used until the end | | overall_granularity | No | Granularity of over time graphs. Data is aggregated to have 1 minute ticks. :::note Granularity must be higher than 1 second (1000) otherwise throughput graphs will be incorrect ::: Default: "60000" (1 minute) | | apdex_satisfied_threshold | No | Sets the satisfaction threshold for the [APDEX](https://en.wikipedia.org/wiki/Apdex) calculation (in ms). Default: `500` | | apdex_tolerated_threshold | No | Sets the tolerance threshold for the APDEX calculation (in ms). Default: `1500` | | jmeter.reportgenerator.apdex_per_transaction | No | Sets satisfaction and tolerance threshold to specific samples. Use sample names or regular expression. Format is `sample_name:satisfaction|tolerance[;]` Values are in milliseconds. :::note Notice the colon between sample name and values, the pipe between thresholds and the semicolon at the end to separate different samples. Don't forget to escape after semicolon to span multiple lines. ::: Example: ``` jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000;\ samples12:3000|4000;\ scenar01-12:5000|6000 ``` | | sample_filter | No | Sets the filter of samples to keep for generating graphs and statistics. An empty value deactivates the filtering. Format: Regular expression. Default: "" | | temp_dir | No | Sets the temporary directory used by the generation process if it needs file I/O operations. Default: `temp` | | statistic_window | No | Sets the size of the sliding window used by percentile evaluation. Caution: higher value provides a better accuracy but needs more memory. Default: `20000` | :::note Percentiles used by Summary table and Percentile graphs can be adjusted to different values by using the 3 properties: - aggregate_rpt_pct1: Defaults to 90 - aggregate_rpt_pct2: Defaults to 95 - aggregate_rpt_pct3: Defaults to 99 ::: :::note Relative paths are built from the JMeter working directory (default: `bin`). ::: :::note You can define some overall properties which are used by the generator configuration. These properties are freely named but you should use the prefix ``` jmeter.reportgenerator. ``` in order to avoid property overlap. E.g.: **Property definition:** : ``` jmeter.reportgenerator.overall_granularity=60000 ``` **Property reference:** : ```bash \${jmeter.reportgenerator.overall_granularity} ``` ::: :::note The calculated percentiles might differ from those from the Aggregate Report in the GUI. This is because the dashboard uses a different formula to estimate the percentiles. It will be most observable when the distribution of the timing values is spread too wide. That can happen if too few samples were taken. If you want the numbers to be more or less the same as those from the Aggregate Report, you will have to switch the used [estimator](https://commons.apache.org/proper/commons-math/javadocs/api-3.6/org/apache/commons/math3/stat/descriptive/rank/Percentile.EstimationType.html) from `LEGACY` to `R_3`, by specifying the JMeter property `backend_metrics_percentile_estimator=R_3` (this time without any prefix). ::: #### 14.2.3 Graph settings Each property describing a graph configuration must be prefixed with ``` jmeter.reportgenerator.graph. ``` followed by the graph identifier. ##### 14.2.3.1 General properties All graphs support these properties: | Name | Required | Description | |------|----------|-------------| | classname | Yes | The fully qualified class name of the graph The class of the graph must extend `org.apache.jmeter.report.processor.graph.AbstractGraphConsumer`. See [Default graph section](#default_graphs) for more details. | | exclude_controllers | No | Defines whether the graph discards controller samples. Default: `false` | | title | No | Sets the title of the graph. Default: "" | ##### 14.2.3.2 Specific properties Specific graph properties must use the prefix: ``` jmeter.reportgenerator.graph.<graph_id>.property ``` The name of the property will be mapped using camel case transformation and the matching method of the class will be called with the property value as argument. E.g.: ``` jmeter.reportgenerator.graph.<graph_id>.property.set_granularity=150 ``` induces the call of the method `setGranularity(150)` on the instance of the graph. #### 14.2.4 Export settings Each property describing an exporter configuration must be prefixed with ``` jmeter.reportgenerator.exporter ``` followed by the exporter identifier. ##### 14.2.4.1 General properties All exporters support these properties: | Name | Required | Description | |------|----------|-------------| | classname | Yes | The fully qualified class name of the exporter The class of the exporter must implement `org.apache.jmeter.report.dashboard.DataExporter` . | | filters_only_sample_series | No | Defines whether `series_filter` (see below) apply only on sample series. Default: `true` | | series_filter | No | Sets the filter of series. An empty value deactivates the filtering. If not empty, regex should end with `(-success|-failure)?$` Format: regular expression. Default: "" | | show_controllers_only | No | Defines whether only controller series are shown. Default: `false` | ##### 14.2.4.2 Specific properties Specific exporter properties must use the prefix ``` jmeter.reportgenerator.exporter.<exporter_id>.property ``` | Name | Required | Description | |------|----------|-------------| | output_dir | No | Sets the destination directory for generated html pages. Default: `report-output` | | template_dir | No | Sets the source directory of template files from which the html pages are generated. Default: `report-template` | ##### 14.2.4.3 Graph properties Graph properties allow exporters to overwrite some graph data. They must use the prefix: ``` jmeter.reportgenerator.exporter.<exporter_id>.graph_options.<graph_id> ``` | Name | Required | Description | |------|----------|-------------| | minX | No | Sets the minimum abscissa for the graph. | | maxX | No | Sets the maximum abscissa for the graph. | | minY | No | Sets the minimum ordinate for the graph. | | maxY | No | Sets the maximum ordinate for the graph. | ##### 14.2.4.4 Filtering mechanisms Unlike the filtering in the section [General properties](#configure_general) which discards data before calculations, here the filtering is performed after the calculations and serves to simplify the final report. The property `series_filter` allows to filter which series of a graph (resp. rows of a summary table) using regular expression that matches the name of the series (resp. of the row). However, even if the name of the series (resp. row) matches the filter, the setting of the other filtering properties can lead to its discarding. Conversely if there is no matching, the other properties can allow to keep it. The following tables show how the setting of filtering properties works. | filter_only_sample_series | Graph/Summary supports controllers discrimination | The current series is a controller series | show_controllers_only | Discarded | | --- | --- | --- | --- | --- | | False | False | - | False | False | | True | | - | False | | True | | True | False | False | | True | | True | False | | True | | True | False | - | False | | True | | - | False | | True | | True | False | False | | True | True | | True | False | False | | True | | filter_only_sample_series | Graph/Summary supports controllers discrimination | Kept | | --- | --- | --- | | False | False | False | | True | | True | False | True | | True | False | :::note Incorrect filter configuration can lead to generate empty graphs/summary tables: - If you set the property `show_controllers_only` and the graph is configured to exclude controllers. - If the property `series_filter` matches none series. ::: #### 14.2.5 Sample configuration You can copy the following configuration to your user.properties file in order to test the report generator. ```properties # Configure this property to change the report title #jmeter.reportgenerator.report_title=Apache JMeter Dashboard # Change this parameter if you want to change the granularity of over time graphs. # Granularity must be higher than 1000 (1second) otherwise Throughput graphs will be incorrect # see Bug 60149 #jmeter.reportgenerator.overall_granularity=60000 Change this parameter if you want to change the granularity of Response time distribution # Set to 100 ms by default #jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity=100 # Change this parameter if you want to override the APDEX satisfaction threshold. jmeter.reportgenerator.apdex_satisfied_threshold=1500 # Change this parameter if you want to override the APDEX tolerance threshold. jmeter.reportgenerator.apdex_tolerated_threshold=3000 # Sets the destination directory for generated html pages, it is better to change it for every generation # This will override the value set through -o command line option # jmeter.reportgenerator.exporter.html.property.output_dir=/tmp/test-report # Indicates which graph series are filtered (regular expression) # In the below example we filter on Search and Order samples # Note that the end of the pattern should always include (-success|-failure)?$ # Transactions per second suffixes Transactions with "-success" or "-failure" depending # on the result #jmeter.reportgenerator.exporter.html.series_filter=^(Search|Order)(-success|-failure)?$ # Indicates whether series filter apply only on sample series jmeter.reportgenerator.exporter.html.filters_only_sample_series=true ``` :::note Adapt the parameter `output_dir` to your environment. ::: This configuration allows to generate a report where: - Over time graphs have a time granularity equal to 1 minute. - The satisfaction threshold for ADPEX calculation is 1 second and half. - The tolerance threshold for ADPEX calculation is 3 seconds. - The HTML files are generated in the directory `/tmp/test-report`. - Only series which the name begins with "`s0`" or "`s1`" are shown. - The previous filter only applies to graphs (resp. summary tables) where the series (resp. rows) match samples ### 14.3 Generating reports The report generation can be done as a stand alone process from a sample log file or automatically after running load test. #### 14.3.1 Generation from an existing sample CSV log file Use the following command: ``` jmeter -g <log file> -o <Path to output folder> ``` #### 14.3.2 Generation after load test Use the following command: ``` jmeter -n -t <test JMX file> -l <test log file> -e -o <Path to output folder> ``` ### 14.3.3 Generation using GUI Tools menu You can generate the HTML report using menu item `Tools → Generate HTML report`: ![Figure 14.1. HTML Report Dialog Menu](/images/screenshots/html_report_menu.png) _Figure 14.1. HTML Report Dialog Menu_ For each parameters see the following table : | Name | Required | Description | |------|----------|-------------| | Results file (csv or jtl) | Yes | The CSV output of a tes run | | user.properties file | Yes | The user.properties file used to run the load test | | Output directory | No | The directory where you want the report to be created(must be empty) | If no output directory is defined, the controller will use `\${JMETER_HOME}/bin/report-output`. You then only have to click on the `Generate report` button and wait for an information dialog to appear :::note If report generation takes more than two minutes, adjust the property `generate_report_ui.generation_timeout` ::: ### 14.4 Default graphs :::note Due to limitations of this early version, each default graph must be declared in JMeter properties. Otherwise, the graph views will be empty. ::: All graphs provided by this report engine are located in the package `org.apache.jmeter.report.processor.graph.impl` The dashboard generator provides the following graph classes: | Graph | Description | Supports controller discrimination | | --- | --- | --- | | ActiveThreadsGraphConsumer | This graph represents the number of active threads over time. | False | | BytesThroughputGraphConsumer | This graph represents the throughput of received and sent data over time. | False | | CodesPerSecondGraphConsumer | This graph represents the rate of response codes over time. | False | | HitsPerSecondGraphConsumer | This graph represents the rate of finished requests over time. | False | | LatencyOverTimeGraphConsumer | This graph represents the average latency time over time. | True | | ConnectTimeOverTimeGraphConsumer | This graph represents the connection time over time. | True | | LatencyVSRequestGraphConsumer | This graph represents the median and average latency time depending on the number of current requests. | False | | ResponseTimeDistributionGraphConsumer | This graph represents the distribution of the samples depending on their elapsed time and name. | True | | ResponseTimeOverTimeGraphConsumer | This graph represents the average response time over time. | True | | ResponseTimePercentilesGraphConsumer | This graph represents the percentiles of the elapsed time over time. | True | | ResponseTimePercentilesOverTimeGraphConsumer | This graph shows Min/Max and 3 percentiles response time over time. | True | | ResponseTimeVSRequestGraphConsumer | This graph represents the median and average response time depending on the number of current requests. | False | | TimeVSThreadGraphConsumer | This graph represents the average response time depending on the number of current active threads. The *-aggregated series represent the average response time regardless of the number of current active threads. These series are represented by a sole point because the number of current active threads is aggregated to an average. So for these points: - The abscissa is the average of the number of current active threads when samples of the series finish. - The ordinate is the average of the response time for the samples of the series regardless of the number of current active threads. | True | | TransactionsPerSecondGraphConsumer | This graph represents the rate of transaction by sample name over time. | True | ### 14.5 Generating customs graphs over time You can graph any sample_variable in CSV over time, you can customize your graphs by settings their properties in the user.properties file. They must use the id prefix `custom_`: ``` jmeter.reportgenerator.graph.custom_<your_graph_name_id>.property.<your_option_name> ``` To specify that this graph is a customized one : ``` jmeter.reportgenerator.graph.custom_<your_graph_name_id>.classname=org.apache.jmeter.report.processor.graph.impl.CustomGraphConsumer ``` | Name | Required | Description | |------|----------|-------------| | set_X_Axis | Yes | Sets the X axis name of the graph. | | set_Y_Axis | Yes | Sets the Y axis name of the graph. | | set_Content_Message | Yes | Sets the displayed message when the cursor is on a point of the graph. | | set_Sample_Variable_Name | Yes | Name of the column you want to graph in the csv. | Here is an example of a custom graph configuration that graphs the variable `ts-hit`: ``` jmeter.reportgenerator.graph.custom_testGraph.classname=org.apache.jmeter.report.processor.graph.impl.CustomGraphConsumer jmeter.reportgenerator.graph.custom_testGraph.title=Chunk Hit jmeter.reportgenerator.graph.custom_testGraph.property.set_Y_Axis=Number of Hits jmeter.reportgenerator.graph.custom_testGraph.set_X_Axis=Over Time jmeter.reportgenerator.graph.custom_testGraph.property.set_granularity=60000 jmeter.reportgenerator.graph.custom_testGraph.property.set_Sample_Variable_Name=ts-hit jmeter.reportgenerator.graph.custom_testGraph.property.set_Content_Message=Number of Hits : ``` ### 14.6 Want to improve Report Dashboard ? If you want to contribute new graphs or improve current ones, you can read this [developer documentation](/../devguide-dashboard/). Read this [documentation](/../building/) on contributing. {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Combine dashboard reports with [Real-time Results](/user-manual/realtime-results/) for live monitoring during tests. - [Listeners](/user-manual/listeners/) - configure CSV output that feeds the dashboard generator - [Best Practices](/user-manual/best-practices/) - ensure test results are clean enough for accurate APDEX scores - If the dashboard shows empty graphs, verify your CSV result file has the correct delimiter configured in `jmeter.properties` - APDEX thresholds may need tuning for your application's expected response times {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Live Statistics URL: https://docs.jmeter.ai/user-manual/realtime-results/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 15. Real-time results Since JMeter 2.13 you can get real-time results sent to a backend through the [Backend Listener](/user-manual/component-reference/#Backend_Listener) using potentially any backend (JDBC, JMS, Webservice, …) by providing a class which implements [AbstractBackendListenerClient](https://jmeter.apache.org/api/org/apache/jmeter/visualizers/backend/AbstractBackendListenerClient.html). JMeter ships with: - a GraphiteBackendListenerClient which allows you to send metrics to a Graphite Backend. This feature provides: - Live results - Nice graphs for metrics - Ability to compare 2 or more load tests - Storing monitoring data as long as JMeter results in the same backend - … - an InfluxDBBackendListenerClient introduced in JMeter 3.2 which allows you to send metrics to an InfluxDB Backend using UDP or HTTP protocols This feature provides: - Live results - Nice graphs for metrics - Ability to compare 2 or more load tests - Ability to add annotations to graphs - Storing monitoring data as long as JMeter results in the same backend - … In this document we will present the configuration setup to graph and historize the data in different backends: - InfluxDB setup for InfluxDBBackendListenerClient - InfluxDB setup for GraphiteBackendListenerClient - Grafana - Graphite ### 15.1 Metrics exposed #### 15.1.1 Thread/Virtual Users metrics Thread metrics are the following: **`<rootMetricsPrefix>test.minAT`** : Min active threads **`<rootMetricsPrefix>test.maxAT`** : Max active threads **`<rootMetricsPrefix>test.meanAT`** : Mean active threads **`<rootMetricsPrefix>test.startedT`** : Started threads **`<rootMetricsPrefix>test.endedT`** : Finished threads #### 15.1.2 Response times metrics Response related metrics are the following: **`<rootMetricsPrefix><samplerName>.ok.count`** : Number of successful responses for sampler name **`<rootMetricsPrefix><samplerName>.h.count`** : Server hits per seconds, this metric cumulates Sample Result and Sub results (if using Transaction Controller, "Generate parent sampler" should be unchecked) **`<rootMetricsPrefix><samplerName>.ok.min`** : Min response time for successful responses of sampler name **`<rootMetricsPrefix><samplerName>.ok.max`** : Max response time for successful responses of sampler name **`<rootMetricsPrefix><samplerName>.ok.avg`** : Average response time for successful responses of sampler name. **`<rootMetricsPrefix><samplerName>.ok.pct<percentileValue>`** : Percentile computed for successful responses of sampler name. There will be one metric for each calculated value. **`<rootMetricsPrefix><samplerName>.ko.count`** : Number of failed responses for sampler name **`<rootMetricsPrefix><samplerName>.ko.min`** : Min response time for failed responses of sampler name **`<rootMetricsPrefix><samplerName>.ko.max`** : Max response time for failed responses of sampler name **`<rootMetricsPrefix><samplerName>.ko.avg`** : Average response time for failed responses of sampler name. **`<rootMetricsPrefix><samplerName>.ko.pct<percentileValue>`** : Percentile computed for failed responses of sampler name. There will be one metric for each calculated value. **`<rootMetricsPrefix><samplerName>.a.count`** : Number of responses for sampler name (sum of ok.count and ko.count) **`<rootMetricsPrefix><samplerName>.sb.bytes`** : Sent Bytes **`<rootMetricsPrefix><samplerName>.rb.bytes`** : Received Bytes **`<rootMetricsPrefix><samplerName>.a.min`** : Min response time for responses of sampler name (min of ok.count and ko.count) **`<rootMetricsPrefix><samplerName>.a.max`** : Max response time for responses of sampler name (max of ok.count and ko.count) **`<rootMetricsPrefix><samplerName>.a.avg`** : Average response time for responses of sampler name (avg of ok.count and ko.count) **`<rootMetricsPrefix><samplerName>.a.pct<percentileValue>`** : Percentile computed for responses of sampler name. There will be one metric for each calculated value. (calculated on the totals for OK and failed samples) The default `percentiles` setting on the [Backend Listener](/user-manual/component-reference/#Backend_Listener) is "90;95;99", i.e. the 3 percentiles 90%, 95% and 99%. The [Graphite naming hierarchy](https://graphite.readthedocs.io/en/latest/feeding-carbon.html#step-1-plan-a-naming-hierarchy) uses dot (".") to separate elements. This could be confused with decimal percentile values. JMeter converts any such values, replacing dot (".") with underscore ("-"). For example, "`99.9`" becomes "`99_9`" By default JMeter sends metrics for all samplers accumulated under the samplerName "`all`". If the Backend Listener `samplersList` is configured, then JMeter also sends the metrics for the matching sample names unless `summaryOnly=true` ### 15.2 JMeter configuration To make JMeter send metrics to backend add a [BackendListener](/./component-reference/#Backend_Listener) using the InfluxDBBackendListenerClient. ![InfluxDB configuration](/images/screenshots/backend_listener.png) _InfluxDB configuration_ ### 15.3 InfluxDB configuration Do one of the following to store data sent by the Backend Listener: - For InfluxDB 2 setup, create a `jmeter` [bucket](https://v2.docs.influxdata.com/v2.0/organizations/buckets/create-bucket/) - For InfluxDB 1.x setup, create a `jmeter` database using the [Influx CLI](https://docs.influxdata.com/influxdb/v1.8/introduction/get-started/) You can also use the HTTP API i.e. `curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE jmeter"` #### 15.3.1 InfluxDB setup for InfluxDBBackendListenerClient InfluxDB is an open-source, distributed, time-series database that allows to easily store metrics. Installation and configuration is very easy, read this for more details [InfluxDB documentation](https://docs.influxdata.com/influxdb/latest/introduction/installation/). InfluxDB data can be easily viewed in a browser through [Grafana](http://grafana.org/). #### 15.3.2 InfluxDB 2 setup for InfluxDBBackendListenerClient The configuration should specify the `influxdbToken` parameter and also specify `bucket` and `org` as query parameters in the `influxdbUrl`. See the [InfluxDB v2 API](https://v2.docs.influxdata.com/v2.0/api/#operation/PostWrite) for more details. How to retrieve the required information in the InfluxDB UI: - [influxdbToken](https://v2.docs.influxdata.com/v2.0/security/tokens/view-tokens/) - [bucket](https://v2.docs.influxdata.com/v2.0/organizations/buckets/view-buckets/) - [org](https://v2.docs.influxdata.com/v2.0/organizations/view-orgs/) ![InfluxDB 2 configuration](/images/screenshots/backend_listener_influxdb_v2.png) _InfluxDB 2 configuration_ ### 15.4 Grafana configuration Installing grafana Read [documentation](https://docs.grafana.org/) for more details. Add the [datasource](https://docs.grafana.org/features/datasources/influxdb/) Here is the kind of dashboard that you could obtain: ![Grafana dashboard](/images/screenshots/grafana_dashboard.png) _Grafana dashboard_ ### 15.5 Graphite Configuration To make JMeter send metrics to backend, add a BackendListener using the GraphiteBackendListenerClient. [GraphiteBackendListenerClient](/./component-reference/#Backend_Listener) section will help you do the configuration. ![Graphite configuration](/images/screenshots/backend_listener_graphite.png) _Graphite configuration_ ### 15.5.1 Graphite Sender Two types of Senders are available. TextGraphiteMetricsSender, PickleGraphiteMetricsSender - For plaintext protocol, set graphiteMetricsSender parameter to `org.apache.jmeter.visualizers.backend.graphite.TextGraphiteMetricsSender` - For pickle protocol, set graphiteMetricsSender parameter to `org.apache.jmeter.visualizers.backend.graphite.PickleGraphiteMetricsSender` To send large amounts of data, use the Pickle sender. It is a more efficient transmission method compared to textplain. Read [the Graphite documentation](https://graphite.readthedocs.io/en/latest/feeding-carbon.html) for more details. ![Graphite pickle sender](/images/screenshots/backend_listener_graphite_pickle.png) _Graphite pickle sender_ {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Set up a Grafana dashboard to visualize the InfluxDB metrics streamed by the Backend Listener. - [Listeners](/user-manual/listeners/) - understand how JMeter captures sample data - [Dashboard Report](/user-manual/generating-dashboard/) - generate post-test HTML reports from the same data - If InfluxDB shows no data, check that the Backend Listener's `influxdb.url` and `application` parameters are correct - Graphite connections may be rejected if Carbon's `auth` pattern doesn't match your JMeter host {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Best Practices URL: https://docs.jmeter.ai/user-manual/best-practices/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 16. Best Practices {/* CUSTOM-INTRO:START */} :::tip[Use CLI mode for real load] Use the GUI to build and validate a test plan, then run the actual load test from the command line so rendering and listeners do not distort injector performance. ::: :::tip[Size threads from target RPS] Not sure how many concurrent users you need? Use the free [JMeter Thread Calculator](/tools/thread-calculator/) to estimate threads and ramp-up from target RPS and average response time, then validate with a pilot run. ::: :::caution[Avoid View Results Tree in load tests] View Results Tree is useful for debugging, but it keeps detailed sample data in memory. Disable it before any sustained or high-volume load test. ::: {/* CUSTOM-INTRO:END */} ## 16.1 Always use latest version of JMeter The performance of JMeter is being constantly improved, so users are highly encouraged to use the most up to date version. Ensure you always read [changes list](/../changes/) to be aware of new improvements and components. You should absolutely avoid using versions that are older than 3 versions before the last one. ## 16.2 Use the correct Number of Threads Your hardware capabilities as well as the Test Plan design will both impact the number of threads you can effectively run with JMeter. The number will also depend on how fast your server is (a faster server makes JMeter work harder since it returns a response quicker). As with any Load Testing tool, if you don't correctly size the number of threads, you will face the "Coordinated Omission" problem which can give you wrong or inaccurate results. If you need large-scale load testing, consider running multiple CLI JMeter instances on multiple machines using distributed mode (or not). When using distributed mode the result file is combined on the Controller node, if using multiple autonomous instances, the sample result files can be combined for subsequent analysis. For testing how JMeter performs on a given platform, the JavaTest sampler can be used. It does not require any network access so can give some idea as to the maximum throughput achievable. JMeter has an option to delay thread creation until the thread starts sampling, i.e. after any thread group delay and the ramp-up time for the thread itself. This allows for a very large total number of threads, provided that not too many are active concurrently. ## 16.3 Where to Put the Cookie Manager See [Building a Web Test](/user-manual/build-web-test-plan/#adding_cookie_support) for information. ## 16.4 Where to Put the Authorization Manager See [Building an Advanced Web Test](/user-manual/build-adv-web-test-plan/#header_manager) for information. ## 16.5 Using the HTTP(S) Test Script Recorder Refer to [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder) for details on setting up the recorder. The most important thing to do is filter out all requests you aren't interested in. For instance, there's no point in recording image requests (JMeter can be instructed to download all images on a page - see [HTTP Request](/user-manual/component-reference/#HTTP_Request)). These will just clutter your test plan. Most likely, there is an extension all your files share, such as `.jsp`, `.asp`, `.php`, `.html` or the like. These you should "`include`" by entering "`.*\.jsp`" as an "Include Pattern". Alternatively, you can exclude images by entering "`.*\.gif`" as an "Exclude Pattern". Depending on your application, this may or may not be a better way to go. You may also have to exclude stylesheets, javascript files, and other included files. Test out your settings to verify you are recording what you want, and then erase and start fresh. The HTTP(S) Test Script Recorder expects to find a ThreadGroup element with a Recording Controller under it where it will record HTTP Requests to. This conveniently packages all your samples under one controller, which can be given a name that describes the test case. Now, go through the steps of a Test Case. If you have no pre-defined test cases, use JMeter to record your actions to define your test cases. Once you have finished a definite series of steps, save the entire test case in an appropriately named file. Then, wipe clean and start a new test case. By doing this, you can quickly record a large number of test case "rough drafts". One of the most useful features of the HTTP(S) Test Script Recorder is that you can abstract out certain common elements from the recorded samples. By defining some [user-defined variables](/user-manual/functions/) at the Test Plan level or in [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) elements, you can have JMeter automatically replace values in you recorded samples. For instance, if you are testing an app on server "`xxx.example.com`", then you can define a variable called "`server`" with the value of "`xxx.example.com`", and anyplace that value is found in your recorded samples will be replaced with "`\${server}`". :::note Please note that matching is case-sensitive. ::: If JMeter does not record any samples, check that the browser really is using the proxy. If the browser works OK even if JMeter is not running, then the browser cannot be using the proxy. Some browsers ignore proxy settings for `localhost` or `127.0.0.1`; try using the local hostname or IP instead. The error "`unknown_ca`" probably means that you are trying to record HTTPS, and the browser has not accepted the JMeter Proxy server certificate. ## 16.6 User variables Some test plans need to use different values for different users/threads. For example, you might want to test a sequence that requires a unique login for each user. This is easy to achieve with the facilities provided by JMeter. For example: - Create a text file containing the user names and passwords, separated by commas. Put this in the same directory as your test plan. - Add a CSV DataSet configuration element to the test plan. Name the variables `USER` and `PASS`. - Replace the login name with `\${USER}` and the password with `\${PASS}` on the appropriate samplers The CSV Data Set element will read a new line for each thread. ## 16.7 Reducing resource requirements Some suggestions on reducing resource usage. - Use CLI mode: `jmeter -n -t test.jmx -l test.jtl` - Use as few Listeners as possible; if using the `-l` flag as above they can all be deleted or disabled. - Don't use "View Results Tree" or "View Results in Table" listeners during the load test, use them only during scripting phase to debug your scripts. - Rather than using lots of similar samplers, use the same sampler in a loop, and use variables (CSV Data Set) to vary the sample. [The Include Controller does not help here, as it adds all the test elements in the file to the test plan.] - Don't use functional mode - Use CSV output rather than XML - Only save the data that you need - Use as few Assertions as possible - Use the most performing scripting language (see JSR223 section) If your test needs large amounts of data - particularly if it needs to be randomised - create the test data in a file that can be read with CSV Dataset. This avoids wasting resources at run-time. ## 16.8 BeanShell server The BeanShell interpreter has a very useful feature - it can act as a server, which is accessible by telnet or http. :::note There is no security. Anyone who can connect to the port can issue any BeanShell commands. These can provide unrestricted access to the JMeter application and the host. **Do not enable the server unless the ports are protected against access, e.g. by a firewall.** ::: If you do wish to use the server, define the following in `jmeter.properties`: ``` beanshell.server.port=9000 beanshell.server.file=../extras/startup.bsh ``` In the above example, the server will be started, and will listen on ports `9000` and `9001`. Port `9000` will be used for http access. Port `9001` will be used for telnet access. The `startup.bsh` file will be processed by the server, and can be used to define various functions and set up variables. The startup file defines methods for setting and printing JMeter and system properties. This is what you should see in the JMeter console: ``` Startup script running Startup script completed Httpd started on port: 9000 Session started on port: 9001 ``` There is a sample script (`extras/remote.bsh`) you can use to test the server. [Have a look at it to see how it works.] When starting it in the JMeter `bin` directory (adjust paths as necessary if running from elsewhere) the output should look like: ```bash $ java -jar ../lib/bshclient.jar localhost 9000 ../extras/remote.bsh Connecting to BSH server on localhost:9000 Reading responses from server … BeanShell 2.0b5 - by Pat Niemeyer (pat@pat.net) bsh % remote.bsh starting user.home = C:\Documents and Settings\User user.dir = D:\eclipseworkspaces\main\JMeter_trunk\bin Setting property 'EXAMPLE' to '0'. Setting property 'EXAMPLE' to '1'. Setting property 'EXAMPLE' to '2'. Setting property 'EXAMPLE' to '3'. Setting property 'EXAMPLE' to '4'. Setting property 'EXAMPLE' to '5'. Setting property 'EXAMPLE' to '6'. Setting property 'EXAMPLE' to '7'. Setting property 'EXAMPLE' to '8'. Setting property 'EXAMPLE' to '9'. EXAMPLE = 9 remote.bsh ended bsh % … disconnected from server. ``` As a practical example, assume you have a long-running JMeter test running in CLI mode, and you want to vary the throughput at various times during the test. The test-plan includes a Constant Throughput Timer which is defined in terms of a property, e.g. `\${__P(throughput)}`. The following BeanShell commands could be used to change the test: ``` printprop("throughput"); curr = Integer.decode(args[0]); // Start value inc = Integer.decode(args[1]); // Increment end = Integer.decode(args[2]); // Final value secs = Integer.decode(args[3]); // Wait between changes while(curr <= end) { setprop("throughput",curr.toString()); // Needs to be a string here Thread.sleep(secs*1000); curr += inc; } printprop("throughput"); ``` The script can be stored in a file (`throughput.bsh`, say), and sent to the server using `bshclient.jar`. For example: ``` java -jar ../lib/bshclient.jar localhost 9000 throughput.bsh 70 5 100 60 ``` ## 16.9 BeanShell scripting :::note Since JMeter 3.1, we advise switching from BeanShell to JSR223 Test Elements (see JSR223 section below for more details), and switching from `[__Beanshell](/user-manual/functions/#__BeanShell)` function to [__groovy](/user-manual/functions/#__groovy) function. ::: ### 16.9.1 Overview Each BeanShell test element has its own copy of the interpreter (for each thread). If the test element is repeatedly called, e.g. within a loop, then the interpreter is retained between invocations unless the "`Reset bsh.Interpreter before each call`" option is selected. Some long-running tests may cause the interpreter to use lots of memory; if this is the case try using the reset option. You can test BeanShell scripts outside JMeter by using the command-line interpreter: ```bash $ java -cp bsh-xxx.jar[;other jars as needed] bsh.Interpreter file.bsh ``` or ```bash $ java -cp bsh-xxx.jar bsh.Interpreter bsh% source("file.bsh"); bsh% exit(); // or use EOF key (e.g. ^Z or ^D) ``` ### 16.9.2 Sharing Variables Variables can be defined in startup (initialisation) scripts. These will be retained across invocations of the test element, unless the reset option is used. Scripts can also access JMeter variables using the `get()` and `put()` methods of the "`vars`" variable, for example: ``` vars.get("HOST"); vars.put("MSG","Successful"); ``` The `get()` and `put()` methods only support variables with String values, but there are also `getObject()` and `putObject()` methods which can be used for arbitrary objects. JMeter variables are local to a thread, but can be used by all test elements (not just Beanshell). If you need to share variables between threads, then JMeter properties can be used: ```java import org.apache.jmeter.util.JMeterUtils; String value = JMeterUtils.getPropDefault("name",""); JMeterUtils.setProperty("name", "value"); ``` The sample `.bshrc` files contain sample definitions of `getprop()` and `setprop()` methods. Another possible method of sharing variables is to use the "`bsh.shared`" shared namespace. For example: ``` if (bsh.shared.myObj == void){ // not yet defined, so create it: myObj = new AnyObject(); } bsh.shared.myObj.process(); ``` Rather than creating the object in the test element, it can be created in the startup file defined by the JMeter property "`beanshell.init.file`". This is only processed once. ## 16.10 Developing script functions in Groovy or Jexl3 etc. It's quite hard to write and test scripts as functions. However, JMeter has the JSR223 samplers which can be used instead with any language supporting it. We advise using [Apache Groovy](http://www.groovy-lang.org/) or any language that supports the `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface of JSR223. Create a simple Test Plan containing the JSR223 Sampler and Tree View Listener. Code the script in the sampler script pane, and test it by running the test. If there are any errors, these will show up in the Tree View and `jmeter.log` file. Also the result of running the script will show up as the response. Once the script is working properly, it can be stored as a variable on the Test Plan. The script variable can then be used to create the function call. For example, suppose a Groovy script is stored in the variable `RANDOM_NAME`. The function call can then be coded as `\${__groovy(\${RANDOM_NAME})}`. There is no need to escape any commas in the script, because the function call is parsed before the variable's value is interpolated. ## 16.11 Parameterising tests Often it is useful to be able to re-run the same test with different settings. For example, changing the number of threads or loops, or changing a hostname. One way to do this is to define a set of variables on the Test Plan, and then use those variables in the test elements. For example, one could define the variable `LOOPS=10`, and refer to that in the Thread Group as `\${LOOPS}`. To run the test with 20 loops, just change the value of the `LOOPS` variable on the Test Plan. This quickly becomes tedious if you want to run lots of tests in CLI mode. One solution to this is to define the Test Plan variable in terms of a property, for example `LOOPS=\${__P(loops,10)}`. This uses the value of the property "`loops`", defaulting to `10` if the property is not found. The "`loops`" property can then be defined on the JMeter command-line: ``` jmeter … -Jloops=12 … ``` If there are a lot of properties that need to be changed together, then one way to achieve this is to use a set of property files. The appropriate property file can be passed in to JMeter using the `-q` command-line option. ## 16.12 JSR223 Elements For intensive load testing, the recommended scripting language is one whose ScriptingEngine implements the `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface. Groovy scripting engine implements `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)`. However neither Beanshell nor Javascript do so as of release date of JMeter 3.1, so it is recommended to avoid them for intensive load testing. :::note Note: Beanshell implements the `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface but it has not been coded - the method just throws an Exception. JMeter has an explicit work-round for this bug. ::: When using JSR 223 elements, it is advised to check `Cache compiled script if available` property to ensure the script compilation is cached if underlying language supports it. In this case, ensure the script does not use any variable using `\${varName}` as caching would take only first value of `\${varName}`. Instead use : ``` vars.get("varName") ``` You can also pass them as Parameters to the script and use them this way. ## 16.13 Sharing variables between threads and thread groups Variables are local to a thread; a variable set in one thread cannot be read in another. This is by design. For variables that can be determined before a test starts, see [Parameterising Tests](#parameterising_tests) (above). If the value is not known until the test starts, there are various options: - Store the variable as a property - properties are global to the JMeter instance - Write variables to a file and re-read them. - Use the `bsh.shared` namespace - see [above](#bsh_variables) - Write your own Java classes ## 16.14 Managing properties When you need to modify jmeter properties, ensure you don't modify `jmeter.properties` file, **instead copy the property from `jmeter.properties` and modify its value in `user.properties` file**. Doing so will ease you migration to the next version of JMeter. Note that in the documentation `jmeter.properties` is frequently mentioned but this should be understood as "Copy from `jmeter.properties` to `user.properties` the property you want to modify and do so in the latter file". :::note `user.properties` file supersedes the properties defined in `jmeter.properties` ::: ## 16.15 Deprecated elements It is advised not to use deprecated elements (marked as such in [changes list](/../changes/) and in [component reference](/./component-reference/)) and to migrate to new advised elements if available or new way of doing the same thing. Deprecated elements are removed from the menu in version N but can be enabled for migration by modifying `not_in_menu` property in `user.properties` file and removing the full class name of the element from there. :::note Please note that deprecated elements in version N will be removed definitely in version N+1, so ensure you stop using them as soon as possible. ::: {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Apply these practices to a [Web Test Plan](/user-manual/build-web-test-plan/) and measure the difference. - [Hints and Tips](/user-manual/hints-and-tips/) - additional community-tested techniques - [Dashboard Report](/user-manual/generating-dashboard/) - generate performance reports that reflect best practices - Using View Results Tree or View Results in Table during actual load tests causes massive memory overhead - Not accounting for Coordinated Omission skews percentile response times {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: My boss wants me to … URL: https://docs.jmeter.ai/user-manual/boss/ --- {/* SYNCED-BODY:START */} ## 17. Help! My boss wants me to load test our application! This is a fairly open-ended proposition. There are a number of questions to be asked first, and additionally a number of resources that will be needed. You will need some hardware to run the benchmarks/load-tests from. A number of tools will prove useful. There are a number of products to consider. And finally, why is Java a good choice to implement a load-testing/Benchmarking product. ### 17.1 Questions to ask What is our anticipated average number of users (normal load)? What is our anticipated peak number of users? When is a good time to load-test our application (i.e. off-hours or week-ends), bearing in mind that this may very well crash one or more of our servers? Does our application have state? If so, how does our application manage it (cookies, session-rewriting, or some other method)? What is the testing intended to achieve? ### 17.2 Resources The following resources will prove very helpful. Bear in mind that if you cannot locate these resources, **you** will become these resources. As you already have your work cut out for you, it is worth knowing who the following people are, so that you can ask them for help if you need it. #### 17.2.1 Network Who knows our network topology? If you run into any firewall or proxy issues, this will become very important. As well, a private testing network (which will therefore have very low network latency) would be a very nice thing. Knowing who can set one up for you (if you feel that this is necessary) will be very useful. If the application doesn't scale as expected, who can add additional hardware? #### 17.2.2 Application Who knows how our application functions? The normal sequence is - test (low-volume - can we benchmark our application?) - benchmark (the average number of users) - load-test (the maximum number of users) - test destructively (what is our hard limit?) The **test** process may progress from black-box testing to white-box testing (the difference is that the first requires no knowledge of the application [it is treated as a "black box"] while the second requires some knowledge of the application). It is not uncommon to discover problems with the application during this process, so be prepared to defend your work. ### 17.3 What platform should I use to run the benchmarks/load-tests? This should be a widely-used piece of hardware, with a standard (i.e. vanilla) software installation. Remember, if you publish your results, the first thing your clients will do is hire a graduate student to verify them. You might as well make it as easy for this person as you possibly can. For Windows, Windows XP Professional should be a minimum (the others do not multi-thread past 50-60 connections, and you probably anticipate more users than that). Good free platforms include the linuxes, the BSDs, and Solaris Intel. If you have a little more money, there are commercial linuxes. This may be worth it if you need the support. For non-Windows platforms, investigate "`ulimit -n unlimited`" with a view to including it in your user account startup scripts (`.bashrc` or `.cshrc` scripts for the testing account). Also note that some Linux/Unix editions are intended for server use. These generally have minimal or no GUI support. Such OSes should be OK for running JMeter in CLI mode, but JMeter GUI mode probably won't work unless you install a minimal GUI environment. As you progress to larger-scale benchmarks/load-tests, this platform will become the limiting factor. So it's worth using the best hardware and software that you have available. Remember to include the hardware/software configuration in your published benchmarks. **When you need a lot of machines or want to test the network latency, Cloud can help you.** JMeter can easily be installed on Cloud instances as it runs on nearly any architecture available in the Cloud. JMeter is also supported within Commercial Cloud PAAS if you don't want to manage it yourself. Don't forget JMeter batch (CLI) mode. This mode should be used during load testing for many reasons: - If you have a powerful server that supports Java but perhaps does not have a fast graphics implementation, or where you need to login remotely. - Batch (CLI) mode can reduce the network traffic compared with using a remote display or client-server mode. - Java AWT Thread used for GUI mode can alter injection behaviour by blocking sometimes The batch log file can then be loaded into JMeter on a workstation for analysis, or you can use CSV output and import the data into a spreadsheet. :::note Remember GUI mode is for Script creation and debugging, not for load testing ::: ### 17.4 Tools The following tools will all prove useful. It is definitely worthwhile to become familiar with them. This should include trying them out, and reading the appropriate documentation (man-pages, info-files, application --help messages, and any supplied documentation). #### 17.4.1 ping This can be used to establish whether or not you can reach your target site. Options can be specified so that '`ping`' provides the same type of route reporting as '`traceroute`'. #### 17.4.2 nslookup/dig While the **user** will normally use a human-readable internet address, **you** may wish to avoid the overhead of DNS lookups when performing benchmarking/load-testing. These can be used to determine the unique address (dotted quad) of your target site. #### 17.4.3 traceroute If you cannot "`ping`" your target site, this may be used to determine the problem (possibly a firewall or a proxy). It can also be used to estimate the overall network latency (running locally should give the lowest possible network latency - remember that your users will be running over a possibly busy internet). Generally, the fewer hops the better. ### 17.5 How can I enhance JMeter? There a lot of open-source and commercial providers who provide JMeter plugins or other resources for use with JMeter. Some of these are listed on the JMeter Wiki. They are listed under several categories: - [JMeterPlugins](https://cwiki.apache.org/confluence/display/JMETER/JMeterPlugins) - plugins for extending JMeter - [JMeterAddons](https://cwiki.apache.org/confluence/display/JMETER/JMeterAddons) - addons for use with JMeter, e.g. plugins for browsers, Maven and Jenkins. - [JMeterServices](https://cwiki.apache.org/confluence/display/JMETER/JMeterServices) - 3rd party services, e.g. cloud-based JMeter Note that appearance of these on the Wiki does not imply any endorsement by the Apache JMeter project. Any requests for support should be directed to the relevant supplier. ### 17.6 Why Java? Why not Perl or C? Well, Perl might be a very good choice except that the Benchmark package seems to give fairly fuzzy results. Also, simulating multiple users with Perl is a tricky proposition (multiple connections can be simulated by forking many processes from a shell script, but these will not be threads, they will be processes). However, the Perl community is very large. If you find that someone has already written something that seems useful, this could be a very good solution. C, of course, is a very good choice (check out the Apache `ab` tool). But be prepared to write all of the custom networking, threading, and state management code that you will need to benchmark your application. Java gives you (for free) the custom networking, threading, and state management code that you will need to benchmark your application. Java is aware of HTTP, FTP, and HTTPS - as well as RMI, IIOP, and JDBC (not to mention cookies, URL-encoding, and URL-rewriting). In addition Java gives you automatic garbage-collection, and byte-code level security. {/* SYNCED-BODY:END */} --- Title: User's Manual: Curl URL: https://docs.jmeter.ai/user-manual/curl/ --- {/* SYNCED-BODY:START */} ## 24. Curl This method is to create http requests from curl command. If you want to know more about curl, please click the [Curl document](https://curl.haxx.se/). ### 24.1 How to enter (a) command(s) Create a Test Plan From a cURL Command 1. To create an import from a cURL, open the `Tools` menu and click `Import from cURL`. ![Figure 1 - The menu where curl is located](/images/screenshots/curl/choose_curl.png) _Figure 1 - The menu where curl is located_ 2. There are two ways to enter the curl command line. Firstly, we can enter it manually. Secondly, we can import a file containing the curl command line. This tool supports input of multiple curl command lines at the same time. ![Figure 2.1 - Enter curl command in text panel](/images/screenshots/curl/enter_command.png) _Figure 2.1 - Enter curl command in text panel_ ![Figure 2.2 - Enter curl command from file](/images/screenshots/curl/enter_command_from_file.png) _Figure 2.2 - Enter curl command from file_ 3. Then, click `Create Test Plan` button and a new HTTP Sample will be added to the Test Plan. ![Figure 3 - result of Test Plan](/images/screenshots/curl/result.png) _Figure 3 - result of Test Plan_ ### 24.2 Curl options supported **`-H`, `--header <header>`** : Extra header to use when getting a web page. **`-X`, `--request <command>`** : Specifies a custom request method to use when communicating with the HTTP server. **`--compressed`** : Request a compressed response using one of the algorithms curl supports, and return the uncompressed document. **`-A`, `--user-agent <agent string>`** : Specify the User-Agent string to send to the HTTP server. **`-b`, `--cookie <name=data>`** : Pass the data to the HTTP server as a cookie. **`-d` and friends** : Sending data via POST request Sends the specified data in a POST request to the HTTP server. If this option is used more than once on the same command line, the data pieces specified will be merged together with a separating '`&`' character. Thus, using '`-d name=daniel -d skill=lousy`' would generate a POST chunk that looks like '`name=daniel&skill=lousy`'. **`-d`, `--data <data>`, `--data-ascii <data>`** : use `@` to upload a file **`--data-raw <data>`gt;** : **`--data-raw <data>`** : This posts data exactly as specified with no extra processing whatsoever. If you start the data with the character `@,` the rest should be a filename. **`--data-raw <data>`ta>** : This posts data, similar to the other `--data` options with the exception that this performs URL-encoding. **`--data-raw <data>`** : This posts data similarly to `--data` but without the special interpretation of the `@` character. **`-F` and friends** : This lets curl emulate a filled-in form in which a user has pressed the submit button. **`-F`, `--form <name=content>`** : use `@` to upload a file **`--form-string <name=content>`** : **`-u`, --user <user:password >** : Specify user and password to use for server authentication. **`--basic`, `--digest`** : Tells curl to use HTTP authentication. **`--cacert` and friends** : Tells curl to use the specified client certificate file when getting a file with HTTPS **`--cacert <CA certificate>`** **`--capath <CA certificate directory>`** **`--ciphers <list of ciphers>`** **`--cert-status`** **`--cert-type <type>`** **`-G`, `--get`** : put the post data in the URL and use get to replace post. **`--no-keepalive`** : Disables the use of keepalive messages on the TCP connection. **`-e`, `--referer <URL>`** : Sends the _Referer Page_ information to the HTTP server. **`-L`, `--location`** : If the server reports that the requested page has moved to a different location this option will make curl redo the request on the new place. **`-i`, `--include`** : Include the HTTP-header in the output. **`--connect-timeout <seconds>`** : Maximum time in seconds that the connection to the server may take. **`--keepalive-time <seconds>`** : This option sets the time a connection needs to remain idle before sending keepalive probes and the time between individual keepalive probes. **`-m`, `--max-time <seconds>`** : Maximum time in seconds that you allow the whole operation to take. **`-x`, `--proxy <[protocol://][user:password@]proxyhost[:port]>`** : Use the specified HTTP proxy. If the port number is not specified, it is assumed at port `1080`. **`-U`, `--proxy-user <user:password>`** : Specify user and password to use for proxy authentication. **`-k`, `--insecure`** : This option explicitly allows curl to perform _insecure_ SSL connections and transfers. **`--raw`** : When used, it disables all internal HTTP decoding of content or transfer encodings and instead makes them passed on unaltered,raw. **`-I`, `--head`** : Fetch the HTTP-header only. HTTP-servers feature the method `HEAD` which this uses to get nothing but the header of a document. **`--interface <name>`** : Perform an operation using a specified interface. You can enter interface name, IP address or host name. **`--proxy-ntlm`/`--proxy-negotiate`** : Tells curl to use HTTP BASIC/NTLM/Digest authentication when communicating with the given proxy. **`--dns-servers <addresses>`** : Resolve host name over DOH. **`--resolve <host:port:address>`** : Provide a custom address for a specific host and port pair. **`--limit-rate <speed>`** : Specify the maximum transfer rate you want curl to use. **`--max-redirs <num>`** : Set maximum number of redirections which may be followed. **`--noproxy <no-proxy-list>`** : Comma-separated list of hosts which do not use a proxy, if one is specified. ### 24.3 Warning When the command you entered is ignored or contains warning content, we will display warning in the comment section of HTTP Request. ![Figure 1 -Warning](/images/screenshots/curl/http_request_warning.png) _Figure 1 -Warning_ ### 24.4 Examples **Use cookie** ``` curl -X POST "https://example.invalid" -b 'username=Tom;password=123456' ``` **Use data** ``` curl -X POST "https://example.invalid" --data 'fname=a&lname=b' ``` **Use form** ``` curl -X POST "https://example.invalid" -F 'lname=a' -F 'fname=b' -F 'c=@C:\Test\test.txt' ``` **Use proxy** ``` curl 'https://example.invalid/' -x 'https://aa:bb@proxy.invalid:8042' ``` **Use authorization** ``` curl "https://example.invalid" -u 'user:passwd' --basic ``` **Use DNS** ``` curl "https://example.invalid" --dns-servers '0.0.0.0,1.1.1.1' ``` {/* SYNCED-BODY:END */} --- Title: User's Manual: Hints and Tips URL: https://docs.jmeter.ai/user-manual/hints-and-tips/ --- {/* SYNCED-BODY:START */} ## 22. Hints and Tips This section is a collection of various hints and tips that have been suggested by various questions on the JMeter User list. If you don't find what you are looking for here, please check the [JMeter Wiki](https://cwiki.apache.org/confluence/display/JMETER/Home). Also, try search the JMeter User list; someone may well have already provided a solution. ### 22.1 Passing variables between threads JMeter variables have thread scope. This is deliberate, so that threads can act independently. However sometimes there is a need to pass variables between different threads, in the same or different Thread Groups. One way to do this is to use a property instead. Properties are shared between all JMeter threads, so if one thread [sets a property](/user-manual/functions/#__setProperty), another thread can [read](/user-manual/functions/#__P) the updated value. If there is a lot of information that needs to be passed between threads, then consider using a file. For example you could use the [Save Responses to a file](/user-manual/component-reference/#Save_Responses_to_a_file) listener or perhaps a BeanShell PostProcessor in one thread, and read the file using the HTTP Sampler "`file:`" protocol, and extract the information using a PostProcessor or BeanShell element. If you can derive the data before starting the test, then it may well be better to store it in a file, read it using CSV Dataset. ### 22.2 Enabling Debug logging Most test elements include debug logging. If running a test plan from the GUI, select the test element and use the Help Menu to enable or disable logging. The Help Menu also has an option to display the GUI and test element class names. You can use these to determine the correct property setting to change the logging level. It is sometimes very useful to see Log messages to debug dynamic scripting languages like BeanShell or Apache Groovy used in JMeter. You can view log messages directly in JMeter GUI, to do so: - use menu **Options → Log Viewer**, a log console will appear at the bottom of the interface - Or click on the Warning icon in the upper right corner of GUI By default this log console is disabled, you can enable it by changing in `jmeter.properties`: ``` jmeter.loggerpanel.display=true ``` To avoid using too much memory, this components limits the number of characters used by this panel: ``` jmeter.loggerpanel.maxlength=80000 ``` ### 22.3 Searching It is sometimes hard to find in a Test Plan tree and elements using a variable or containing a certain URL or parameter. A new feature is now available since 2.6, you can access it in Menu Search. It provides search with following options: **`Case sensitive`** : Makes search case sensitive **`Regular exp.`** : Is text to search a regexp, if so Regexp will be searched in Tree of components, example "`\btest\b`" will match any component that contains test in searchable elements of the component ![Figure 1 - Search raw text in TreeView](/images/screenshots/searching/raw-search.png) _Figure 1 - Search raw text in TreeView_ ![Figure 2 - Result in TreeView](/images/screenshots/searching/raw-search-result.png) _Figure 2 - Result in TreeView_ ![Figure 3 - Search Regexp in TreeView (in this example we search whole word)](/images/screenshots/searching/regexp-search.png) _Figure 3 - Search Regexp in TreeView (in this example we search whole word)_ ![Figure 4 - Result in TreeView](/images/screenshots/searching/regexp-search-result.png) _Figure 4 - Result in TreeView_ ### 22.4 JMeter and a HiDPI screen With **Java version 9 and up**, the HiDPI (High Dot Per Inch) screens are supported. You can define the Java property **sun.java2d.uiScale** to change the scale of JMeter. The value can be an integer or percentage value. For example, on Linux, with x2 factor (200%): ```bash $ export JVM_ARGS="-Dsun.java2d.uiScale=200%" $ ./bin/jmeter ``` With **Java version 8**, the HiDPI (High Dot Per Inch) screens aren't supported in the Swing API. You can improve the JMeter's display on HiDPI screen by changing some properties: **`jmeter.hidpi.mode`** : set to `true` to activate a '_pseudo_'-hidpi mode allowing to increase size of some UI elements **`jmeter.hidpi.scale.factor`** : set to `2.0` to scale the size of some UI elements **`jmeter.toolbar.icons.size`** : with these values: `22x22` (default size), `32x32` or `48x48` (Suggested value for HiDPI) **`jmeter.tree.icons.size`** : with these values: `19x19` (default size), `24x24`, `32x32` (Suggested value for HiDPI) or `48x48` Additionally you can increase the font size of the text areas in some elements like JSR223 sampler by changing theses properties: **`jsyntaxtextarea.font.family`** : set to `Hack` to activate and to change the font and their size **`jsyntaxtextarea.font.size`** : set to a greater value, like `28` (Suggested value for HiDPI) :::note This is not a full HiDPI support and only affects - JMeter tree nodes - Icons in the toolbar - Tables content - Font size into text areas ::: ### 22.5 Autosave process configuration Since JMeter 3.0, JMeter automatically saves up to ten backups of every saved jmx files. When enabled, just before the jmx file is saved, it will be backed up to the `\${JMETER_HOME}/backups` subfolder. Backup files are named after the saved jmx file and assigned a version number that is automatically incremented, ex: `test-plan-000001.jmx`, `test-plan-000002.jmx`, `test-plan-000003.jmx`, etc. To control auto-backup, add the following properties to `user.properties`. **`backup_on_save`** : To enable/disable auto-backup, set the following property to `true`/`false` (default is `true`): ``` jmeter.gui.action.save.backup_on_save=false ``` **`backup_directory`** : The backup directory can also be set to a different location. Setting the `jmeter.gui.action.save.backup_directory` property to the path of the desired directory will cause backup files to be stored inside instead of the `\${JMETER_HOME}/backups` folder. If the specified directory does not exist it will be created. Leaving this property unset will cause the `\${JMETER_HOME}/backups` folder to be used. ``` jmeter.gui.action.save.backup_directory=/path/to/backups/dir ``` **`keep_backup_max_hours`** : You can also configure the maximum time (in hours) that backup files should be preserved since the most recent save time. By default a zero expiration time is set which instructs JMeter to preserve backup files for ever. Use the following property to control max preservation time: ``` jmeter.gui.action.save.keep_backup_max_hours=0 ``` **`keep_backup_max_count`** : You can set the maximum number of backup files that should be preserved. By default `10` backups will be kept. Setting this to zero will cause the backups to never being deleted (unless `keep_backup_max_hours` is set to a non null value) Maximum backup files selection is processed _after_ time expiration selection, so even if you set one year as the expiry time, only the `keep_backup_max_count` most recent backups files will be kept. ``` jmeter.gui.action.save.keep_backup_max_count=10 ``` ### 22.5 Adding Elements with Hotkeys When you do intense scripting with JMeter, there is a way to add elements to test plan quickly with keyboard shortcuts. Default bindings are: **`Ctrl + 0`** : Thread Group **`Ctrl + 1`** : HTTP Request **`Ctrl + 2`** : Regular Expression Extractor **`Ctrl + 3`** : Response Assertion **`Ctrl + 4`** : Constant Timer **`Ctrl + 5`** : Test Action **`Ctrl + 6`** : JSR223 PostProcessor **`Ctrl + 7`** : JSR223 PreProcessor **`Ctrl + 8`** : Debug Sampler **`Ctrl + 9`** : View Results Tree :::note The binding above are made for Windows QWERTY keyboards. For other platforms and keyboards ensure you adapt those values. ::: To change these binding, please find "`gui.quick_*`" properties within `jmeter.properties` file as example, it is recommended to put overrides for them into `user.properties` file. ### 22.6 Browser renderer is not displaying in View Results Tree If you're using OpenJDK or Oracle Java version higher than 8, you'll notice that Browser Renderer is not displayed. This is because JavaFX is not embedded. In order to have this element you need to follow the below procedure. - Follow this [documentation](https://openjfx.io/openjfx-docs/) to install Java FX for your OS and Java version. If you don't want to read it, here are the necessary steps: - Go to [Gluon website](https://gluonhq.com/products/javafx/) and download the runtime for your Java version and OS - Unzip it - Then configure a variable pointing to lib folder: Linux/MacOSX: ``` export PATH_TO_FX=path/to/javafx-sdk-XX/lib ``` Windows: ``` set PATH_TO_FX=path/to/javafx-sdk-XX/lib ``` - Then open bin/jmeter file for Linux/MacOSX, bin/jmeter.bat for Windows, find JAVA9_OPTS variable and add: Linux/MacOSX: ``` --module-path $PATH_TO_FX --add-modules javafx.web,javafx.swing ``` Windows: ``` --module-path %PATH_TO_FX% --add-modules javafx.web,javafx.swing ``` - {/* SYNCED-BODY:END */} --- Title: User's Manual: Glossary URL: https://docs.jmeter.ai/user-manual/glossary/ --- {/* SYNCED-BODY:START */} ## 23. Glossary . JMeter measures the elapsed time from just before sending the request to just after the last response has been received. JMeter does not include the time needed to render the response, nor does JMeter process any client code, for example Javascript. . JMeter measures the latency from just before sending the request to just after the first response has been received. Thus the time includes all the processing needed to assemble the request as well as assembling the first part of the response, which in general will be longer than one byte. Protocol analysers (such as Wireshark) measure the time when bytes are actually sent/received over the interface. The JMeter time should be closer to that which is experienced by a browser or other application client. . JMeter measures the time it took to establish the connection, including SSL handshake. Note that connect time is not automatically subtracted from [latency](#Latency). In case of connection error, the metric will be equal to the time it took to face the error, for example in case of Timeout, it should be equal to connection timeout. :::note As of JMeter 3.1, this metric is only computed for TCP Sampler, HTTP Request and JDBC Request. ::: is a number which divides the samples into two equal halves. Half of the samples are smaller than the median, and half are larger. [Some samples may equal the median.] This is a standard statistical measure. See, for example: [Median](http://en.wikipedia.org/wiki/Median) entry at Wikipedia. The Median is the same as the 50th Percentile is the value below which 90% of the samples fall. The remaining samples too at least as long as the value. This is a standard statistical measure. See, for example: [Percentile](http://en.wikipedia.org/wiki/Percentile) entry at Wikipedia. is a measure of the variability of a data set. This is a standard statistical measure. See, for example: [Standard Deviation](http://en.wikipedia.org/wiki/Standard_deviation) entry at Wikipedia. JMeter calculates the population standard deviation (e.g. STDEVP function in spreadsheets), not the sample standard deviation (e.g. STDEV). as it appears in Listeners and logfiles is derived from the Thread Group name and the thread within the group. The name has the format `groupName + " " + groupIndex + "-" + threadIndex` where: - groupName - name of the Thread Group element - groupIndex - number of the Thread Group in the Test Plan, starting from 1 - threadIndex - number of the thread within the Thread Group, starting from 1 A test plan with two Thread Groups each with two threads would use the names: ``` Thread Group 1-1 Thread Group 1-2 Thread Group 2-1 Thread Group 2-2 ``` is calculated as requests/unit of time. The time is calculated from the start of the first sample to the end of the last sample. This includes any intervals between samples, as it is supposed to represent the load on the server. The formula is: Throughput = (number of requests) / (total time). {/* SYNCED-BODY:END */} --- Title: User's Manual: Regular Expressions URL: https://docs.jmeter.ai/user-manual/regular-expressions/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 21. Regular Expressions ### 21.1 Overview JMeter includes the pattern matching software [Apache Jakarta ORO](http://attic.apache.org/projects/jakarta-oro.html) There is some documentation for this on the Jakarta web-site, for example [a summary of the pattern matching characters](http://archimedes.fas.harvard.edu/scrapbook/jakarta-oro-2.0.6/docs/api/org/apache/oro/text/regex/package-summary.html) There is also documentation on an older incarnation of the product at [OROMatcher User's guide](http://www.savarese.org/oro/docs/OROMatcher/index.html), which might prove useful. :::note With JMeter version 5.5 the Regex implementation can be switched from Oro to the JDK based one by setting the JMeter property `jmeter.regex.engine` to some value different than `oro`. ::: The pattern matching is very similar to the pattern matching in Perl. A full installation of Perl will include plenty of documentation on regular expressions - look for `perlrequick`, `perlretut`, `perlre` and `perlreref`. It is worth stressing the difference between "_contains_" and "_matches_", as used on the Response Assertion test element: **"_contains_"** : means that the regular expression matched at least some part of the target, so '`alphabet`' "_contains_" '`ph.b.`' because the regular expression matches the substring '`phabe`'. **"_matches_"** : means that the regular expression matched the whole target. So '`alphabet`' is "_matched_" by '`al.*t`'. In this case, it is equivalent to wrapping the regular expression in `^` and `$`, viz '`^al.*t$`'. However, this is not always the case. For example, the regular expression '`alp|.lp.*`' is "_contained_" in '`alphabet`', but does not "_match_" '`alphabet`'. Why? Because when the pattern matcher finds the sequence '`alp`' in '`alphabet`', it stops trying any other combinations - and '`alp`' is not the same as '`alphabet`', as it does not include '`habet`'. :::note Unlike Perl, there is no need to (i.e. do not) enclose the regular expression in `//`. ::: So how does one use the modifiers `ismx` etc. if there is no trailing `/`? The solution is to use _extended regular expressions_, i.e. `/abc/i` becomes `(?i)abc`. See also [Placement of modifiers](#placement) below. ### 21.2 Examples #### Extract single string Suppose you want to match the following portion of a web-page: `name="file" value="readme.txt">` and you want to extract `readme.txt`. A suitable regular expression would be: `name="file" value="(.+?)">` The special characters above are: **`(` and `)`** : these enclose the portion of the match string to be returned **`.`** : match any character **`+`** : one or more times **`?`** : don't be greedy, i.e. stop when first match succeeds Note: without the `?`, the `.+` would continue past the first `">` until it found the last possible `">` - which is probably not what was intended. Note: although the above expression works, it's more efficient to use the following expression: `name="file" value="([^"]+)">` where `[^"]` - means match anything except `"` In this case, the matching engine can stop looking as soon as it sees the first `"`, whereas in the previous case the engine has to check that it has found `">` rather than say `" >`. #### Extract multiple strings Suppose you want to match the following portion of a web-page: `name="file.name" value="readme.txt"` and you want to extract both `file.name` and `readme.txt`. A suitable regular expression would be: `name="([^"]+)" value="([^"]+)"` This would create 2 groups, which could be used in the JMeter Regular Expression Extractor template as `$1$` and `$2$`. The JMeter Regex Extractor saves the values of the groups in additional variables. For example, assume: - Reference Name: `MYREF` - Regex: `name="(.+?)" value="(.+?)"` - Template: `$1$$2$` :::note Do not enclose the regular expression in `/ /` ::: The following variables would be set: **`MYREF`** : `file.namereadme.txt` **`MYREF_g0`** : `name="file.name" value="readme.txt"` **`MYREF_g1`** : `file.name` **`MYREF_g2`** : `readme.txt` These variables can be referred to later on in the JMeter test plan, as `\${MYREF}`, `\${MYREF_g1}` etc. ### 21.3 Line mode The pattern matching behaves in various slightly different ways, depending on the setting of the multi-line and single-line modifiers. Note that the single-line and multi-line operators have nothing to do with each other; they can be specified independently. #### Single-line mode Single-line mode only affects how the '`.`' meta-character is interpreted. Default behaviour is that '`.`' matches any character except newline. In single-line mode, '`.`' also matches newline. #### Multi-line mode Multi-line mode only affects how the meta-characters '`^`' and '`$`' are interpreted. Default behaviour is that '`^`' and '`$`' only match at the very beginning and end of the string. When Multi-line mode is used, the '`^`' metacharacter matches at the beginning of every line, and the '`$`' metacharacter matches at the end of every line. ### 21.4 Meta characters Regular expressions use certain characters as meta characters - these characters have a special meaning to the RE engine. Such characters must be escaped by preceding them with `\` (backslash) in order to treat them as ordinary characters. Here is a list of the meta characters and their meaning (please check the ORO documentation if in doubt). **`(` and `)`** : grouping **`[` and `]`** : character classes **`{` and `}`** : repetition **`*`, `+` and `?`** : repetition **`.`** : wild-card character **`\`** : escape character **`|`** : alternatives **`^` and `$`** : start and end of string or line :::note Please note that ORO does not support the `\Q` and `\E` meta-characters. [In other RE engines, these can be used to quote a portion of an RE so that the meta-characters stand for themselves.] You can use function to do the equivalent, see [\$\{__escapeOroRegexpChars(valueToEscape)\}](/user-manual/functions/#__escapeOroRegexpChars). ::: The following Perl5 extended regular expressions are supported by ORO. **`(?#text)`** : An embedded comment causing text to be ignored. **`(?:regexp)`** : Groups things like "`()`" but doesn't cause the group match to be saved. **`(?=regexp)`** : A zero-width positive lookahead assertion. For example, `\w+(?=\s)` matches a word followed by whitespace, without including whitespace in the MatchResult. **`(?!regexp)`** : A zero-width negative lookahead assertion. For example `foo(?!bar)` matches any occurrence of "`foo`" that isn't followed by "`bar`". Remember that this is a zero-width assertion, which means that `a(?!b)d` will match `ad` because `a` is followed by a character that is not `b` (the `d`) and a `d` follows the zero-width assertion. **`(?imsx)`** : One or more embedded pattern-match modifiers. `i` enables case insensitivity, `m` enables multiline treatment of the input, `s` enables single line treatment of the input, and `x` enables extended whitespace comments. **Note that `(?<=regexp)` - lookbehind - is not supported.** ### 21.5 Placement of modifiers Modifiers can be placed anywhere in the regex, and apply from that point onwards. [A bug in ORO means that they cannot be used at the very end of the regex. However they would have no effect there anyway.] The single-line `(?s)` and multi-line `(?m)` modifiers are normally placed at the start of the regex. The ignore-case modifier `(?i)` may be usefully applied to just part of a regex, for example: ``` Match ExAct case or (?i)ArBiTrARY(?-i) case ``` would match `Match ExAct case or arbitrary case` as well as `Match ExAct case or ARBitrary case`, but not `Match exact case or ArBiTrARY case`. ## 21.6 Testing Regular Expressions Since JMeter 2.4, the listener [View Results Tree](/user-manual/component-reference/#View_Results_Tree) include a RegExp Tester to test regular expressions directly on sampler response data. There is a [Website](http://www.regexplanet.com/advanced/java/index.html) to test Java Regular expressions. Another approach is to use a simple test plan to test the regular expressions. The Java Request sampler can be used to generate a sample, or the HTTP Sampler can be used to load a file. Add a Debug Sampler and a Tree View Listener and changes to the regular expression can be tested quickly, without needing to access any external servers. {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Use a Regular Expression Extractor to capture dynamic tokens (like CSRF tokens) for subsequent requests. - [Functions and Variables](/user-manual/functions/) - combine regex results with JMeter functions - [Component Reference](/user-manual/component-reference/) - Response Assertion and RegEx Extractor configuration - Confusing "contains" (substring match) with "matches" (full string match) in Response Assertions - Not testing regex patterns with the RegExp Tester in View Results Tree before running load tests {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Functions and Variables URL: https://docs.jmeter.ai/user-manual/functions/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 20. Functions and Variables JMeter functions are special values that can populate fields of any Sampler or other element in a test tree. A function call looks like this: `\${__functionName(var1,var2,var3)}` Where "__functionName" matches the name of a function. Parentheses surround the parameters sent to the function, for example `\${__time(YMD)}` The actual parameters vary from function to function. Functions that require no parameters can leave off the parentheses, for example `\${__threadNum}`. If a function parameter contains a comma, then be sure to escape this with "`\`", otherwise JMeter will treat it as a parameter delimiter. For example: ```bash \${__time(EEE\, d MMM yyyy)} ``` If the comma is not escaped - e.g. `\${__javaScript(Math.max(2,5))}` - you will get an error such as: ``` ERROR - jmeter.functions.JavaScript: Error processing Javascript: [Math.max(2] org.mozilla.javascript.EvaluatorException: missing ) after argument list (<cmd>#1) ``` This is because the string "`Math.max(2,5)`" is treated as being two parameters to the __javascript function: `Math.max(2` and `5)` Other error messages are possible. Variables are referenced as follows: ``` \${VARIABLE} ``` If an undefined function or variable is referenced, JMeter does not report/log an error - the reference is returned unchanged. For example if `UNDEF` is not defined as a variable, then the value of `\${UNDEF}` is `\${UNDEF}`. Variables, functions (and properties) are all case-sensitive. JMeter trims spaces from variable names before use, so for example `\${__Random(1,63, LOTTERY )}` will use the variable '`LOTTERY`' rather than '` LOTTERY `'. :::note Properties are not the same as variables. Variables are local to a thread; properties are common to all threads, and need to be referenced using the `__P` or `__property` function. ::: :::note When using `\` before a variable for a windows path for example `C:\test\\${test}`, ensure you escape the `\` otherwise JMeter will not interpret the variable, example: `C:\\test\\\${test}`. Alternatively, just use `/` instead for the path separator - e.g. `C:/test/\${test}` - Windows JVMs will convert the separators as necessary. ::: List of functions, loosely grouped into types. | | | | | | --- | --- | --- | --- | | Information | [threadNum](#__threadNum) | get thread number | 1.X | | Information | [threadGroupName](#__threadGroupName) | get thread group name | 4.1 | | Information | [samplerName](#__samplerName) | get the sampler name (label) | 2.5 | | Information | [machineIP](#__machineIP) | get the local machine IP address | 2.6 | | Information | [machineName](#__machineName) | get the local machine name | 1.X | | Information | [time](#__time) | return current time in various formats | 2.2 | | Information | [timeShift](#__timeShift) | return a date in various formats with the specified amount of seconds/minutes/hours/days added | 3.3 | | Information | [log](#__log) | log (or display) a message (and return the value) | 2.2 | | Information | [logn](#__logn) | log (or display) a message (empty return value) | 2.2 | | Input | [StringFromFile](#__StringFromFile) | read a line from a file | 1.9 | | Input | [FileToString](#__FileToString) | read an entire file | 2.4 | | Input | [CSVRead](#__CSVRead) | read from CSV delimited file | 1.9 | | Input | [XPath](#__XPath) | Use an XPath expression to read from a file | 2.0.3 | | Input | [StringToFile](#__StringToFile) | write a string to a file | 5.2 | | Calculation | [counter](#__counter) | generate an incrementing number | 1.X | | Formatting | [dateTimeConvert](#__dateTimeConvert) | Convert a date or time from source to target format | 4.0 | | Calculation | [digest](#__digest) | Generate a digest (SHA-1, SHA-256, MD5...) | 4.0 | | Calculation | [intSum](#__intSum) | add int numbers | 1.8.1 | | Calculation | [longSum](#__longSum) | add long numbers | 2.3.2 | | Calculation | [Random](#__Random) | generate a random number | 1.9 | | Calculation | [RandomDate](#__RandomDate) | generate random date within a specific date range | 3.3 | | Calculation | [RandomFromMultipleVars](#__RandomFromMultipleVars) | extracts an element from the values of a set of variables separated by `|` | 3.1 | | Calculation | [RandomString](#__RandomString) | generate a random string | 2.6 | | Calculation | [UUID](#__UUID) | generate a random type 4 UUID | 2.9 | | Scripting | [groovy](#__groovy) | run an Apache Groovy script | 3.1 | | Scripting | [BeanShell](#__BeanShell) | run a BeanShell script | 1.X | | Scripting | [javaScript](#__javaScript) | process JavaScript (Nashorn) | 1.9 | | Scripting | [jexl2](#__jexl2) | evaluate a Commons Jexl2 expression | jexl2(2.1.1) | | Scripting | [jexl3](#__jexl3) | evaluate a Commons Jexl3 expression | jexl3 (3.0) | | Properties | [isPropDefined](#__isPropDefined) | Test if a property exists | 4.0 | | Properties | [property](#__property) | read a property | 2.0 | | Properties | [P](#__P) | read a property (shorthand method) | 2.0 | | Properties | [setProperty](#__setProperty) | set a JMeter property | 2.1 | | Variables | [split](#__split) | Split a string into variables | 2.0.2 | | Variables | [eval](#__eval) | evaluate a variable expression | 2.3.1 | | Variables | [evalVar](#__evalVar) | evaluate an expression stored in a variable | 2.3.1 | | Properties | [isVarDefined](#__isVarDefined) | Test if a variable exists | 4.0 | | Variables | [V](#__V) | evaluate a variable name | 2.3RC3 | | String | [char](#__char) | generate Unicode char values from a list of numbers | 2.3.3 | | String | [changeCase](#__changeCase) | Change case following different modes | 4.0 | | String | [escapeHtml](#__escapeHtml) | Encode strings using HTML encoding | 2.3.3 | | String | [escapeOroRegexpChars](#__escapeOroRegexpChars) | quote meta chars used by ORO regular expression | 2.9 | | String | [escapeXml](#__escapeXml) | Encode strings using XMl encoding | 3.2 | | String | [regexFunction](#__regexFunction) | parse previous response using a regular expression | 1.X | | String | [unescape](#__unescape) | Process strings containing Java escapes (e.g. \n & \t) | 2.3.3 | | String | [unescapeHtml](#__unescapeHtml) | Decode HTML-encoded strings | 2.3.3 | | String | [urldecode](#__urldecode) | Decode a application/x-www-form-urlencoded string | 2.10 | | String | [urlencode](#__urlencode) | Encode a string to a application/x-www-form-urlencoded string | 2.10 | | String | [TestPlanName](#__TestPlanName) | Return name of current test plan | 2.6 | ### 20.1 What can functions do There are two kinds of functions: user-defined static values (or variables), and built-in functions. User-defined static values allow the user to define variables to be replaced with their static value when a test tree is compiled and submitted to be run. This replacement happens once at the beginning of the test run. This could be used to replace the DOMAIN field of all HTTP requests, for example - making it a simple matter to change a test to target a different server with the same test. Note that variables cannot currently be nested; i.e. `\${Var\${N}}` does not work. The `__V` (variable) function can be used to do this: `\${__V(Var\${N})}`. You can also use `\${__BeanShell(vars.get("Var\${N}")}`. This type of replacement is possible without functions, but was less convenient and less intuitive. It required users to create default config elements that would fill in blank values of Samplers. Variables allow one to replace only part of any given value, not just filling in blank values. With built-in functions users can compute new values at run-time based on previous response data, which thread the function is in, the time, and many other sources. These values are generated fresh for every request throughout the course of the test. :::note Functions are shared between threads. Each occurrence of a function call in a test plan is handled by a separate function instance. ::: ### 20.2 Where can functions and variables be used? Functions and variables can be written into any field of any test component (apart from the TestPlan - see below). Some fields do not allow random strings because they are expecting numbers, and thus will not accept a function. However, most fields will allow functions. Functions which are used on the Test Plan have some restrictions. JMeter thread variables will have not been fully set up when the functions are processed, so variable names passed as parameters will not be set up, and variable references will not work, so `split()` and `regex()` and the variable evaluation functions won't work. The `threadNum()` function won't work (and does not make sense at test plan level). The following functions should work OK on the test plan: - intSum - longSum - machineName - BeanShell - groovy - javaScript - jexl2/jexl3 - random - time - property functions - log functions Configuration elements are processed by a separate thread. Therefore functions such as `__threadNum` do not work properly in elements such as User Defined Variables. Also note that variables defined in a UDV element are not available until the element has been processed. :::note When using variable/function references in SQL code (etc.), remember to include any necessary quotes for text strings, i.e. use ``` SELECT item from table where name='\${VAR}' ``` **not** ``` SELECT item from table where name=\${VAR} ``` (unless `VAR` itself contains the quotes) ::: ### 20.3 How to reference variables and functions Referencing a variable in a test element is done by bracketing the variable name with '`\${`' and '`}`'. Functions are referenced in the same manner, but by convention, the names of functions begin with "`__`" to avoid conflict with user value names*. Some functions take arguments to configure them, and these go in parentheses, comma-delimited. If the function takes no arguments, the parentheses can be omitted. Argument values that themselves contain commas should be escaped as necessary. If you need to include a comma in your parameter value, escape it like so: '`\,`'. This applies for example to the scripting functions - Javascript, Beanshell, Jexl, groovy - where it is necessary to escape any commas that may be needed in script method calls - e.g. ``` \${__BeanShell(vars.put("name"\,"value"))} ``` Alternatively, you can define your script as a variable, e.g. on the Test Plan: ``` SCRIPT vars.put("name","value") ``` The script can then be referenced as follows: ``` \${__BeanShell(\${SCRIPT})} ``` There is no need to escape commas in the `SCRIPT` variable because the function call is parsed before the variable is replaced with its value. This works well in conjunction with the JSR223 or BeanShell Samplers, as these can be used to test Javascript, Jexl and BeanShell scripts. Functions can reference variables and other functions, for example `\${__XPath(\${__P(xpath.file),\${XPATH})}` will use the property "`xpath.file`" as the file name and the contents of the variable `XPATH` as the expression to search for. JMeter provides a tool to help you construct function calls for various built-in functions, which you can then copy-paste. It will not automatically escape values for you, since functions can be parameters to other functions, and you should only escape values you intend as literal. :::note If a string contains a backslash('`\`') and also contains a function or variable reference, the backslash will be removed if it appears before '`$`' or '`,`' or '`\`'. This behaviour is necessary to allow for nested functions that include commas or the string `\${`. Backslashes before '`$`' or '`,`' or '`\`' are not removed if the string does not contain a function or variable reference. ::: **The value of a variable or function can be reported** using the [`__logn()`](#__logn) function. The `__logn()` function reference can be used anywhere in the test plan after the variable has been defined. Alternatively, the Java Request sampler can be used to create a sample containing variable references; the output will be shown in the appropriate Listener. Note there is a [Debug Sampler](/user-manual/component-reference/#Debug_Sampler) that can be used to display the values of variables etc. in the Tree View Listener. :::note *If you define a user-defined static variable with the same name as a built-in function, your static variable will override the built-in function. ::: ### 20.4 The Function Helper Dialog The Function Helper dialog is available from JMeter's Tools menu. ![Function Helper Dialog](/images/screenshots/function_helper_dialog.png) _Function Helper Dialog_ Using the Function Helper, you can select a function from the pull down, and assign values for its arguments. The left column in the table provides a brief description of the argument, and the right column is where you write in the value for that argument. Different functions take different arguments. Once you have done this, click the "generate" button, and the appropriate string is generated for you to copy-paste into your test plan wherever you like. ### 20.5 Functions ## __regexFunction The Regex Function is used to parse the previous response (or the value of a variable) using any regular expression (provided by user). The function returns the template string with variable values filled in. The `__regexFunction` can also store values for future use. In the sixth parameter, you can specify a reference name. After this function executes, the same values can be retrieved at later times using the syntax for user-defined values. For instance, if you enter "`refName`" as the sixth parameter you will be able to use: - `\${refName}` to refer to the computed result of the second parameter ("Template for the replacement string") parsed by this function - `\${refName_g0}` to refer to the entire match parsed by this function. - `\${refName_g1}` to refer to the first group parsed by this function. - `\${refName_g#}` to refer to the nth group parsed by this function. - `\${refName_matchNr}` to refer to the number of groups found by this function. :::note If using distributed testing, ensure you switch mode (see `jmeter.properties`) so that it's not a stripping one, see [Bug 56376](https://bz.apache.org/bugzilla/show_bug.cgi?id=56376) ::: | Name | Required | Description | |------|----------|-------------| | First argument | Yes | The first argument is the regular expression to be applied to the response data. It will grab all matches. Any parts of this expression that you wish to use in your template string, be sure to surround in parentheses. Example: `<a href="(.*)">`. This will grab the value of the link and store it as the first group (there is only 1 group). Another example: `<input type="hidden" name="(.*)" value="(.*)">`. This will grab the name as the first group, and the value as the second group. These values can be used in your template string | | Second argument | Yes | This is the template string that will replace the function at run-time. To refer to a group captured in the regular expression, use the syntax: `$[group_number]$`. I.e.: `$1$`, or `$2$`. Your template can be any string. | | Third argument | No, default=1 | The third argument tells JMeter which match to use. Your regular expression might find numerous matches. You have four choices: - An integer - Tells JMeter to use that match. '`1`' for the first found match, '`2`' for the second, and so on - `RAND` - Tells JMeter to choose a match at random. - `ALL` - Tells JMeter to use all matches, and create a template string for each one and then append them all together. This option is little used. - A float number between 0 and 1 - tells JMeter to find the Xth match using the formula: (number_of_matches_found * float_number) rounded to nearest integer. | | Fourth argument | No | If '`ALL`' was selected for the above argument value, then this argument will be inserted between each appended copy of the template value. | | Fifth argument | No | Default value returned if no match is found | | Sixth argument | No | A reference name for reusing the values parsed by this function. Stored values are `\${refName}` (the replacement template string) and `\${refName_g#}` where "`#`" is the group number from the regular expression ("`0`" can be used to refer to the entire match). | | Seventh argument | No | Input variable name. If specified, then the value of the variable is used as the input instead of using the previous sample result. | ## __counter The counter generates a new number each time it is called, starting with 1 and incrementing by +1 each time. The counter can be configured to keep each simulated user's values separate, or to use the same counter for all users. If each user's values is incremented separately, that is like counting the number of iterations through the test plan. A global counter is like counting how many times that request was run. The counter uses an integer variable to hold the count, which therefore has a maximum of 2,147,483,647. The counter function instances are completely independent. The global counter - "`FALSE`" - is separately maintained by each counter instance. **Multiple `__counter` function calls in the same iteration won't increment the value further.** If you want to have a count that increments for each sample, use the function in a Pre-Processor such as [User Parameters](/user-manual/component-reference/#User_Parameters). | Name | Required | Description | |------|----------|-------------| | First argument | Yes | `TRUE` if you wish each simulated user's counter to be kept independent and separate from the other users. `FALSE` for a global counter. | | Second argument | No | A reference name for reusing the value created by this function. Stored values are of the form `\${refName}`. This allows you to keep one counter and refer to its value in multiple places. | ## __threadNum The thread number function simply returns the number of the thread currently being executed. These numbers are only locally unique with respect to their ThreadGroup, meaning thread #1 in one threadgroup is indistinguishable from thread #1 in another threadgroup, from the point of view of this function. :::note The function returns a number between one and the max number of running threads. Note that if you're using JSR223 code with [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object (`ctx` variable), the below code returns a number between zero and (max number of running threads minus one) ``` ctx.getThreadNum() ``` ::: There are no arguments for this function. Usage Example: ```bash \${__threadNum} ``` returns a number between 1 and the max number of running threads configured in the containing Thread Group :::note This function does not work in any Configuration elements (e.g. User Defined Variables) as these are run from a separate thread. Nor does it make sense to use it on the Test Plan. ::: ## __threadGroupName The thread group name function simply returns the name of the thread group being executed. There are no arguments for this function. Usage Example: ```bash \${__threadGroupName} ``` :::note This function does not work in any Configuration elements (e.g. User Defined Variables) as these are run from a separate thread. Nor does it make sense to use it on the Test Plan. ::: ## __intSum The intSum function can be used to compute the sum of two or more integer values. :::note The reference name is optional, but it must not be a valid integer. ::: | Name | Required | Description | |------|----------|-------------| | First argument | Yes | The first int value. | | Second argument | Yes | The second int value. | | nth argument | No | The nth int value. | | last argument | No | A reference name for reusing the value computed by this function. If specified, the reference name must contain at least one non-numeric character otherwise it will be treated as another int value to be added. | Examples: ```bash \${__intSum(2,5,MYVAR)} ``` will return 7 (2+5) and store the result in MYVAR variable. So `\${MYVAR}` will be equal to 7. ```bash \${__intSum(2,5,7)} ``` will return 14 (2+5+7) and store the result in MYVAR variable. ```bash \${__intSum(1,2,5,\${MYVAR})} ``` will return 16 if MYVAR value is equal to 8, 1+2+5+\$\{MYVAR\}) ## __longSum The longSum function can be used to compute the sum of two or more long values, use this instead of __intSum whenever you know your values will not be in the interval -2147483648 to 2147483647. | Name | Required | Description | |------|----------|-------------| | First argument | Yes | The first long value. | | Second argument | Yes | The second long value. | | nth argument | No | The nth long value. | | last argument | No | A reference name for reusing the value computed by this function. If specified, the reference name must contain at least one non-numeric character otherwise it will be treated as another long value to be added. | Examples: ```bash \${__longSum(2,5,MYVAR)} ``` will return 7 (2+5) and store the result in MYVAR variable. So `\${MYVAR}` will be equal to 7. ```bash \${__longSum(2,5,7)} ``` will return 14 (2+5+7) and store the result in MYVAR variable. ```bash \${__longSum(1,2,5,\${MYVAR})} ``` will return 16 if MYVAR value is equal to 8, 1+2+5+\$\{MYVAR\}) ## __StringFromFile The StringFromFile function can be used to read strings from a text file. This is useful for running tests that require lots of variable data. For example when testing a banking application, 100s or 1000s of different account numbers might be required. See also the [CSV Data Set Config test element](/user-manual/component-reference/#CSV_Data_Set_Config) which may be easier to use. However, that does not currently support multiple input files. Each time it is called it reads the next line from the file. All threads share the same instance, so different threads will get different lines. When the end of the file is reached, it will start reading again from the beginning, unless the maximum loop count has been reached. If there are multiple references to the function in a test script, each will open the file independently, even if the file names are the same. [If the value is to be used again elsewhere, use different variable names for each function call.] :::note Function instances are shared between threads, and the file is (re-)opened by whatever thread happens to need the next line of input, so using the `threadNumber` as part of the file name will result in unpredictable behaviour. ::: If an error occurs opening or reading the file, then the function returns the string "`**ERR**`" | Name | Required | Description | |------|----------|-------------| | File Name | Yes | Path to the file name. (The path can be relative to the JMeter launch directory) If using optional sequence numbers, the path name should be suitable for passing to DecimalFormat. See below for examples. | | Variable Name | No | A reference name - `refName` - for reusing the value created by this function. Stored values are of the form `\${refName}`. Defaults to "`StringFromFile_`". | | Start sequence number | No | Initial Sequence number (if omitted, the End sequence number is treated as a loop count) | | End sequence number | No | Final sequence number (if omitted, sequence numbers can increase without limit) | The file name parameter is resolved when the file is opened or re-opened. The reference name parameter (if supplied) is resolved every time the function is executed. **Using sequence numbers:** When using the optional sequence numbers, the path name is used as the format string for `java.text.DecimalFormat`. The current sequence number is passed in as the only parameter. If the optional start number is not specified, the path name is used as is. Useful formatting sequences are: **`#`** : insert the number, with no leading zeros or spaces **`000`** : insert the number packed out to three digits with leading zeros if necessary #### Usage of format strings Here are a few format strings and the corresponding sequences they will generate. **`pin#'.'dat`** : Will generate the digits without leading zeros and treat the dot literally like `pin1.dat`, …, `pin9.dat`, `pin10.dat`, …, `pin9999.dat` **`pin000'.'dat`** : Will generate leading zeros while keeping the dot. When the numbers start having more digits then those three digits that this format suggests, the sequence will use more digits as can be seen in `pin001.dat`, … `pin099.dat`, …, `pin999.dat`, …, `pin9999.dat` **`pin'.'dat#`** : Will append digits without leading zeros while keeping the dot and generate `pin.dat1`, …, `pin.dat9`, …, `pin.dat999` If more digits are required than there are formatting characters, the number will be expanded as necessary. To prevent a formatting character from being interpreted, enclose it in single quotes. Note that "`.`" is a formatting character, and must be enclosed in single quotes (though `#.` and `000.` work as expected in locales where the decimal point is also "`.`") In other locales (e.g. `fr`), the decimal point is "`,`" - which means that "`#.`" becomes "`nnn,`". See the documentation for `DecimalFormat` for full details. If the path name does not contain any special formatting characters, the current sequence number will be appended to the name, otherwise the number will be inserted according to the formatting instructions. If the start sequence number is omitted, and the end sequence number is specified, the sequence number is interpreted as a loop count, and the file will be used at most "`end`" times. In this case the filename is not formatted. `\${__StringFromFile(PIN#'.'DAT,,1,2)}` - reads `PIN1.DAT`, `PIN2.DAT` `\${__StringFromFile(PIN.DAT,,,2)}` - reads `PIN.DAT` twice Note that the "`.`" in `PIN.DAT` above should not be quoted. In this case the start number is omitted, so the file name is used exactly as is. ## __machineName The machineName function returns the local host name. This uses the Java method `InetAddress.getLocalHost()` and passes it to `getHostName()` | Name | Required | Description | |------|----------|-------------| | Variable Name | No | A reference name for reusing the value computed by this function. | Examples: ```bash \${__machineName()} ``` will return the host name of the machine ```bash \${__machineName} ``` will return the host name of the machine ## __machineIP The machineIP function returns the local IP address. This uses the Java method `InetAddress.getLocalHost()` and passes it to `getHostAddress()` | Name | Required | Description | |------|----------|-------------| | Variable Name | No | A reference name for reusing the value computed by this function. | Examples: ```bash \${__machineIP()} ``` will return the IP address of the machine ```bash \${__machineIP} ``` will return the IP address of the machine ## __javaScript The javaScript function executes a piece of JavaScript (not Java!) code and returns its value The JMeter Javascript function calls a standalone JavaScript interpreter. Javascript is used as a scripting language, so you can do calculations etc. :::note javaScript is not the best scripting language for performances in JMeter. If your plan requires a high number of threads it is advised to use `__jexl3` or `__groovy` functions. ::: For Nashorn Engine, please see [Java Platform, Standard Edition Nashorn User's Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/). For Rhino engine, please see [Mozilla Rhino Overview](http://www.mozilla.org/rhino/overview.html) The following variables are made available to the script: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) for the function - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) object - `threadName` - String containing the current thread name - `sampler` - current [Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html) object (if any) - `sampleResult` - previous [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) object (if any) - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) object Rhinoscript allows access to static methods via its Packages object. See the [Scripting Java](https://wiki.openjdk.java.net/display/Nashorn/Rhino+Migration+Guide) documentation. For example one can access the JMeterContextService static methods thus: `Java.type("org.apache.jmeter.threads.JMeterContextService").getTotalThreads()` :::note JMeter is not a browser, and does not interpret the JavaScript in downloaded pages. ::: | Name | Required | Description | |------|----------|-------------| | Expression | Yes | The JavaScript expression to be executed. For example: - `new Date()` - return the current date and time - `Math.floor(Math.random()*(\${maxRandom}+1))` - a random number between `0` and the variable `maxRandom` - `\${minRandom}+Math.floor(Math.random()*(\${maxRandom}-\${minRandom}+1))` - a random number between the variables `minRandom` and `maxRandom` - `"\${VAR}"=="abcd"` | | Variable Name | No | A reference name for reusing the value computed by this function. | :::note Remember to include any necessary quotes for text strings and JMeter variables. Also, if the expression has commas, please make sure to escape them. For example in: ```bash \${__javaScript('\${sp}'.slice(7\,99999))} ``` the comma after `7` is escaped. ::: Examples: ```bash \${__javaScript(new Date())} ``` will return `Sat Jan 09 2016 16:22:15 GMT+0100 (CET)` ```bash \${__javaScript(new Date(),MYDATE)} ``` will return `Sat Jan 09 2016 16:22:15 GMT+0100 (CET)` and store it under variable `MYDATE` ```bash \${__javaScript(Math.floor(Math.random()*(\${maxRandom}+1)),MYRESULT)} ``` will use maxRandom variable, return a random value between 0 and maxRandom and store it in MYRESULT ```bash \${__javaScript(\${minRandom}+Math.floor(Math.random()*(\${maxRandom}-\${minRandom}+1)),MYRESULT)} ``` will use `maxRandom` and `minRandom` variables, return a random value between `maxRandom` and `minRandom` and store it under variable `MYRESULT` ```bash \${__javaScript("\${VAR}"=="abcd",MYRESULT)} ``` will compare the value of `VAR` variable with `abcd`, return `true` or `false` and store the result in MYRESULT ## __Random The random function returns a random number that lies between the given min and max values. | Name | Required | Description | |------|----------|-------------| | Minimum value | Yes | A number | | Maximum value | Yes | A bigger number | | Variable Name | No | A reference name for reusing the value computed by this function. | Examples: ```bash \${__Random(0,10)} ``` will return a random number between 0 and 10 ```bash \${__Random(0,10, MYVAR)} ``` will return a random number between 0 and 10 and store it in `MYVAR`. `\${MYVAR}` will contain the random number ## __RandomDate The RandomDate function returns a random date that lies between the given start date and end date values. | Name | Required | Description | |------|----------|-------------| | Time format | No | Format string for DateTimeFormatter (default `yyyy-MM-dd`) | | Start date | No | The start date, the default is _now_ | | End date | Yes | The end date | | Locale to use for format | No | The string format of a locale. The language code must be lowercase. The country code must be uppercase. The separator must be an underscore, e.g. `en_EN`. See [http://www.oracle.com/technetwork/java/javase/javase7locales-334809.html](http://www.oracle.com/technetwork/java/javase/javase7locales-334809.html). If omitted, by default the function uses the Apache JMeter locale one. | | Name of variable | No | The name of the variable to set. | Examples: ```bash \${__RandomDate(,,2050-07-08,,)} ``` will return a random date between _now_ and `2050-07-08`. For example `2039-06-21` ```bash \${__RandomDate(dd MM yyyy,,08 07 2050,,)} ``` will return a random date with a custom format like `04 03 2034` ## __RandomString The RandomString function returns a random String of length using characters in chars to use. | Name | Required | Description | |------|----------|-------------| | Length | Yes | A number length of generated String | | Characters to use | No | Chars used to generate String | | Variable Name | No | A reference name for reusing the value computed by this function. | Examples: ```bash \${__RandomString(5)} ``` will return a random string of 5 characters which can be readable or not ```bash \${__RandomString(10,abcdefg)} ``` will return a random string of 10 characters picked from `abcdefg` set, like `cdbgdbeebd` or `adbfeggfad`, … ```bash \${__RandomString(6,a12zeczclk, MYVAR)} ``` will return a random string of 6 characters picked from `a12zeczclk` set and store the result in `MYVAR`, `MYVAR` will contain string like `2z22ak` or `z11kce`, … ## __RandomFromMultipleVars The RandomFromMultipleVars function returns a random value based on the variable values provided by `Source Variables`. The variables can be simple or multi-valued as they can be generated by the following extractors: - [Boundary Extractor](/user-manual/component-reference/#Boundary_Extractor) - [Regular Expression Extractor](/user-manual/component-reference/#Regular_Expression_Extractor) - [CSS Selector Extractor](/user-manual/component-reference/#CSS_Selector_Extractor) - [JSON Extractor](/user-manual/component-reference/#JSON_Extractor) - [XPath Extractor](/user-manual/component-reference/#XPath_Extractor) - [XPath2 Extractor](/user-manual/component-reference/#XPath2_Extractor) Multi-value vars are the ones that are extracted when you set `-1` for `Match Numbers`. This leads to creation of match number variable called `varName_matchNr` and for each value to the creation of variable `varName_n` where n = 1, 2, 3 etc. | Name | Required | Description | |------|----------|-------------| | Source Variables | Yes | Variable names separated by `|` that contain the values that will be used as input for random computation | | Variable Name | No | A reference name for reusing the value computed by this function. | Examples: ```bash \${__RandomFromMultipleVars(val)} ``` will return a random string based on content of variable val taking into account whether they are multi-value or not ```bash \${__RandomFromMultipleVars(val1|val2)} ``` will return a random string based on content of variables val1 and val2 taking into account whether they are multi-value or not ```bash \${__RandomFromMultipleVars(val1|val2, MYVAR)} ``` will return a random string based on content of variables val1 and val2 taking into account whether they are multi-value or not and store the result in `MYVAR` ## __UUID The UUID function returns a pseudo random type 4 Universally Unique IDentifier (UUID). Examples: ```bash \${__UUID()} ``` will return UUIDs with this format : `c69e0dd1-ac6b-4f2b-8d59-5d4e8743eecd` ## __CSVRead The CSVRead function returns a string from a CSV file (c.f. [StringFromFile](#__StringFromFile)) NOTE: JMeter supports multiple file names. In most cases, the newer [CSV Data Set Config element](/user-manual/component-reference/#CSV_Data_Set_Config) is easier to use. When a filename is first encountered, the file is opened and read into an internal array. If a blank line is detected, this is treated as end of file - this allows trailing comments to be used. All subsequent references to the same file name use the same internal array. N.B. the filename case is significant to the function, even if the OS doesn't care, so `CSVRead(abc.txt,0)` and `CSVRead(aBc.txt,0)` would refer to different internal arrays. The `*ALIAS` feature allows the same file to be opened more than once, and also allows for shorter file names. Each thread has its own internal pointer to its current row in the file array. When a thread first refers to the file it will be allocated the next free row in the array, so each thread will access a different row from all other threads. [Unless there are more threads than there are rows in the array.] :::note The function splits the line at every comma by default. If you want to enter columns containing commas, then you will need to change the delimiter to a character that does not appear in any column data, by setting the property: `csvread.delimiter` ::: | Name | Required | Description | |------|----------|-------------| | File Name | Yes | The file (or `*ALIAS`) to read from | | Column number | Yes | The column number in the file. `0` = first column, `1` = second etc. "`next`" - go to next line of file. `*ALIAS` - open a file and assign it to the alias | For example, you could set up some variables as follows: - COL1a `\${__CSVRead(random.txt,0)}` - COL2a `\${__CSVRead(random.txt,1)}\${__CSVRead(random.txt,next)}` - COL1b `\${__CSVRead(random.txt,0)}` - COL2b `\${__CSVRead(random.txt,1)}\${__CSVRead(random.txt,next)}` This would read two columns from one line, and two columns from the next available line. If all the variables are defined on the same User Parameters Pre-Processor, then the lines will be consecutive. Otherwise, a different thread may grab the next line. :::note The function is not suitable for use with large files, as the entire file is stored in memory. For larger files, use [CSV Data Set Config element](/user-manual/component-reference/#CSV_Data_Set_Config) or [StringFromFile](#__StringFromFile). ::: ## __property The property function returns the value of a JMeter property. If the property value cannot be found, and no default has been supplied, it returns the property name. When supplying a default value, there is no need to provide a function name - the parameter can be set to null, and it will be ignored. For example: - `\${__property(user.dir)}` - return value of `user.dir` - `\${__property(user.dir,UDIR)}` - return value of `user.dir` and save in `UDIR` - `\${__property(abcd,ABCD,atod)}` - return value of property `abcd` (or "`atod`" if not defined) and save in `ABCD` - `\${__property(abcd,,atod)}` - return value of property `abcd` (or "`atod`" if not defined) but don't save it | Name | Required | Description | |------|----------|-------------| | Property Name | Yes | The property name to be retrieved. | | Variable Name | No | A reference name for reusing the value computed by this function. | | Default Value | No | The default value for the property. | ## __P This is a simplified property function which is intended for use with properties defined on the command line. Unlike the `__property` function, there is no option to save the value in a variable, and if no default value is supplied, it is assumed to be 1. The value of 1 was chosen because it is valid for common test variables such as loops, thread count, ramp up etc. For example: ` Define the property value: ``` jmeter -Jgroup1.threads=7 -Jhostname1=www.realhost.edu ``` Fetch the values: `\${__P(group1.threads)}` - return the value of `group1.threads` `\${__P(group1.loops)}` - return the value of `group1.loops` `\${__P(hostname,www.dummy.org)}` - return value of property `hostname` or `www.dummy.org` if not defined ` In the examples above, the first function call would return `7`, the second would return `1` and the last would return `www.dummy.org` (unless those properties were defined elsewhere!) | Name | Required | Description | |------|----------|-------------| | Property Name | Yes | The property name to be retrieved. | | Default Value | No | The default value for the property. If omitted, the default is set to "`1`". | ## __log The log function logs a message, and returns its input string | Name | Required | Description | |------|----------|-------------| | String to be logged | Yes | A string | | Log Level | No | `OUT`, `ERR`, `DEBUG`, `INFO` (default), `WARN` or `ERROR` | | Throwable text | No | If non-empty, creates a Throwable to pass to the logger | | Comment | No | If present, it is displayed in the string. Useful for identifying what is being logged. | The `OUT` and `ERR` log level names are used to direct the output to `System.out` and `System.err` respectively. In this case, the output is always printed - it does not depend on the current log setting. For example: **`\$\{__log(Message)\}`** : written to the log file as "` … thread Name : Message`" **`\$\{__log(Message,OUT)\}`** : written to console window **`\$\{__log(\$\{VAR\},,,VAR=)\}`** : written to log file as "` … thread Name VAR=value`" ## __logn The logn function logs a message, and returns the empty string | Name | Required | Description | |------|----------|-------------| | String to be logged | Yes | A string | | Log Level | No | `OUT`, `ERR`, `DEBUG`, `INFO` (default), `WARN` or `ERROR` | | Throwable text | No | If non-empty, creates a Throwable to pass to the logger | The `OUT` and `ERR` log level names are used to direct the output to `System.out` and `System.err` respectively. In this case, the output is always printed - it does not depend on the current log setting. For example: **`\$\{__logn(VAR1=\$\{VAR1\},OUT)\}`** : write the value of the variable to the console window ## __BeanShell The BeanShell function evaluates the script passed to it, and returns the result. :::note For performance it is better to use [__groovy](#__groovy) function ::: **For full details on using BeanShell, please see the BeanShell web-site at [http://www.beanshell.org/](http://www.beanshell.org/)** :::note Note that a different Interpreter is used for each independent occurrence of the function in a test script, but the same Interpreter is used for subsequent invocations. This means that variables persist across calls to the function. ::: A single instance of a function may be called from multiple threads. However the function `execute()` method is synchronised. If the property "`beanshell.function.init`" is defined, it is passed to the Interpreter as the name of a sourced file. This can be used to define common methods and variables. There is a sample init file in the bin directory: `BeanShellFunction.bshrc`. The following variables are set before the script is executed: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) for the BeanShell function (*) - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) object - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) object - `threadName` - the threadName (String) - `Sampler` - the current [Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html), if any - `SampleResult` - the current [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html), if any (*) means that this is set before the init file, if any, is processed. Other variables vary from invocation to invocation. | Name | Required | Description | |------|----------|-------------| | BeanShell script | Yes | A beanshell script (not a file name) | | Name of variable | No | A reference name for reusing the value computed by this function. | Example: **`\$\{__BeanShell(123*456)\}`** : returns `56088` **`\$\{__BeanShell(source("function.bsh"))\}`** : processes the script in `function.bsh` :::note Remember to include any necessary quotes for text strings and JMeter variables that represent text strings. ::: ## __groovy The `__groovy` function evaluates [Apache Groovy](http://groovy-lang.org/) scripts passed to it, and returns the result. If the property "`groovy.utilities`" is defined, it will be loaded by the ScriptEngine. This can be used to define common methods and variables. There is a sample init file in the `bin` directory: `utility.groovy`. The following variables are set before the script is executed: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) for the groovy function (*) - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) object - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) object - `threadName` - the threadName (String) - `sampler` - the current [Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html), if any - `prev` - the previous [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html), if any - `OUT` - System.out (*) means that this is set before the init file, if any, is processed. Other variables vary from invocation to invocation. :::note When using this function please use the variables defined above rather than using string replacement to access a variable in your script. Following this pattern will ensure that your tests are performant by ensuring that the Groovy can be cached. ::: For instance **don't** do the following: ```bash \${__groovy("\${myVar}".substring(0\,2))} ``` Imagine that the variable myVar changes with each transaction, the Groovy above cannot be cached as the script changes each time. Instead do the following, which can be cached: ```bash \${__groovy(vars.get("myVar").substring(0\,2))} ``` | Name | Required | Description | |------|----------|-------------| | Expression to evaluate | Yes | An Apache Groovy script (not a file name) :::note Argument values that themselves contain commas should be escaped as necessary. If you need to include a comma in your parameter value, escape it like this: '`\,`' ::: | | Name of variable | No | A reference name for reusing the value computed by this function. | Example: ```bash \${__groovy(123*456)} ``` : returns `56088` ```bash \${__groovy(vars.get("myVar").substring(0\,2))} ``` : If var's value is `JMeter`, it will return `JM` as it runs `String.substring(0,2)`. Note that `,` has been escaped to `\,` :::note Remember to include any necessary quotes for text strings and JMeter variables that represent text strings. ::: ## __split The split function splits the string passed to it according to the delimiter, and returns the original string. If any delimiters are adjacent, "`?`" is returned as the value. The split strings are returned in the variables `\${VAR_1}`, `\${VAR_2}` etc. The count of variables is returned in `\${VAR_n}`. A trailing delimiter is treated as a missing variable, and "`?`" is returned. Also, to allow it to work better with the ForEach controller, `__split` now deletes the first unused variable in case it was set by a previous split. Example: Define `VAR`="`a||c|`" in the test plan. ```bash \${__split(\${VAR},VAR,|)} ``` This will return the contents of `VAR`, i.e. "`a||c|`" and set the following variables: `VAR_n`=`4` `VAR_1`=`a` `VAR_2`=`?` `VAR_3`=`c` `VAR_4`=`?` `VAR_5`=`null` | Name | Required | Description | |------|----------|-------------| | String to split | Yes | A delimited string, e.g. "`a|b|c`" | | Name of variable | Yes | A reference name for reusing the value computed by this function. | | Delimiter | No | The delimiter character, e.g. `|`. If omitted, `,` is used. Note that `,` would need to be specified as `\,`. | ## __XPath The XPath function reads an XML file and matches the XPath. Each time the function is called, the next match will be returned. At end of file, it will wrap around to the start. If no nodes matched, then the function will return the empty string, and a warning message will be written to the JMeter log file. :::note Note that the entire NodeList is held in memory. ::: Example: ```bash \${__XPath(/path/to/build.xml, //target/@name)} ``` This will match all targets in `build.xml` and return the contents of the next name attribute | Name | Required | Description | |------|----------|-------------| | XML file to parse | Yes | a XML file to parse | | XPath | Yes | a XPath expression to match nodes in the XML file | ## __setProperty The setProperty function sets the value of a JMeter property. The default return value from the function is the empty string, so the function call can be used anywhere functions are valid. The original value can be returned by setting the optional 3rd parameter to "`true`". Properties are global to JMeter, so can be used to communicate between threads and thread groups | Name | Required | Description | |------|----------|-------------| | Property Name | Yes | The property name to be set. | | Property Value | Yes | The value for the property. | | True/False | No | Should the original value be returned? | ## __time The time function returns the current time in various formats. | Name | Required | Description | |------|----------|-------------| | Format | No | The format to be passed to [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). The function supports various shorthand aliases, see below. If omitted, the function returns the current time in milliseconds since the epoch. | | Name of variable | No | The name of the variable to set. | If the format string is omitted, then the function returns the current time in milliseconds since the epoch. If the format matches "`/ddd`" (where `ddd` are decimal digits), then the function returns the current time in milliseconds divided by the value of `ddd`. For example, "`/1000`" returns the current time in seconds since the epoch. Otherwise, the current time is passed to DateTimeFormatter. The following shorthand aliases are provided: - `YMD` = `yyyyMMdd` - `HMS` = `HHmmss` - `YMDHMS` = `yyyyMMdd-HHmmss` - `USER1` = whatever is in the JMeter property `time.USER1` - `USER2` = whatever is in the JMeter property `time.USER2` The defaults can be changed by setting the appropriate JMeter property, e.g. `time.YMD=yyMMdd` ```bash \${__time(dd/MM/yyyy,)} ``` will return `21/01/2018` if ran on 21 january 2018 ```bash \${__time(YMD,)} ``` will return `20180121` if ran on 21 january 2018 ```bash \${__time()} ``` will return time in millis `1516540541624` :::note The format to be passed to used to be [SimpleDateFormat](https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html), but that changed with JMeter 5.5 to [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). While they use mostly the same codes, they differ slightly. Most notable is probably the code `u`, that meant _day number of week_ and is now interpreted as _year_. ::: ## __jexl2 The jexl function returns the result of evaluating a [Commons JEXL expression](http://commons.apache.org/jexl). See links below for more information on JEXL expressions. The `__jexl2` function uses Commons JEXL 2 - [JEXL syntax description](http://commons.apache.org/proper/commons-jexl/reference/syntax.html) - [JEXL examples](http://commons.apache.org/proper/commons-jexl/reference/examples.html#Example_Expressions) | Name | Required | Description | |------|----------|-------------| | Expression | Yes | The expression to be evaluated. For example, `6*(5+2)` | | Name of variable | No | The name of the variable to set. | The following variables are made available to the script: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) for the function - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) object - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) object - `threadName` - String containing the current thread name - `sampler` - current [Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html) object (if any) - `sampleResult` - previous [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) object (if any) - `OUT` - System.out - e.g. `OUT.println("message")` Jexl can also create classes and call methods on them, for example: ``` Systemclass=log.class.forName("java.lang.System"); now=Systemclass.currentTimeMillis(); ``` Note that the Jexl documentation on the web-site wrongly suggests that "`div`" does integer division. In fact "`div`" and "`/`" both perform normal division. One can get the same effect as follows: ``` i= 5 / 2; i.intValue(); // or use i.longValue() ``` :::note JMeter allows the expression to contain multiple statements. ::: ## __jexl3 The jexl function returns the result of evaluating a [Commons JEXL expression](http://commons.apache.org/proper/commons-jexl/). See links below for more information on JEXL expressions. The `__jexl3` function uses Commons JEXL 3 - [JEXL syntax description](http://commons.apache.org/proper/commons-jexl/reference/syntax.html) - [JEXL examples](http://commons.apache.org/proper/commons-jexl/reference/examples.html#Example_Expressions) | Name | Required | Description | |------|----------|-------------| | Expression | Yes | The expression to be evaluated. For example, `6*(5+2)` | | Name of variable | No | The name of the variable to set. | The following variables are made available to the script: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) for the function - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) object - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) object - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) object - `threadName` - String containing the current thread name - `sampler` - current [Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html) object (if any) - `sampleResult` - previous [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) object (if any) - `OUT` - System.out - e.g. `OUT.println("message")` Jexl can also create classes and call methods on them, for example: ``` Systemclass=log.class.forName("java.lang.System"); now=Systemclass.currentTimeMillis(); ``` Note that the Jexl documentation on the web-site wrongly suggests that "`div`" does integer division. In fact "`div`" and "`/`" both perform normal division. One can get the same effect as follows: ``` i= 5 / 2; i.intValue(); // or use i.longValue() ``` :::note JMeter allows the expression to contain multiple statements. ::: ## __V The V (variable) function returns the result of evaluating a variable name expression. This can be used to evaluate nested variable references (which are not currently supported). For example, if one has variables `A1`,`A2` and `N`=`1`: - `\${A1}` - works OK - `\${A\${N}}` - does not work (nested variable reference) - `\${__V(A\${N})}` - works OK. `A\${N}` becomes `A1`, and the `__V` function returns the value of `A1` | Name | Required | Description | |------|----------|-------------| | Variable name | Yes | The variable to be evaluated. | | Default value | No | The default value in case no variable found, if it's empty and no variable found function returns the variable name | ## __evalVar The evalVar function returns the result of evaluating an expression stored in a variable. This allows one to read a string from a file, and process any variable references in it. For example, if the variable "`query`" contains "`select \${column} from \${table}`" and "`column`" and "`table`" contain "`name`" and "`customers`", then `\${__evalVar(query)}` will evaluate as "`select name from customers`". | Name | Required | Description | |------|----------|-------------| | Variable name | Yes | The variable to be evaluated. | ## __eval The eval function returns the result of evaluating a string expression. This allows one to interpolate variable and function references in a string which is stored in a variable. For example, given the following variables: - `name`=`Smith` - `column`=`age` - `table`=`birthdays` - `SQL`=`select \${column} from \${table} where name='\${name}'` then `\${__eval(\${SQL})}` will evaluate as "`select age from birthdays where name='Smith'`". This can be used in conjunction with CSV Dataset, for example where the both SQL statements and the values are defined in the data file. | Name | Required | Description | |------|----------|-------------| | Variable name | Yes | The variable to be evaluated. | ## __char The char function returns the result of evaluating a list of numbers as Unicode characters. See also `__unescape()`, below. This allows one to add arbitrary character values into fields. | Name | Required | Description | |------|----------|-------------| | Unicode character number (decimal or 0xhex) | Yes | The decimal number (or hex number, if prefixed by `0x`, or octal, if prefixed by `0`) to be converted to a Unicode character. | Examples: `\${__char(13,10)}` = `\${__char(0xD,0xA)}` = `\${__char(015,012)}` = `CRLF` `\${__char(165)}` = `¥` (yen) ## __unescape The unescape function returns the result of evaluating a Java-escaped string. See also `__char()` above. This allows one to add characters to fields which are otherwise tricky (or impossible) to define via the GUI. | Name | Required | Description | |------|----------|-------------| | String to unescape | Yes | The string to be unescaped. | Examples: `\${__unescape(\r\n)}` = `CRLF` `\${__unescape(1\t2)}` = `1`[tab]`2` ## __unescapeHtml Function to unescape a string containing HTML entity escapes to a string containing the actual Unicode characters corresponding to the escapes. Supports HTML 4.0 entities. For example, the string ```bash \${__unescapeHtml(<Français>)} ``` will return `<Français>`. If an entity is unrecognized, it is left alone, and inserted verbatim into the result string. e.g. `\${__unescapeHtml(>&zzzz;x)}` will return `>&zzzz;x`. Uses `StringEscapeUtils#unescapeHtml(String)` from Commons Lang. | Name | Required | Description | |------|----------|-------------| | String to unescape | Yes | The string to be unescaped. | ## __escapeHtml Function which escapes the characters in a String using HTML entities. Supports HTML 4.0 entities. For example, ```bash \${__escapeHtml("bread" & "butter")} ``` return: `"bread" & "butter"`. Uses `StringEscapeUtils#escapeHtml(String)` from Commons Lang. | Name | Required | Description | |------|----------|-------------| | String to escape | Yes | The string to be escaped. | ## __urldecode Function to decode a `application/x-www-form-urlencoded` string. Note: use UTF-8 as the encoding scheme. For example, the string ```bash \${__urldecode(Word+%22school%22+is+%22%C3%A9cole%22+in+french)} ``` returns `Word "school" is "école" in french`. Uses Java class [URLDecoder](http://docs.oracle.com/javase/7/docs/api/java/net/URLDecoder.html). | Name | Required | Description | |------|----------|-------------| | String to decode | Yes | The string with URL encoded chars to decode. | ## __urlencode Function to encode a string to a `application/x-www-form-urlencoded` string. For example, the string ```bash \${__urlencode(Word "school" is "école" in french)} ``` returns `Word+%22school%22+is+%22%C3%A9cole%22+in+french`. Uses Java class [URLEncoder](http://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html). | Name | Required | Description | |------|----------|-------------| | String to encode | Yes | String to encode in URL encoded chars. | ## __FileToString The FileToString function can be used to read an entire file. Each time it is called it reads the entire file. If an error occurs opening or reading the file, then the function returns the string "`**ERR**`" | Name | Required | Description | |------|----------|-------------| | File Name | Yes | Path to the file name. (The path can be relative to the JMeter launch directory) | | File encoding if not the platform default | No | The encoding to be used to read the file. If not specified, the platform default is used. | | Variable Name | No | A reference name - `refName` - for reusing the value created by this function. Stored values are of the form `\${refName}`. | The file name, encoding and reference name parameters are resolved every time the function is executed. ## __samplerName The samplerName function returns the name (i.e. label) of the current sampler. The function does not work in Test elements that don't have an associated sampler. For example the Test Plan. Configuration elements also don't have an associated sampler. However some Configuration elements are referenced directly by samplers, such as the HTTP Header Manager and Http Cookie Manager, and in this case the functions are resolved in the context of the Http Sampler. Pre-Processors, Post-Processors and Assertions always have an associated Sampler. Example: ```bash \${__samplerName()} ``` | Name | Required | Description | |------|----------|-------------| | Variable Name | No | A reference name - `refName` - for reusing the value created by this function. Stored values are of the form `\${refName}`. | ## __TestPlanName The TestPlanName function returns the name of the current test plan (can be used in Including Plans to know the name of the calling test plan). Example: ```bash \${__TestPlanName} ``` will return the file name of your test plan, for example if plan is in a file named Demo.jmx, it will return "`Demo.jmx` ## __escapeOroRegexpChars Function which escapes the ORO Regexp meta characters, it is the equivalent of `\Q` `\E` in Java Regexp Engine. For example, ```bash \${__escapeOroRegexpChars([^"].+?,)} ``` returns: `\[\^\"\]\.\+\?`. Uses Perl5Compiler#quotemeta(String) from ORO. | Name | Required | Description | |------|----------|-------------| | String to escape | Yes | The string to be escaped. | | Variable Name | No | A reference name - `refName` - for reusing the value created by this function. Stored values are of the form `\${refName}`. | ## __escapeXml Function which escapes the characters in a String using XML 1.0 entities. For example, ```bash \${__escapeXml("bread" & 'butter')} ``` returns: `"bread" & 'butter'`. Uses `StringEscapeUtils#escapeXml10(String)` from Commons Lang. | Name | Required | Description | |------|----------|-------------| | String to escape | Yes | The string to be escaped. | ## __timeShift The timeShift function returns a date in the given format with the specified amount of seconds, minutes, hours, days or months added | Name | Required | Description | |------|----------|-------------| | Format | No | The format to be passed to DateTimeFormatter (for input data parsing and output formating). See [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) If omitted, the function uses milliseconds since epoch format. | | Date to shift | No | Indicate the date in the format set by the parameter `Format` to shift. If omitted, the date is set to _ZonedDateTime.now_ with system zone _ZoneId.systemDefault()_. :::note If `Format` is empty then this parameter must be long value (look at examples). ::: | | value to shift | No | Indicate the specified amount of seconds, minutes, hours or days to shift according to a textual representation of a duration such as `PnDTnHnMn.nS`. See [Duration#parse(CharSequence)](https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-). If ommitted, no shifting will be done. - `PT20.345S` parses as 20.345 seconds - `PT15M` parses as 15 minutes - `PT10H` parses as 10 hours - `P2D` parses as 2 days - `-P6H3M` parses as -6 hours and -3 minutes | | Locale to use for format | No | The string format of a locale. The language code must be lowercase. The country code must be uppercase. The separator must be an underscore (`_`). For example `en_EN` See [supported locales on Java 7](http://www.oracle.com/technetwork/java/javase/javase7locales-334809.html). If omitted, by default the function uses the current locale from the JVM. | | Name of variable | No | The name of the variable to set. | Examples: ```bash \${__timeShift(dd/MM/yyyy,21/01/2018,P2D,,)} ``` returns `23/01/2018` ```bash \${__timeShift(dd MMMM yyyy,21 février 2018,P2D,fr_FR,)} ``` returns `23 février 2018` ```bash \${__timeShift(,10000,PT10S,,)} ``` returns `20000` = 10sec input + 10sec shift ```bash \${__timeShift(,,PT10S,,)} ``` returns `1632158276770` = 1632158266770 ms (now) + 10sec shift ## __digest The digest function returns an encrypted value in the specific hash algorithm with the optional salt, upper case and variable name. | Name | Required | Description | |------|----------|-------------| | Algorithm | Yes | The algorithm to be used to encrypt For possible algorithms See MessageDigest in [StandardNames](https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html) - MD2 - MD5 - SHA-1 - SHA-224 - SHA-256 - SHA-384 - SHA-512 :::note Spaces are taken into account for `Salt to add` and `String to encode` ::: | | String to encode | Yes | The String that will be encrypted | | Salt to add | No | Salt to be added to string (after it) | | Upper Case value | No | Result will be in lower case by default. Choose true to upper case results. | | Name of variable | No | The name of the variable to set. | Examples: ```bash \${__digest(MD5,Errare humanum est,,,)} ``` returns `c49f00b92667a35c63708933384dad52` ```bash \${__digest(SHA-256,Felix qui potuit rerum cognoscere causas,mysalt,,)} ``` returns `a3bc6900fe2b2fc5fa8a601a4a84e27a079bf2c581d485009bc5c00516729ac7` ## __dateTimeConvert The `__dateTimeConvert` function converts a date that is in source format to a target format storing the result optionally in the variable name. | Name | Required | Description | |------|----------|-------------| | Date String | Yes | The date string to convert from Source Date Format to Target Date Format. A date as a epoch time could be use here if Source Date Format is empty. | | Source Date Format | No | The original date format. If empty, the Date String field must be a epoch time. | | Target Date Format | Yes | The new date format | | Name of variable | No | The name of the variable to set. | Example: ```bash \${__dateTimeConvert(01212018,MMddyyyy,dd/MM/yyyy,)} ``` returns `21/01/2018` With epoch time value: 1526574881000, ```bash \${__dateTimeConvert(1526574881000,,dd/MM/yyyy HH:mm,)} ``` returns `17/05/2018 16:34` in UTC time(-Duser.timezone=GMT) ## __isPropDefined The `__isPropDefined` function returns true if property exists or false if not. | Name | Required | Description | |------|----------|-------------| | Property Name | Yes | The Property Name to be used to check if defined | Example: ```bash \${__isPropDefined(START.HMS)} ``` will return `true` ## __isVarDefined The `__isVarDefined` function returns true if variable exists or false if not. | Name | Required | Description | |------|----------|-------------| | Variable Name | Yes | The Variable Name to be used to check if defined | Example: ```bash \${__isVarDefined(JMeterThread.last_sample_ok)} ``` will return `true` ## __changeCase The change case function returns a string value which case has been changed following a specific mode. Result can optionally be saved in a JMeter variable. | Name | Required | Description | |------|----------|-------------| | String to change case | Yes | The String which case will be changed | | change case mode | No | The mode to be used to change case, for example for `ab-CD eF`: - `UPPER` result as AB-CD EF - `LOWER` result as ab-cd ed - `CAPITALIZE` result as Ab-CD eF :::note `change case mode` is case insensitive ::: If no mode is given, `UPPER` is used as default. | | Name of variable | No | The name of the variable to set. | Examples: ```bash \${__changeCase(Avaro omnia desunt\, inopi pauca\, sapienti nihil,UPPER,)} ``` will return `AVARO OMNIA DESUNT, INOPI PAUCA, SAPIENTI NIHIL` ```bash \${__changeCase(LABOR OMNIA VINCIT IMPROBUS,LOWER,)} ``` will return `labor omnia vincit improbus` ```bash \${__changeCase(omnibus viis romam pervenitur,CAPITALIZE,)} ``` will return `Omnibus viis romam pervenitur` ## __StringToFile The `__StringToFile` function can be used to write a string to a file. Each time it is called it writes a string to file appending or overwriting. The default return value from the function is the empty string | Name | Required | Description | |------|----------|-------------| | Path to file | Yes | Path to the file name.(The path is absolute) | | String to write | Yes | The string to write to the file. If you need to insert a line break in your content, use `\n` in your string. | | Append to file? | No | The way to write the string, `true` means append, `false` means overwrite. If not specified, the default append is `true`. | | File encoding if not UTF-8 | No | The encoding to be used to write to the file. If not specified, the default encoding is `UTF-8`. | ### 20.6 Pre-defined Variables Most variables are set by calling functions or by test elements such as User Defined Variables; in which case the user has full control over the variable name that is used. However some variables are defined internally by JMeter. These are listed below. - `COOKIE_cookiename` - contains the cookie value (see [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager)) - `JMeterThread.last_sample_ok` - whether or not the last sample was OK - `true`/`false`. Note: this is updated after PostProcessors and Assertions have been run. - `START` variables (see next section) ### 20.6 Pre-defined Properties The set of JMeter properties is initialised from the system properties defined when JMeter starts; additional JMeter properties are defined in `jmeter.properties`, `user.properties` or on the command line. Some built-in properties are defined by JMeter. These are listed below. For convenience, the `START` properties are also copied to variables with the same names. - `START.MS` - JMeter start time in milliseconds - `START.YMD` - JMeter start time as `yyyyMMdd` - `START.HMS` - JMeter start time as `HHmmss` - `TESTSTART.MS` - test start time in milliseconds Please note that the `START` variables / properties represent JMeter startup time, not the test start time. They are mainly intended for use in file names etc. {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Practice by parameterizing an HTTP Request sampler with `${__Random()}` and `${__time()}` functions. - [Properties Reference](/user-manual/properties-reference/) - JMeter properties that interact with variables - [Regular Expressions](/user-manual/regular-expressions/) - extract dynamic values from responses - Forgetting to escape commas in function parameters with backslash - Using `${variable}` when you need `${__V(variable)}` for nested variable resolution {/* CUSTOM-FOOTER:END */} --- Title: User's Manual: Properties Reference URL: https://docs.jmeter.ai/user-manual/properties-reference/ --- {/* SYNCED-BODY:START */} ## 19 Introduction {/* CUSTOM-INTRO:START */} :::caution[Security-sensitive setting] Properties can affect SSL, remote execution, scripting, file access, and report contents. Review changes before committing shared `user.properties` or CI overrides. ::: :::note[Version-specific behavior] Property names and defaults can change across JMeter releases. Check the installed `jmeter.properties` file when upgrading. ::: {/* CUSTOM-INTRO:END */} This document describes JMeter properties. The properties present in `jmeter.properties` or `reportgenerator.properties` should be set in the `user.properties` file. These properties are only taken into account after restarting JMeter as they are usually resolved when the class is loaded. ## 19.1 Language | Name | Required | Description | |------|----------|-------------| | language | No | Preferred GUI language. Comment out to use the JVM default locale's language. Example: ``` language=en ``` :::note This property is the only one that must be set in `jmeter.properties` file ::: :::note To fully configure language ensure you set locale, see [Internationalization: Understanding Locale in the Java Platform](http://www.oracle.com/us/technologies/java/locale-140624.html). Example for English: ``` -Duser.language=en -Duser.region=EN ``` ::: | | locales.add | No | Additional locale(s) to add to the displayed list. The current default list is: `en`, `fr`, `de`, `no`, `es`, `tr`, `ja`, `zh_CN`, `zh_TW`, `pl`, `pt_BR`. See `JMeterMenuBar#makeLanguageMenu()` The entries are a comma-separated list of language names. Example: ``` locales.add=zu ``` | ## 19.2 XML Parser | Name | Required | Description | |------|----------|-------------| | xpath.namespace.config | No | Path to a Properties file containing Namespace mapping in the form `prefix=Namespace`. Example: ``` ns=http://biz.aol.com/schema/2006-12-18 ``` | | xpath2query.parser.cache.size | No | XPath2 query cache for storing compiled XPath queries Defaults to `400` | ## 19.3 SSL configuration :::note SSL (Java) System properties are now in `system.properties` JMeter no longer converts `javax._xxx_` property entries in `jmeter.properties` into System properties. These must now be defined in the `system.properties` file or on the command-line. The `system.properties` file gives more flexibility. ::: | Name | Required | Description | |------|----------|-------------| | https.sessioncontext.shared | No | By default, SSL session contexts are now created per-thread, rather than being shared. The old behaviour can be enabled by setting this property to `true`. Defaults to: `false` | | https.default.protocol | No | Be aware that https default protocol may vary depending on the version of JVM. See [Diagnosing TLS, SSL and HTTPS](https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https) and [Bug 58236](https://bz.apache.org/bugzilla/show_bug.cgi?id=58236). Default HTTPS protocol level: ``` https.default.protocol=TLS ``` This may need to be changed to: ``` https.default.protocol=SSLv3 ``` | | https.socket.protocols | No | List of protocols to enable. You may have to select only a subset if you find issues with target server. This is needed when server does not support Socket version negotiation, this can lead to errors like: `javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated` or `java.net.SocketException: Connection reset`. See [Bug 54759](https://bz.apache.org/bugzilla/show_bug.cgi?id=54759), example: ``` https.socket.protocols=SSLv2Hello SSLv3 TLSv1 ``` | | https.cipherSuites | No | Comma-separated list of SSL cipher suites that may be used in HTTPS connections. It may be desirable to use a subset of cipher suites in order to match expected client behavior or to reduce encryption overhead in JMeter when running with large numbers of users. Errors may occur if the JVM does not support the specified cipher suites, or if the cipher suites supported by the HTTPS server do not overlap this list. See the [JSSE Reference Guide.](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#Customization) For example: ``` https.cipherSuites=TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256 ``` If not specified, JMeter will use the default list of cipher suites supported by the JVM. | | httpclient.reset_state_on_thread_group_iteration | No | Reset HTTP State when starting a new Thread Group iteration. In summary`true` means next iteration is associated to a new user. `false` means next iteration is associated to same user. `true` involves: - Closing opened connection - resetting SSL State Defaults to: `true` | | https.use.cached.ssl.context | No | Control if we allow reuse of cached SSL context between iterations. Set the value to `false` to reset the SSL context each iteration. Defaults to: `true` :::note DEPRECATED, you should use `httpclient.reset_state_on_thread_group_iteration` with correct value ::: | | https.keyStoreStartIndex | No | Start index to be used with keystores with many entries. The default is to use entry `0`, i.e. the first. Defaults to: `0` | | https.keyStoreEndIndex | No | End index to be used with keystores with many entries. Defaults to: `0` | ## 19.4 Look and Feel configuration | Name | Required | Description | |------|----------|-------------| | jmeter.laf.windows_10 | No | Classname of the Swing default UI The LAF classnames that are available are now displayed as ToolTip text when hovering over the Options/Look and Feel selection list. You can either use a full class name, as shown below, or one of the strings "`System`" or "`CrossPlatform`" which means JMeter will use the corresponding string returned by `UIManager.get<name>LookAndFeelClassName()`. LAF can be overridden by `os.name` (lowercased, spaces replaced by '_'). #### Order of LAF property lookup Take for example an `os.name` of `Windows 10`. JMeter would look first for a property ``` jmeter.laf.windows_10=javax.swing.plaf.metal.MetalLookAndFeel ``` Failing that, the OS family `os.name` would be used shortened to the first space. In our example JMeter would therefore look for a property ``` jmeter.laf.windows=com.sun.java.swing.plaf.windows.WindowsLookAndFeel ``` :::note Mac apparently looks better with the System LAF set through ``` jmeter.laf.mac=System ``` Failing that, the JMeter default LAF can be defined through: ``` jmeter.laf=System ``` If none of the above `jmeter.laf` properties are defined, JMeter uses the `CrossPlatform` LAF. This is because the `CrossPlatform` LAF generally looks better than the `System` LAF. See [Bug 52026](https://bz.apache.org/bugzilla/show_bug.cgi?id=52026) for details. ::: :::note When you change Look and Feel (LAF) from JMeter GUI through menu Options > Look and Feel, you should restart JMeter to ensure change is fully effective. ::: | | jmeter.loggerpanel.display | No | Display LoggerPanel. Defaults to: `false` | | jmeter.loggerpanel.enable_when_closed | No | Enable LogViewer Panel to receive log event even when closed. Enabled since 2.12 :::note Note this has some impact on performances, but as GUI mode must not be used for Load Test it is acceptable ::: Defaults to: `true` | | jmeter.loggerpanel.maxlength | No | Max lines kept in LoggerPanel, `0` means no limit. Defaults to: `1000` | | jmeter.gui.refresh_period | No | Interval period in `ms` to process the events of the listeners. Defaults to: `500` | ## 19.4.1 Darklaf configuration | Name | Required | Description | |------|----------|-------------| | darklaf.decorations | No | Enables custom window chrome when using a Darklaf Look And Feel. Defaults to: `false` | | darklaf.unifiedMenuBar | No | Enables the unified menubar on Windows when using a Darklaf Look and Feel. This property only has an effect if `darklaf.native` is `true`. Defaults to: `true` | ## 19.5 Toolbar display | Name | Required | Description | |------|----------|-------------| | jmeter.toolbar.icons | No | Toolbar icon definitions. Defaults to `org/apache/jmeter/images/toolbar/icons-toolbar.properties` | | jmeter.toolbar | No | Toolbar list. Defaults to: ``` new,open,close,save,save_as_testplan,|,cut,copy,paste,|,expand,collapse,toggle,|,test_start,test_stop,test_shutdown,|,test_start_remote_all,test_stop_remote_all,test_shutdown_remote_all,|,test_clear,test_clear_all,|,search,search_reset,|,function_helper,help ``` | | jmeter.toolbar.icons.size | No | Available sizes are: `22x22`, `32x32`, `48x48`. Suggested value for HiDPI mode is ``` jmeter.toolbar.icons.size=48x48 ``` Defaults to: `22x22` | | jmeter.icons | No | Icon definitions. Alternate set: ``` jmeter.icons=org/apache/jmeter/images/icon_1.properties ``` Historical icon set (deprecated): ``` jmeter.icons=org/apache/jmeter/images/icon_old.properties ``` Defaults to:`org/apache/jmeter/images/icon.properties` | | jmeter.tree.icons.size | No | Available sizes are: `19x19`, `24x24`, `32x32`, `48x48`. Useful for HiDPI display (see below). Defaults to: `19x19` Suggested value for HiDPI screen like 3200x1800 is: `32x32` | | jmeter.hidpi.mode | No | HiDPI mode. Activate a '_pseudo_'-HiDPI mode. Allows to increase size of some UI elements which are not correctly managed by JVM with high resolution screens in Linux or Windows. Defaults to: `false` | | jmeter.hidpi.scale.factor | No | HiDPI scale factor. Suggested value for HiDPI: `2.0`. Defaults to: `1.0` | | not_in_menu | No | Components to not display in JMeter GUI (GUI class name or static label). | | undo.history.size | No | Number of items in undo history. Feature is disabled by default (`0`) due to known and not fixed bugs [Bug 57043](https://bz.apache.org/bugzilla/show_bug.cgi?id=57043), [Bug 57039](https://bz.apache.org/bugzilla/show_bug.cgi?id=57039) and [Bug 57040](https://bz.apache.org/bugzilla/show_bug.cgi?id=57040). Set it to a number greater than zero (`25` can be a good default). The bigger it is, the more memory will be consumed. Defaults to: `0` | | gui.quick_X | No | Hotkeys to add JMeter components where `_X_` is the shortcut key, for example: ``` gui.quick_0=ThreadGroupGui gui.quick_1=HttpTestSampleGui gui.quick_2=RegexExtractorGui gui.quick_3=AssertionGui gui.quick_4=ConstantTimerGui gui.quick_5=TestActionGui gui.quick_6=JSR223PostProcessor gui.quick_7=JSR223PreProcessor gui.quick_8=DebugSampler gui.quick_9=ViewResultsFullVisualizer ``` Above code will add the corresponding elements when you press `Ctrl + 0` … `Ctrl + 9` (`&command; + 0` … `&command; + 9` on Mac) | ## 19.6 JMX Backup configuration | Name | Required | Description | |------|----------|-------------| | jmeter.gui.action.save.backup_on_save | No | Enable auto backups of the `.jmx` file when a test plan is saved. When enabled, before the `.jmx` is saved, it will be backed up to the directory pointed to by the `jmeter.gui.action.save.backup_directory` property (see below). Backup file names are built after the jmx file being saved. For example, saving `test-plan.jmx` will create a `test-plan-000012.jmx` in the backup directory provided that the last created backup file is `test-plan-000011.jmx`. Default value is `true` indicating that auto backups are enabled. Defaults to: `true` | | jmeter.gui.action.save.backup_directory | No | Set the backup directory path where JMX backups will be created upon save in the GUI. If not set (what it defaults to) then backup files will be created in a sub-directory of the JMeter base installation. If set and the directory does not exist, a corresponding directory will be created. Defaults to: `\${JMETER_HOME}/backups` | | jmeter.gui.action.save.keep_backup_max_hours | No | Set the maximum time (in hours) that backup files should be preserved since the save time. By default no expiration time is set which means we keep backups for ever. Defaults to: `0` | | jmeter.gui.action.save.keep_backup_max_count | No | Set the maximum number of backup files that should be preserved. By default ten backups will be preserved. Setting this to zero will cause the backups to not being deleted (unless `keep_backup_max_hours` is set to a non zero value). Defaults to: `10` | | save_automatically_before_run | No | Enable auto saving of the .jmx file before start run a test plan When enabled, before the run, the .jmx will be saved and also backed up to the directory pointed. Defaults to: `true` | ## 19.7 Remote hosts and RMI configuration | Name | Required | Description | |------|----------|-------------| | remote_hosts | No | Remote Hosts - comma delimited, for example ``` remote_hosts=localhost:1099,localhost:2010 ``` Defaults to: `127.0.0.1` | | server_port | No | RMI port to be used by the server (must start `rmiregistry` with same port). To change the port to (say) `1234`: On the server(s): 1. `set server_port=1234` 2. start `rmiregistry` with port `1234` On Windows this can be done by: ``` SET SERVER_PORT=1234 JMETER-SERVER ``` On Unix: ``` SERVER_PORT=1234 jmeter-server ``` On the Windows client: ``` set remote_hosts=_server_:1234 ``` On the Unix client: ``` export remote_hosts=_server_:1234 ``` Defaults to: `1099` | | client.rmi.localport | No | Parameter that controls the RMI ports used by `RemoteSampleListenerImpl` and `RemoteThreadsListenerImpl` (The Controller) Default value is `0`, which means ports are randomly assigned. If this is non-zero, it will be used as the base for local port numbers for the client engine. At the moment JMeter will open up to three ports beginning with the port defined in this property. :::note You may need to open corresponding ports in the firewall on the Controller machine. ::: Defaults to: `0` | | client.tries | No | When distributed test is starting, there may be several attempts to initialize remote engines. By default, only a single try is made. Increase this property to make it retry additional times. Defaults to: `1` | | client.retries_delay | No | If initialization is retried, this property sets the delay between those attempts in milliseconds. Defaults to: `5000` | | client.continue_on_fail | No | When all initialization tries were made, the test will fail, if any remote engines are failed. Set this property to `true` to ignore failed nodes and proceed with test. Defaults to: `false` | | server.rmi.port | No | To change the default port (`1099`) used to access the server. Defaults to: `1099` | | server.rmi.localport | No | To use a specific port for the JMeter server engine, define this property before starting the server. Defaults to: `4000` | | server.rmi.create | No | From JMeter version 2.3.1, the JMeter server creates the RMI registry as part of the server process. Set this property to `false`, to stop the server creating the RMI registry. Defaults to: `true` | | server.exitaftertest | No | From JMeter version 2.3.1, define this property to cause JMeter to exit after the first test. Defaults to: `true` | | server.rmi.ssl.keystore.type | No | Type of keystore for RMI connection security. Possible values are dependent on the JVM in use, but commonly supported are `JKS` and `PKCS12`. Defaults to: `JKS` | | server.rmi.ssl.keystore.file | No | Keystore file that contains private key Defaults to: `rmi_keystore.jks` | | server.rmi.ssl.keystore.password | No | Password of Keystore Defaults to: `changeit` | | server.rmi.ssl.keystore.alias | No | Key alias Defaults to: `rmi` | | server.rmi.ssl.truststore.type | No | Type of truststore for RMI connection security Defaults to: the value of `server.rmi.ssl.keystore.type`, which is `JKS` | | server.rmi.ssl.truststore.file | No | Keystore file that contains certificate Defaults to: the value of `server.rmi.ssl.keystore.file`, which is `rmi_keystore.jks` | | server.rmi.ssl.truststore.password | No | Password of Trust store Defaults to: the value of `server.rmi.ssl.keystore.password`, which is `changeit` | | server.rmi.ssl.disable | No | Set this to `true` if you don't want to use SSL for RMI Defaults to: `false` | ## 19.8 Include Controller | Name | Required | Description | |------|----------|-------------| | includecontroller.prefix | No | Prefix used by `IncludeController` when building file names. Defaults to empty value | ## 19.9 HTTP Java configuration | Name | Required | Description | |------|----------|-------------| | http.java.sampler.retries | No | Number of connection retries performed by HTTP Java sampler before giving up. `0` means no retry since version 3.0. Defaults to: `0` | ## 19.10 Apache HttpClient common properties | Name | Required | Description | |------|----------|-------------| | http.post_add_content_type_if_missing | No | Should JMeter add to POST request a Header `Content-type: application/x-www-form-urlencoded` if missing? Was true before version 4.1. Defaults to: `false` | | httpclient.timeout | No | Set the socket timeout (or use the parameter `http.socket.timeout`) for AJP Sampler. Value is in milliseconds, `0` means no timeout. Defaults to: `0` | | httpclient.version | No | Set the http version. Defaults to: `1.1` (or use the parameter `http.protocol.version`) | | httpclient.socket.http.cps | No | Set characters per second to a value greater then zero to emulate slow connections. Defaults to: `0` | | httpclient.socket.https.cps | No | Same as before but for https. Defaults to: `0` | | httpclient.loopback | No | Enable loopback protocol. Defaults to: `true` | | httpclient.localaddress | No | Define the local host address to be used for multi-homed hosts, example ``` httpclient.localaddress=1.2.3.4 ``` | | http.proxyUser | No | Set the user name to use with a proxy. | | http.proxyPass | No | Set the password to use with a proxy. | ## 19.11 Kerberos properties | Name | Required | Description | |------|----------|-------------| | kerberos_jaas_application | No | AuthManager Kerberos configuration Name of application module used in `jaas.conf`. Defaults to: `JMeter` | | kerberos.spnego.strip_port | No | Should port be stripped from urls before constructing SPNs for SPNEGO authentication. Defaults to: `true` | | kerberos.spnego.use_canonical_host_name | No | Should the host name for constructing SPN be canonicalized for SPNEGO authentication. | | kerberos.spnego.delegate_cred | No | Should SPNEGO authentication should use delegation of credentials. Defaults to: `false` | ## 19.12 Apache HttpClient logging examples Enable header wire and context logging - Best for Debugging In log4j2.xml, set: ``` <Logger name="org.apache.http" level="debug" /> <Logger name="org.apache.http.wire" level="error" /> ``` Enable full wire and context logging In log4j2.xml, set: ``` <Logger name="org.apache.http" level="debug" /> ``` Enable context logging for connection management ``` <Logger name="org.apache.http.impl.conn" level="debug" /> ``` Enable context logging for connection management / request execution ``` <Logger name="org.apache.http.impl.conn" level="debug" /> <Logger name="org.apache.http.impl.client" level="debug" /> <Logger name="org.apache.http.client" level="debug" /> ``` ## 19.13 Apache HttpComponents HTTPClient configuration (HTTPClient4) | Name | Required | Description | |------|----------|-------------| | hc.parameters.file | No | Define a properties file for overriding Apache HttpClient parameters. Uncomment this line if you put anything in `hc.parameters` file. Defaults to: `hc.parameters` | | httpclient4.auth.preemptive | No | Preemptively send Authorization Header when BASIC auth is used Defaults to: `true` | | httpclient4.retrycount | No | Number of retries to attempt. Retry will be done on Idempotent Http Methods by default. If you want to retry for all methods, see property `httpclient4.request_sent_retry_enabled` Defaults to: `0` | | httpclient4.request_sent_retry_enabled | No | Set this property to `true` if it's OK to retry requests that have been sent. This mean that both Idempotent and non Idempotent requests will be retried. This should usually be false, but it can be useful when testing against some Load Balancers like Amazon ELB. Defaults to: `false` | | httpclient4.idletimeout | No | Idle connection timeout (in milliseconds) to apply if the server does not send `Keep-Alive` timeout headers. Defaults to: `0` (no suggested duration for `Keep-Alived` connections) | | httpclient4.validate_after_inactivity | No | Check connection if the elapsed time (in milliseconds) since the last use of the connection exceeds this value. Ensure this value is always lower by at least 150 ms than `httpclient4.time_to_live` Defaults to: `4900` | | httpclient4.time_to_live | No | TTL (in milliseconds) represents an absolute value. No matter what, the connection will not be re-used beyond its TTL. Defaults to: `60000` | | httpclient4.deflate_relax_mode | No | Ignore EOFException that some edgy application may emit to signal end of Deflated stream. Defaults to: `false` | | httpclient4.gzip_relax_mode | No | Ignore EOFException that some edgy application may emit to signal end of GZipped stream. Defaults to: `false` | | httpclient4.default_user_agent_disabled | No | If true, default HC4 User-Agent (Apache-HttpClient/X.Y.Z (Java/A.B.C_D)) will not be added. Defaults to: `false` | ## 19.14 HTTP Cache Manager configuration | Name | Required | Description | |------|----------|-------------| | cacheable_methods | No | Space or comma separated list of methods that can be cached. Defaults to: `GET` | | cache_manager.cached_resource_mode | No | :::note N.B. This property is currently a temporary solution for [Bug 56162](https://bz.apache.org/bugzilla/show_bug.cgi?id=56162). ::: Since version 2.12, JMeter does not create anymore a Sample Result with a response code of `204` for a resource found in cache. This is in line with what browser do. You can choose between three modes: **`RETURN_NO_SAMPLE` (default)** : this mode returns no Sample Result. It has no additional configuration. **`RETURN_200_CACHE`** : this mode will return Sample Result with response code to `200` and response message to "`(ex cache)`". **`RETURN_CUSTOM_STATUS`** : choosing this mode, response code and message have to be set by specifying `RETURN_CUSTOM_STATUS.code` and `RETURN_CUSTOM_STATUS.message`. Defaults to: `RETURN_NO_SAMPLE` | | RETURN_CUSTOM_STATUS.code | No | This lets you select what response code you want to return if mode `RETURN_CUSTOM_STATUS` is selected. Defaults to empty value. | | RETURN_CUSTOM_STATUS.message | No | This lets you select what response message you want to return if mode `RETURN_CUSTOM_STATUS` is selected. Defaults to empty value | ## 19.15 Results file configuration | Name | Required | Description | |------|----------|-------------| | jmeter.save.saveservice.output_format | No | This section helps determine how result data will be saved. The commented out values are the defaults. Legitimate values: `xml`, `csv`, `db`. Only `xml` and `csv` are currently supported. Defaults to: `csv` | | jmeter.save.saveservice.assertion_results_failure_message | No | `true` when field should be saved; `false` otherwise. `assertion_results_failure_message` only affects CSV output. Defaults to: `true` | | jmeter.save.saveservice.assertion_results | No | Legitimate values: `none`, `first`, `all`. Defaults to: `none` | | jmeter.save.saveservice.data_type | No | Defaults to: `true` | | jmeter.save.saveservice.label | No | Defaults to: `true` | | jmeter.save.saveservice.response_code | No | Defaults to: `true` | | jmeter.save.saveservice.response_data | No | :::note `response_data` is currently not supported for CSV output ::: Defaults to: `false` | | jmeter.save.saveservice.response_data.on_error | No | Save ResponseData for failed samples. Defaults to: `false` | | jmeter.save.saveservice.response_message | No | Defaults to: `true` | | jmeter.save.saveservice.successful | No | Defaults to: `true` | | jmeter.save.saveservice.thread_name | No | Defaults to: `true` | | jmeter.save.saveservice.time | No | Defaults to: `true` | | jmeter.save.saveservice.subresults | No | Defaults to: `true` | | jmeter.save.saveservice.assertions | No | Defaults to: `true` | | jmeter.save.saveservice.latency | No | Defaults to: `true` | | jmeter.save.saveservice.connect_time | No | Defaults to: `false` | | jmeter.save.saveservice.samplerData | No | Defaults to: `false` | | jmeter.save.saveservice.responseHeaders | No | Defaults to: `false` | | jmeter.save.saveservice.requestHeaders | No | Defaults to: `false` | | jmeter.save.saveservice.encoding | No | Defaults to: `false` | | jmeter.save.saveservice.bytes | No | Defaults to: `true` | | jmeter.save.saveservice.url | No | Defaults to: `false` | | jmeter.save.saveservice.filename | No | Defaults to: `false` | | jmeter.save.saveservice.hostname | No | Defaults to: `false` | | jmeter.save.saveservice.thread_counts | No | Defaults to: `true` | | jmeter.save.saveservice.sample_count | No | Defaults to: `false` | | jmeter.save.saveservice.idle_time | No | Defaults to: `true` | | jmeter.save.saveservice.timestamp_format | No | Timestamp format - this only affects CSV output files. Legitimate values: `none`, `ms`, or a format suitable for `SimpleDateFormat`. Defaults to: `ms` | | jmeter.save.saveservice.timestamp_format | No | Defaults to: `yyyy/MM/dd HH:mm:ss.SSS` | | jmeter.save.saveservice.default_delimiter | No | For use with Comma-separated value (CSV) files or other formats where the fields' values are separated by specified delimiters. Defaults to: `,` :::note For TAB, one can use `\t` ::: | | jmeter.save.saveservice.print_field_names | No | Only applies to CSV format files: Print field names as first line in CSV Defaults to: `true` | | sample_variables | No | Optional list of JMeter variable names whose values are to be saved in the result data files. Use commas to separate the names. Defaults to: `SESSION_ID,REFERENCE` | | jmeter.save.saveservice.xml_pi | No | :::note N.B. The current implementation saves the values in XML as attributes, so the names must be valid XML names. ::: Versions of JMeter after 2.3.2 send the variable to all servers to ensure that the correct data is available at the client. Optional XML processing instruction for line two of the file. Defaults to empty value | | jmeter.save.saveservice.base_prefix | No | Prefix used to identify filenames that are relative to the current base. Defaults to: `~/` | | jmeter.save.saveservice.autoflush | No | AutoFlush on each line written in XML or CSV output. Setting this to `true` will result in less test results data loss in case of a crash, but with impact on performances, particularly for intensive tests (low or no pauses). Since JMeter version 2.10, this is `false` by default. Defaults to: `false` | ## 19.16 Settings that affect SampleResults | Name | Required | Description | |------|----------|-------------| | sampleresult.timestamp.start | No | Save the start time stamp instead of the end. This also affects the timestamp stored in result files. Defaults to: `false` | | sampleresult.useNanoTime | No | Whether to use `System.nanoTime()` - otherwise only use `System.currentTimeMillis()`. Defaults to: `true` | | sampleresult.nanoThreadSleep | No | Use a background thread to calculate the nanoTime offset. Set this to a value less than zero to disable the background thread. Defaults to: `5000` | | subresults.disable_renaming | No | Since version 5.0 JMeter has a new SubResult Naming Policy which numbers subresults by default This property if set to `true` discards renaming policy. This can be required if you're using JMeter for functional testing. Defaults to: `false` | ## 19.17 Upgrade | Name | Required | Description | |------|----------|-------------| | upgrade_properties | No | File that holds a record of name changes for backward compatibility issues. Defaults to: `/bin/upgrade.properties` | ## 19.18 JMeter Test Script recorder configuration | Name | Required | Description | |------|----------|-------------| | proxy.pause | No | :::note N.B. The element was originally called the Proxy recorder, which is why the properties have the prefix "proxy". ::: If the recorder detects a gap of at least 5s (default) between HTTP requests, it assumes that the user has clicked a new URL. Specified in milliseconds. Defaults to: `5000` | | proxy.number.requests | No | Add numeric suffix to Sampler names. defaults to: `true` | | proxy.sampler_format | No | Default format string for new samplers when `Use format string` is selected as `naming scheme`. Defaults to: `#{counter,number,000} - #{path} (#{name})` | | proxy.excludes.suggested | No | List of URL patterns that will be added to URL Patterns to exclude. Separate multiple lines with `;` Defaults to: `.*\\.(bmp|css|js|gif|ico|jpe?g|png|swf|woff|woff2)` | | jmeter.httpsampler | No | Change the default HTTP Sampler. Can be one of **`HTTPSampler` or `Java`** : Use the `Java` Sampler **`HTTPSampler2`** **`HttpClient4`** : Use Apache HTTPClient version 4 Defaults to: `HttpClient4` | | jmeter.httpclient.strict_rfc2616 | No | By default JMeter tries to be more lenient with [RFC 2616](http://tools.ietf.org/html/rfc2616) redirects and allows relative paths. If you want to test strict conformance, set this value to `true`. When the property is `true`, JMeter follows [RFC 3986 section 5.2](https://tools.ietf.org/html/3986#section-5.2). Defaults to: `false` | | proxy.content_type_include | No | Default `content-type` include filter to use. Specified as a regex. Defaults to: `text/html|text/plain|text/xml` | | proxy.content_type_exclude | No | Default `content-type` exclude filter to use. Specified as a regex. Defaults to: `image/.*|text/css|application/.*` | | proxy.headers.remove | No | Default headers to remove from Header Manager elements. Specified as comma separated list :::note The headers `Cookie` and `Authorization` are always removed. ::: Defaults to: `If-Modified-Since,If-None-Match,Host` | | proxy.binary.types | No | Binary `content-type` handling. These `content-types` will be handled by saving the request in a file. Defaults to: `application/x-amf,application/x-java-serialized-object,binary/octet-stream` | | proxy.binary.directory | No | The files will be saved in this directory. Defaults to: `user.dir` | | proxy.binary.filesuffix | No | The files will be created suffixed with this value. Defaults to: `.binary` | | proxy.redirect.disabling | No | Whether to attempt disabling of samples that resulted from redirects where the generated samples use auto-redirection. Defaults to: `true` | | proxy.ssl.protocol | No | SSL configuration. Defaults to: `TLS` | ## 19.19 Test Script Recorder certificate configuration | Name | Required | Description | |------|----------|-------------| | proxy.cert.directory | No | Defaults to: _JMeter `bin` directory_ | | proxy.cert.file | No | Defaults to: `proxyserver.jks` | | proxy.cert.type | No | Defaults to: `JKS` | | proxy.cert.keystorepass | No | Defaults to: `password` | | proxy.cert.keypassword | No | Defaults to: `password` | | proxy.cert.factory | No | Defaults to: `SunX509` | | proxy.cert.alias | No | Define this property if you wish to use a special entry from the keystore. Defaults to empty value | | proxy.cert.validity | No | The default validity (in days) for certificates created by JMeter. Defaults to: `7` | | proxy.cert.dynamic_keys | No | Use dynamic key generation (if supported by JMeter/JVM). If `false`, will revert to using a single key with no certificate. Defaults to: `true` | ## 19.20 JMeter Proxy configuration | Name | Required | Description | |------|----------|-------------| | http.proxyDomain | No | Use command-line flags for user-name and password. Defaults to: NTLM domain, if required by HTTPClient sampler | ## 19.21 HTML Parser configuration | Name | Required | Description | |------|----------|-------------| | HTTPResponse.parsers | No | Space-separated list of parser groups. :::note For each parser, there should be a `_parser_.types` and a `_parser_.className` property ::: Defaults to: `htmlParser wmlParser cssParser` | | cssParser.className | No | CSS Parser based on ph-css. Defaults to: `org.apache.jmeter.protocol.http.parser.CssParser` | | cssParser.types | No | Content types handled by cssParser. Defaults to: `text/css` | | css.parser.cache.size | No | CSS parser LRU cache size. This cache stores the URLs found in a CSS to avoid continuously parsing the CSS. By default the cache size is 400. It can be disabled by setting its value to 0. Defaults to: `400` | | css.parser.ignore_all_css_errors | No | Let the CSS Parser ignore all CSS errors. Defaults to: `true` | | htmlParser.className | Yes | Define the HTML parser to be used. Do not comment this property. **`org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser`** : This new parser (since 2.10) should perform better than all others. See [Bug 55632](https://bz.apache.org/bugzilla/show_bug.cgi?id=55632). **`org.apache.jmeter.protocol.http.parser.JTidyHTMLParser`** : Default parser before JMeter version 2.10 **`org.apache.jmeter.protocol.http.parser.RegexpHTMLParser`** : :::note Note that Regexp extractor may detect references that have been commented out. ::: In many cases it will work OK, but you should be aware that it may generate additional references. **`org.apache.jmeter.protocol.http.parser.JsoupBasedHtmlParser`** : This parser is based on JSoup. It should be the most accurate parser, but it is less performant than LagartoBasedHtmlParser Defaults to: `org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser` | | htmlParser.types | No | Used by HTTPSamplerBase to associate htmlParser with content types below. Defaults to: `text/html application/xhtml+xml application/xml text/xml` | | wmlParser.className | No | Defaults to: `org.apache.jmeter.protocol.http.parser.RegexpHTMLParser` | | wmlParser.types | No | Used by HTTPSamplerBase to associate wmlParser with content types below. Defaults to: `text/vnd.wap.wml` | ## 19.22 Remote batching configuration Configure how SampleResults are sent from server to client when using distributed testing. :::note Note that the mode is currently resolved on the client, while other properties (e.g. `time_threshold`) are resolved on the server. ::: Since JMeter version 2.9, default is `StrippedBatch`, which returns samples in batch mode (every 100 samples or every minute by default). You can set mode by configuring: ``` mode=_one of the possible modes below_ ``` :::note StrippedBatch strips response data from SampleResult, so if you need the response data, change to another mode. ::: Possible modes are: **`Standard`** : Sends SampleResult one by one **`Batch`** : Accumulates SampleResults before sending them. Configured by properties `num_sample_threshold` and `time_threshold` **`Statistical`** : returns sample summary statistics. Configured by properties `key_on_threadname` and `time_threshold` **`Stripped`** : Similar to `Standard` mode but strips Response from SampleResult. Configured by property `sample_sender_strip_also_on_error` **`StrippedBatch`** : Same as `Batch` but strips Response from SampleResult. Configured by properties `num_sample_threshold`, `time_threshold` and `sample_sender_strip_also_on_error` **`Asynch`** : Asynchronous sender; uses a queue and background worker process to return the samples. Configured by property `asynch.batch.queue.size` **`StrippedAsynch`** : Same as `Asynch` but strips response data from SampleResult. Configured by properties `asynch.batch.queue.size` and `sample_sender_strip_also_on_error` **`StrippedDiskStore`** : Same as `DiskStore` but strips response data from SampleResult **Class extending [`AbstractSampleSender`](https://jmeter.apache.org/api/org/apache/jmeter/samplers/AbstractSampleSender.html) (`org.example.load.MySampleSender` for example)** : A custom implementation of your choice | Name | Required | Description | |------|----------|-------------| | sample_sender_client_configured | No | How is Sample sender implementations configured: **`true`** : (default) means client configuration will be used **`false`** : means server configuration will be used Defaults to: `true` | | sample_sender_strip_also_on_error | No | By default when Stripping modes are used JMeter since version 3.1 will strip response even for SampleResults in error. If you want to revert to previous behaviour (no stripping of Responses in error) set this property to `false` Defaults to: `true` | | mode | No | Remote batching support. Since JMeter version 2.9, default is `StrippedBatch`, which returns samples in batch mode (every 100 samples or every minute by default). :::note Note also that StrippedBatch strips response data from SampleResult, so if you need the response data, change to another mode. ::: | | key_on_threadname | No | Set to `true` to key statistical samples on `threadName` rather than `threadGroup`. Defaults to: `false` | | num_sample_threshold | No | Number of SampleResults to accumulate before sending to client. Defaults to: `100` | | time_threshold | No | Time to retain SampleResults before sending them to client. Value is in milliseconds. Defaults to: `60000` | | asynch.batch.queue.size | No | Default queue size used by `Async` mode. Defaults to: `100` | ## 19.23 JDBC Request configuration | Name | Required | Description | |------|----------|-------------| | jdbcsampler.nullmarker | No | String used to indicate a null value. Defaults to: `]NULL[` | | jdbcsampler.max_retain_result_size | No | Max bytes to store from a `CLOB` or `BLOB` in the sampler. Defaults to: `65536` (bytes) | | jdbc.config.check.query | No | List of queries used to determine if the database is still responding. Defaults to: ``` select 1 from INFORMATION_SCHEMA.SYSTEM_USERS|select 1 from dual|select 1 from sysibm.sysdummy1|select 1|select 1 from rdb$database ``` | | jdbc.config.jdbc.driver.class | No | List of JDBC driver class name Defaults to: ``` com.mysql.cj.jdbc.Driver|com.mysql.jdbc.Driver|org.postgresql.Driver|oracle.jdbc.OracleDriver|com.ingres.jdbc.IngresDriver|com.microsoft.sqlserver.jdbc.SQLServerDriver|com.microsoft.jdbc.sqlserver.SQLServerDriver|org.apache.derby.jdbc.ClientDriver|org.hsqldb.jdbc.JDBCDriver|com.ibm.db2.jcc.DB2Driver|org.apache.derby.jdbc.ClientDriver|org.h2.Driver|org.firebirdsql.jdbc.FBDriver|org.mariadb.jdbc.Driver|org.sqlite.JDBC|net.sourceforge.jtds.jdbc.Driver|com.exasol.jdbc.EXADriver ``` | ## 19.24 OS Process Sampler configuration ## 19.25 TCP Sampler configuration | Name | Required | Description | |------|----------|-------------| | tcp.handler | No | The default handler class. Defaults to: `TCPClientImpl` | | tcp.eolByte | No | Set this to a value outside the range `-128` to `+127` to skip `eol` checking. Defaults to byte value for end of line: `1000` | | tcp.charset | No | TCP Charset, used by `org.apache.jmeter.protocol.tcp.sampler.TCPClientImpl`. Defaults to platforms default charset as returned by `Charset.defaultCharset().name()` | | tcp.status.prefix | No | String at the beginning of the status response code. Defaults to: `Status` | | tcp.status.suffix | No | String at the end of the status response code. defaults to: `.` | | tcp.status.properties | No | Property file to convert codes to messages. Defaults to: `mytestfiles/tcpstatus.properties` | | tcp.binarylength.prefix.length | No | The length prefix used by `LengthPrefixedBinaryTCPClientImpl` implementation (in bytes). Defaults to: `2` | ## 19.26 Summariser - Generate Summary Results - configuration (mainly applies to CLI mode) | Name | Required | Description | |------|----------|-------------| | summariser.name | No | Comment the following property to disable the default CLI mode summariser. [or change the value to rename it] :::note Applies to CLI mode only ::: Defaults to: `summary` | | summariser.interval | No | Interval between summaries (in seconds). Defaults to: `30` | | summariser.log | No | Write messages to log file. Defaults to: `true` | | summariser.out | No | Write messages to `System.out`. Defaults to: `true` | | summariser.ignore_transaction_controller_sample_result | No | Ignore SampleResults generated by TransactionControllers. Defaults to: `true` | ## 19.27 Aggregate Report and Aggregate Graph - configuration | Name | Required | Description | |------|----------|-------------| | aggregate_rpt_pct1 | No | Percentiles to display in reports. Given as a float value between `0` and `100` (means percent). First percentile to display. Defaults to: `90` | | aggregate_rpt_pct2 | No | Second percentile to display. Given as a float value between `0` and `100` (means percent). Defaults to: `95` | | aggregate_rpt_pct3 | No | Second percentile to display. Given as a float value between `0` and `100` (means percent). Defaults to: `99` | ## 19.28 BackendListener - configuration | Name | Required | Description | |------|----------|-------------| | backend_graphite.send_interval | No | Send interval in seconds. Defaults to: `1` second | | backend_influxdb.send_interval | No | Send interval in seconds. Defaults to: `5` seconds | | backend_influxdb.connection_timeout | No | InfluxDB connection timeout. Defaults to: `1000` millis | | backend_influxdb.socket_timeout | No | InfluxDB socket read timeout. Defaults to: `3000` millis | | backend_influxdb.connection_request_timeout | No | InfluxDB timeout to get a connection. Defaults to: `100` millis | | backend_metrics_window | No | Backend metrics sliding window size for `Percentiles`, `Min` and `Max`. Defaults to: `100` | | backend_metrics_large_window | No | Backend metrics sliding window size for `Percentiles`, `Min` and `Max`. when `backend_metrics_window_mode=timed` Setting this value too high can lead to OOM Backend metrics sliding window size Defaults to: `5000` | | backend_metrics_percentile_estimator | No | Specify the [Percentile Estimation Type](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/stat/descriptive/rank/Percentile.EstimationType.html) to use. To make the values from the dashboard compatible with the Aggregate Report, use the value `R_3`. Defaults to: `LEGACY` | | backend_metrics_window_mode | No | Backend metrics window mode. Possible values: - `fixed` : fixed-size window - `timed` : time boxed Defaults to: `fixed` | ## 19.29 BeanShell configuration | Name | Required | Description | |------|----------|-------------| | beanshell.server.port | No | BeanShell Server properties. Define the port number as non-zero to start the http server on that port. The telnet server will be started on the next port. Defaults to: `0` (i.e. don't start the server) :::note There is no security. Anyone who can connect to the port can issue any BeanShell commands. These can provide unrestricted access to the JMeter application and the host. **Do not enable the server unless the ports are protected against access, e.g. by a firewall.** ::: | | beanshell.server.file | No | Define the server initialisation file. Defaults to: `../extras/startup.bsh` | | beanshell.init.file | No | Define a file to be processed at startup. This is processed using its own interpreter. Defaults to empty value. | | beanshell.sampler.init | No | Define the initialisation files for BeanShell Sampler, Function and other BeanShell elements. :::note N.B. Beanshell test elements do not share interpreters. Each element in each thread has its own interpreter. This is retained between samples. ::: Defaults to empty value. | | beanshell.function.init | No | Defaults to empty value. | | beanshell.assertion.init | No | Defaults to empty value. | | beanshell.listener.init | No | Defaults to empty value. | | beanshell.postprocessor.init | No | Defaults to empty value. | | beanshell.preprocessor.init | No | Defaults to empty value. | | beanshell.timer.init | No | Defaults to empty value. | The file `BeanShellListeners.bshrc` contains sample definitions of Test and Thread Listeners. ## 19.30 MailerModel configuration | Name | Required | Description | |------|----------|-------------| | mailer.successlimit | No | Number of successful samples before a message is sent. Defaults to: `2` | | mailer.failurelimit | No | Number of failed samples before a message is sent. Defaults to: `2` | ## 19.31 CSVRead configuration | Name | Required | Description | |------|----------|-------------| | csvread.delimiter | No | CSVRead delimiter setting (default "`,`"). :::note Make sure that there are no trailing spaces or tabs after the delimiter characters, or these will be included in the list of valid delimiters. ::: Defaults to: `,` | ## 19.32 __time() function configuration | Name | Required | Description | |------|----------|-------------| | time.YMD | No | This and the following properties can be used to redefine the default time formats. Defaults to: `yyyyMMdd` | | time.HMS | No | Defaults to: `HHmmss` | | time.YMDHMS | No | Defaults to: `yyyyMMdd-HHmmss` | | time.USER1 | No | Defaults to empty value | | time.USER2 | No | Defaults to empty value | ## 19.33 CSV DataSet configuration | Name | Required | Description | |------|----------|-------------| | csvdataset.eofstring | No | String to return at `EOF` (if recycle not used). Defaults to: `<EOF>` | | csvdataset.file.encoding_list | No | List of file encoding values Defaults to: `platform default` | ## 19.34 LDAP Sampler configuration | Name | Required | Description | |------|----------|-------------| | ldapsampler.max_sorted_results | No | Maximum number of search results returned by a search that will be sorted to guarantee a stable ordering (if more results then this limit are returned then no sorting is done). Set to zero to turn off all sorting, in which case "Equals" response assertions will be very likely to fail against search results. Defaults to: `1000` | | assertion.equals_section_diff_len | No | Number of characters to log for each of three sections (starting matching section, diff section, ending matching section where not all sections will appear for all diffs) diff display when an Equals assertion fails. So a value of `100` means a maximum of `300` characters of diff text will be displayed (plus a number of extra characters like "`...`" and "`[[[`"/"`]]]`" which are used to decorate it). Defaults to: `100` | | assertion.equals_diff_delta_start | No | Test written out to log to signify start/end of diff delta. Defaults to: `[[[` | | assertion.equals_diff_delta_end | No | Defaults to: `]]]` | ## 19.35 Miscellaneous configuration | Name | Required | Description | |------|----------|-------------| | cssselector.parser.cache.size | No | Size of cache used by `CSS Selector Extractor` (for JODD implementation only) to store parsed CSS Selector expressions. Defaults to: `400` | | resultcollector.action_if_file_exists | No | Used to control what happens when you start a test and have listeners that could overwrite existing result files. Possible values: - `ASK` : Ask user - `APPEND` : Append results to existing file - `DELETE` : Delete existing file and start a new file | | mirror.server.port | No | If defined and greater then zero, then start the mirror server on the port. Defaults to: `0` | | oro.patterncache.size | No | ORO PatternCacheLRU size. Defaults to: `1000` | | function.cache.per.iteration | No | Cache function execution during test execution. By default, JMeter caches function properties during a test iteration, however, it might cause unexpected results when a component is shared across threads and the expression depends on the thread variables. :::note The property will likely be removed in an upcoming version, so if you need it consider raising an issue with your use-case. ::: Defaults to: `false` | | propertyEditorSearchPath | No | TestBeanGui Defaults to: `null` | | jmeter.expertMode | No | Turn expert mode on/off: expert mode will show expert-mode beans and properties. Defaults to: `true` | | httpsampler.max_bytes_to_store_per_request | No | Max size of bytes stored in memory per `SampleResult`. Ensure that you don't exceed the maximum capacity of a Java Array and remember that the higher you set this value, the more memory JMeter will consume. Defaults to: `0` bytes which means no truncation will occur | | httpsampler.max_buffer_size | No | Max size of buffer in bytes used when reading responses. Defaults to: `66560` bytes | | httpsampler.max_redirects | No | Maximum redirects to follow in a single sequence. Defaults to: `20` | | httpsampler.max_frame_depth | No | Maximum frame/iframe nesting depth. defaults to: `5` | | httpsampler.separate.container | No | Revert to [Bug 51939](https://bz.apache.org/bugzilla/show_bug.cgi?id=51939) behaviour (no separate container for embedded resources) by setting the following `false`. defaults to: `true` | | httpsampler.ignore_failed_embedded_resources | No | If embedded resources download fails due to missing resources or other reasons, if this property is `true`, Parent sample will not be marked as failed. Defaults to: `false` | | httpsampler.parallel_download_thread_keepalive_inseconds | No | Keep-alive time for the parallel download threads (in seconds). Defaults to: `60` | | httpsampler.embedded_resources_use_md5 | No | Don't keep the embedded resources response data; just keep the size and the MD5 sum. Defaults to: `false` | | httpsampler.user_defined_methods | No | List of extra HTTP methods that should be available in select box. Defaults to: ``` VERSION-CONTROL,REPORT,CHECKOUT,CHECKIN,UNCHECKOUT,MKWORKSPACE,UPDATE,LABEL,MERGE,BASELINE-CONTROL,MKACTIVITY ``` | | sampleresult.default.encoding | No | The encoding to be used if none is provided. Defaults to: `UTF-8` (since 5.6.1) | | CookieManager.delete_null_cookies | No | CookieManager behaviour - should cookies with null/empty values be deleted? Use `false` to revert to original behaviour. Defaults to: `true` | | CookieManager.allow_variable_cookies | No | CookieManager behaviour - should variable cookies be allowed? Use `false` to revert to original behaviour. Defaults to: `true` | | CookieManager.save.cookies | No | CookieManager behaviour - should Cookies be stored as variables? Default to: `false` | | CookieManager.name.prefix | No | CookieManager behaviour - prefix to add to cookie name before storing it as a variable. Default is COOKIE_; to remove the prefix, define it as one or more spaces. Defaults to: `COOKIE_` | | CookieManager.check.cookies | No | CookieManager behaviour - check received cookies are valid before storing them? Use `false` to revert to previous behaviour. Defaults to: `true` | | cookies | No | Netscape HTTP Cookie file. Defaults to: `cookies` | | javascript.use_rhino | No | Ability to switch to Rhino as default Javascript Engine used by `IfController` and `[__javaScript](/user-manual/functions/#__javaScript)` function. :::note JMeter uses Nashorn since 3.2 version. If you want to use Rhino, set this value to `true` ::: Defaults to: `false` | | jmeter.regex.engine | No | Ability to switch out the old Oro Regex implementation with the JDK built-in implementation. Any value different to `oro` will disable the Oro implementation and enable the JDK based. :::note We intend to switch the default to the JDK based one in a later version of JMeter. ::: Defaults to: `oro` | | jmeter.regex.patterncache.size | No | We assist the JDK based Regex implementation by caching Pattern objects. The size of the cache can be set with this setting. It can be disabled by setting it to `0`. Defaults to: `1000` | | jmeterengine.threadstop.wait | No | Number of milliseconds to wait for a thread to stop. Defaults to: `5000` | | jmeterengine.remote.system.exit | No | Whether to invoke `System.exit(0)` in server exit code after stopping RMI. Defaults to: `false` | | jmeterengine.stopfail.system.exit | No | Whether to call `System.exit(1)` on failure to stop threads in CLI mode. This only takes effect if the test was explicitly requested to stop. If this is disabled, it may be necessary to kill the JVM externally. Defaults to: `true` | | jmeterengine.force.system.exit | No | Whether to force call `System.exit(0)` at end of test in CLI mode, even if there were no failures and the test was not explicitly asked to stop. Without this, the JVM may never exit if there are other threads spawned by the test which never exit. Defaults to: `false` | | jmeter.exit.check.pause | No | How long to pause (in ms) in the daemon thread before reporting that the JVM has failed to exit. If the value is less than zero, the JMeter does not start the daemon thread Defaults to: `2000` | | jmeterengine.nongui.port | No | If running CLI mode, then JMeter listens on the following port for a shutdown message. To disable, set the port to `1000` or less. Defaults to: `4445` | | jmeterengine.nongui.maxport | No | If the initial port is busy, keep trying until this port is reached (to disable searching, set the value less than or equal to the `.port` property). Defaults to: `4455` | | jmeterthread.rampup.granularity | No | How often to check for shutdown during ramp-up (milliseconds). Defaults to: `1000` | | onload.expandtree | No | Should JMeter expand the tree when loading a test plan? Default value is `false` since JMeter 2.7 Defaults to: `false` | | jsyntaxtextarea.wrapstyleword | No | JSyntaxTextArea configuration. Defaults to: `true` | | jsyntaxtextarea.linewrap | No | Defaults to: `true` | | jsyntaxtextarea.codefolding | No | Defaults to: `true` | | jsyntaxtextarea.maxundos | No | Set to zero to disable undo feature in JSyntaxTextArea. Defaults to: `50` | | jsyntaxtextarea.font.family | No | Change the font on the (JSyntax) Text Areas. (Useful for HiDPI screens). Defaults to empty value, which means platform default monospaced font | | jsyntaxtextarea.font.size | No | Change the size of the (JSyntax) Text Areas. Will be used only, when `jsyntaxtextarea.font.family` is set. Defaults to: `-1` | | loggerpanel.usejsyntaxtext | No | Set this to `false` to disable the use of JSyntaxTextArea for the Console Logger panel. Defaults to: `true` | | view.results.tree.max_results | No | Maximum number of main samples, that should be stored and displayed. A value of `0` will store all results. This might consume a lot of memory. Defaults to: `500` | | view.results.tree.max_size | No | Maximum size (in bytes) of HTML page that can be displayed. Set to zero to disable the size check and display the whole response. Defaults to: `10485760` | | view.results.tree.max_line_size | No | Maximum size (in characters) of the line in the displayed. This property works around Bug 63620 since Swing hangs when displaying very long lines. Set to zero to disable line wrapping. Defaults to: `110000` | | view.results.tree.soft_wrap_line_size | No | Line size (in characters) to consider wrapping to make UI faster. This property works around Bug 63620 since Swing hangs when displaying very long lines. Set to zero to disable line wrapping. Defaults to: `view.results.tree.max_line_size / 1.1f` | | view.results.tree.renderers_order | No | Order of Renderers in View Results Tree. :::note Note full class names should be used for non JMeter core renderers ::: For JMeter core renderers, class names start with `.` and are automatically prefixed with `org.apache.jmeter.visualizers` Defaults to: ``` .RenderAsText,.RenderAsRegexp,.RenderAsCssJQuery,.RenderAsXPath,.RenderAsHTML,.RenderAsHTMLWithEmbedded,.RenderAsDocument,.RenderAsJSON,.RenderAsXML ``` | | view.results.tree.simple_view_limit | No | Configures maximum document length for text view before switching to a simpler view, that does not do line breaks. Works probably best, when combined with a low setting of `view.results.tree.max_line_size`. Can be switched off by setting the value to `-1`. Defaults to: `10000` | | document.max_size | No | Maximum size (in bytes) of Document that can be parsed by Tika engine Set to zero to disable the size check. Defaults to: `10485760` | | text.kerning.max_document_size | No | Configures the maximum document length for rendering with kerning enabled. Defaults to: `10000` | | JMSSampler.useSecurity.properties | No | JMS options. Enable the following property to stop JMS Point-to-Point Sampler from using the properties `java.naming.security.[principal|credentials]` when creating the queue connection. Defaults to: `false` | | confirm.delete.skip | No | Set the following value to `true` in order to skip the delete confirmation dialogue. Defaults to: `false` | ## 19.36 Classpath configuration | Name | Required | Description | |------|----------|-------------| | search_paths | No | List of directories (separated by `;`) to search for additional JMeter plugin classes, for example new GUI elements and samplers. Any jar file in such a directory will be automatically included; jar files in sub directories are ignored. The given value is in addition to any jars found in the `lib/ext` directory. Do not use this for utility or plugin dependency jars. Defaults to empty value. | | user.classpath | No | List of directories that JMeter will search for utility and plugin dependency classes. Use your platform path separator (`java.io.File.pathSeparatorChar` in Java) to separate multiple paths. Any jar file in such a directory will be automatically included; jar files in sub directories are ignored. The given value is in addition to any jars found in the `lib` directory. All entries will be added to the class path of the system class loader and also to the path of the JMeter internal loader. Paths with spaces may cause problems for the JVM. Defaults to empty value. | | plugin_dependency_paths | No | List of directories (separated by `;`) that JMeter will search for utility and plugin dependency classes. Any jar file in such a directory will be automatically included; jar files in sub directories are ignored. The given value is in addition to any jars found in the `lib` directory or given by the `user.classpath` property. All entries will be added to the path of the JMeter internal loader only. For plugin dependencies this property should be used instead of `user.classpath`. Defaults to empty value. | | classfinder.functions.contain | No | The classpath finder currently needs to load every single JMeter class to find the classes it needs. For CLI mode, it's only necessary to scan for Function classes, but all classes are still loaded. All current Function classes include "`.function.`" in their name, and none include "`.gui.`" in the name, so the number of unwanted classes loaded can be reduced by checking for these. However, if a valid function class name does not match these restrictions, it will not be loaded. If problems are encountered, then comment or change this or the following property. Defaults to: `.functions.` | | classfinder.functions.notContain | No | Defaults to: `.gui.` | ## 19.37 Reporting configuration | Name | Required | Description | |------|----------|-------------| | jmeter.reportgenerator.apdex_satisfied_threshold | No | Sets the satisfaction threshold for the APDEX calculation (in milliseconds). Defaults to: `500` | | jmeter.reportgenerator.apdex_tolerated_threshold | No | Sets the tolerance threshold for the APDEX calculation (in milliseconds). Defaults to: `1500` | | jmeter.reportgenerator.sample_filter | No | Regular Expression which Indicates which samples to keep for graphs and statistics generation. Empty value means no filtering Defaults to empty value. | | jmeter.reportgenerator.temp_dir | No | Sets the temporary directory used by the generation process if it needs file I/O operations. Defaults to: `temp` | | jmeter.reportgenerator.statistic_window | No | Sets the size of the sliding window used by percentile evaluation. :::note Caution: higher value provides a better accuracy but needs more memory. ::: Defaults to: `20000` | | jmeter.reportgenerator.report_title | No | Configure this property to change the report title Defaults to: `Apache JMeter Dashboard` | | jmeter.reportgenerator.overall_granularity | No | Defines the overall granularity for over time graphs Defaults to: `60000` | | jmeter.reportgenerator.graph.responseTimePercentiles.classname | No | Response Time Percentiles graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.ResponseTimePercentilesGraphConsumer ``` | | jmeter.reportgenerator.graph.responseTimePercentiles.title | No | Defaults to: `Response Time Percentiles` | | jmeter.reportgenerator.graph.responseTimeDistribution.classname | No | Response Time Distribution graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.ResponseTimeDistributionGraphConsumer ``` | | jmeter.reportgenerator.graph.responseTimeDistribution.title | No | Defaults to: `Response Time Distribution` | | jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity | No | Defaults to: `100` | | jmeter.reportgenerator.graph.activeThreadsOverTime.classname | No | Active Threads Over Time graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.ActiveThreadsGraphConsumer ``` | | jmeter.reportgenerator.graph.activeThreadsOverTime.title | No | Defaults to: `Active Threads Over Time` | | jmeter.reportgenerator.graph.activeThreadsOverTime.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.timeVsThreads.classname | No | Time VS Threads graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.TimeVSThreadGraphConsumer ``` | | jmeter.reportgenerator.graph.timeVsThreads.title | No | Defaults to: `Time VS Threads` | | jmeter.reportgenerator.graph.bytesThroughputOverTime.classname | No | Bytes Throughput Over Time graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.BytesThroughputGraphConsumer ``` | | jmeter.reportgenerator.graph.bytesThroughputOverTime.title | No | Defaults to: `Bytes Throughput Over Time` | | jmeter.reportgenerator.graph.bytesThroughputOverTime.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.responseTimesOverTime.classname | No | Response Time Over Time graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.ResponseTimeOverTimeGraphConsumer ``` | | jmeter.reportgenerator.graph.responseTimesOverTime.title | No | Defaults to: `Response Time Over Time` | | jmeter.reportgenerator.graph.responseTimesOverTime.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.latenciesOverTime.classname | No | Latencies Over Time graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.LatencyOverTimeGraphConsumer ``` | | jmeter.reportgenerator.graph.latenciesOverTime.title | No | Defaults to: `Latencies Over Time` | | jmeter.reportgenerator.graph.latenciesOverTime.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.responseTimeVsRequest.classname | No | Response Time Vs Request graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.ResponseTimeVSRequestGraphConsumer ``` | | jmeter.reportgenerator.graph.responseTimeVsRequest.title | No | Defaults to: `Response Time Vs Request` | | jmeter.reportgenerator.graph.responseTimeVsRequest.exclude_controllers | No | Defaults to: `true` | | jmeter.reportgenerator.graph.responseTimeVsRequest.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.latencyVsRequest.classname | No | Latencies Vs Request graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.LatencyVSRequestGraphConsumer ``` | | jmeter.reportgenerator.graph.latencyVsRequest.title | No | Defaults to: `Latencies Vs Request` | | jmeter.reportgenerator.graph.latencyVsRequest.exclude_controllers | No | Defaults to: `true` | | jmeter.reportgenerator.graph.latencyVsRequest.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.hitsPerSecond.classname | No | Hits Per Second graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.HitsPerSecondGraphConsumer ``` | | jmeter.reportgenerator.graph.hitsPerSecond.title | No | Defaults to: `Hits Per Second` | | jmeter.reportgenerator.graph.hitsPerSecond.exclude_controllers | No | Defaults to: `true` | | jmeter.reportgenerator.graph.hitsPerSecond.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.codesPerSecond.classname | No | Codes Per Second graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.CodesPerSecondGraphConsumer ``` | | jmeter.reportgenerator.graph.codesPerSecond.title | No | Defaults to: `Codes Per Second` | | jmeter.reportgenerator.graph.codesPerSecond.exclude_controllers | No | Defaults to: `true` | | jmeter.reportgenerator.graph.codesPerSecond.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.graph.transactionsPerSecond.classname | No | Transactions Per Second graph definition Defaults to: ``` org.apache.jmeter.report.processor.graph.impl.TransactionsPerSecondGraphConsumer ``` | | jmeter.reportgenerator.graph.transactionsPerSecond.title | No | Defaults to: `Transactions Per Second` | | jmeter.reportgenerator.graph.transactionsPerSecond.property.set_granularity | No | Defaults to: `\${jmeter.reportgenerator.overall_granularity}` | | jmeter.reportgenerator.exporter.html.classname | No | HTML Export Defaults to: ``` org.apache.jmeter.report.dashboard.HtmlTemplateExporter ``` | | jmeter.reportgenerator.exporter.html.property.template_dir | No | Sets the source directory of templated files from which the html pages are generated. Defaults to: `report-template` | | jmeter.reportgenerator.exporter.html.property.output_dir | No | Sets the destination directory for generated html pages. This will be overridden by the command line option `-o`. Defaults to: `report-output` | | jmeter.reportgenerator.exporter.html.series_filter | No | Regular Expression which Indicates which graph series are filtered in display. Empty value means no filtering. Defaults to empty value. | | jmeter.reportgenerator.exporter.html.filters_only_sample_series | No | Indicates whether series filter apply only on sample series Defaults to: `true` | | jmeter.reportgenerator.exporter.html.show_controllers_only | No | Indicates whether only controller samples are displayed on graphs that support it. Defaults to: `false` | | jmeter.reportgenerator.date_format | No | Date format of report using by start_date and end_date properties. Defaults to: `yyyyMMddHHmmss` | | jmeter.reportgenerator.start_date | No | Start date of report using date_format property. Defaults to: nothing | | jmeter.reportgenerator.end_date | No | End date of report using date_format property. Defaults to: nothing | | generate_report_ui.generation_timeout | No | Timeout in milliseconds for Report generation when using Tools > Generate HTML report. Defaults to: 300000 | ## 19.38 Additional property files to load | Name | Required | Description | |------|----------|-------------| | user.properties | No | Should JMeter automatically load additional JMeter properties? File name to look for (comment to disable) Defaults to: `user.properties` | | system.properties | No | Should JMeter automatically load additional system properties? File name to look for (comment to disable) Defaults to: `system.properties` | | template.files | No | Comma separated list of files that contain reference to templates and their description. Path must be relative to JMeter root folder Defaults to: `/bin/templates/templates.xml` | ## 19.39 Thread Group Validation feature Validation is the name of the feature used to rapidly validate a Thread Group runs fine | Name | Required | Description | |------|----------|-------------| | testplan_validation.tree_cloner_class | No | Default implementation is ``` org.apache.jmeter.gui.action.validation.TreeClonerForValidation ``` It runs validation without timers, with one thread and one iteration. You can implement your own policy that must extend `org.apache.jmeter.engine.TreeCloner`. JMeter will instantiate it and use it to create the Tree used to run validation on Thread Group. Defaults to: ``` org.apache.jmeter.gui.action.validation.TreeClonerForValidation ``` | | testplan_validation.nb_threads_per_thread_group | No | Number of threads to use to validate a Thread Group. Defaults to: `1` | | testplan_validation.ignore_timers | No | Ignore timers when validating the thread group of plan. Defaults to: `true` | | testplan_validation.ignore_backends | No | Ignore BackendListener when validating the thread group of plan. Defaults to: `true` | | testplan_validation.number_iterations | No | Number of iterations to use to validate a Thread Group. Defaults to: `1` | | testplan_validation.tpc_force_100_pct | No | Force throughput controllers that work in percentage mode to be a 100%. Defaults to: `false` | ## 19.40 Timer related feature Timer are used to introduce think time in your plan. | Name | Required | Description | |------|----------|-------------| | timer.factor | No | Apply a factor on computed pauses by the following Timers: - Gaussian Random Timer - Uniform Random Timer - Poisson Random Timer Defaults to: `1.0f` | | think_time_creator.impl | No | Default implementation that create the Timer structure to add to Test Plan. Implementation of interface [`org.apache.jmeter.gui.action.thinktime.ThinkTimeCreator`](https://jmeter.apache.org/api/org/apache/jmeter/gui/action/thinktime/ThinkTimeCreator.html) Defaults to: [`org.apache.jmeter.thinktime.DefaultThinkTimeCreator`](https://jmeter.apache.org/api/org/apache/jmeter/thinktime/DefaultThinkTimeCreator.html) | | think_time_creator.default_timer_implementation | No | Default Timer GUI class added to Test Plan by DefaultThinkTimeCreator Defaults to: [`org.apache.jmeter.timers.gui.UniformRandomTimerGui`](https://jmeter.apache.org/api/org/apache/jmeter/timers/gui/UniformRandomTimerGui.html) | | think_time_creator.default_constant_pause | No | Default constant pause of Timer Defaults to: `1000` | | think_time_creator.default_range | No | Default range pause of Timer Defaults to: `100` | [^](#) ## 19.41 Naming Policy Timer are used to introduce think time in your plan. | Name | Required | Description | |------|----------|-------------| | naming_policy.prefix | No | Prefix used when naming elements. Defaults to empty prefix | | naming_policy.suffix | No | Prefix used when naming elements. Defaults to empty suffix | | naming_policy.impl | No | Implementation of interface [`org.apache.jmeter.gui.action.TreeNodeNamingPolicy`](https://jmeter.apache.org/api/org/apache/jmeter/gui/action/TreeNodeNamingPolicy.html) Default implementation that create the Timer structure to add to Test Plan. Implementation of interface org.apache.jmeter.gui.action.thinktime.ThinkTimeCreator Defaults to: [`org.apache.jmeter.gui.action.impl.DefaultTreeNodeNamingPolicy`](https://jmeter.apache.org/api/org/apache/jmeter/gui/action/impl/DefaultTreeNodeNamingPolicy.html) | [^](#) ## 19.42 Help Controls how documentation in JMeter is displayed | Name | Required | Description | |------|----------|-------------| | help.local | No | Switch that allows using Local documentation opened in JMeter GUI. By default we use Online documentation opened in Browser. Defaults to `false` | ## 19.43 Advanced Groovy Scripting configuration Advanced properties for configuration of scripting in Groovy | Name | Required | Description | |------|----------|-------------| | groovy.utilities | No | Path to Groovy file containing utility functions to make available to `[__groovy](/user-manual/functions/#__groovy)` function. Defaults to `bin/utility.groovy` | ## 19.44 Advanced JSR-223 Scripting configuration Advanced properties for configuration of scripting in JSR-223 | Name | Required | Description | |------|----------|-------------| | jsr223.init.file | No | Path to JSR-223 file containing script to call on JMeter startup. The actual scripting engine to use will be determined by the extension of the init file name. If the file name has no extension, or no scripting engine could be found for that extension, Groovy will be used. This script can use pre-defined variables: - `log`: Logger to log any message, uses SLF4J library - `props`: JMeter Properties - `OUT`: System.OUT, useful to write in the console No script is defined by default. | | jsr223.compiled_scripts_cache_size | No | Used by JSR-223 elements. Size of compiled scripts cache. Defaults to: `100` | ## 19.45 Documentation generation Advanced properties for documentation generation | Name | Required | Description | |------|----------|-------------| | docgeneration.schematic_xsl | No | Path to XSL file used to generate Schematic View of Test Plan. When empty, JMeter will use the embedded one in src/core/org/apache/jmeter/gui/action/schematic.xsl No default value | ## 19.46 Security Provider Advanced properties for documentation generation | Name | Required | Description | |------|----------|-------------| | security.provider | No | The value must be in this format: <ClassName>[:<Postion>[:<ConfigString>]] | | security.provider.<n> | No | Replace the `<n>` with any number. The SecurityProviders will be added in the alphabetical order of the property names. (First: `security.provider` and then `security.provider.2`, `security.provider.3`,...) See property `security.provider` | {/* SYNCED-BODY:END */} --- Title: User's Manual: Component Reference URL: https://docs.jmeter.ai/user-manual/component-reference/ --- import RelatedContent from '../../../components/RelatedContent.astro'; {/* SYNCED-BODY:START */} ## 18 Introduction {/* CUSTOM-INTRO:START */} :::note[Version-specific behavior] Component fields, defaults, and save formats can change across JMeter versions. Verify component behavior against the version used by your test runners. ::: {/* CUSTOM-INTRO:END */} :::note Several test elements use JMeter properties to control their behaviour. These properties are normally resolved when the class is loaded. This generally occurs before the test plan starts, so it's not possible to change the settings by using the `[__setProperty()](/user-manual/functions/#__setProperty__)` function. ::: ## 18.1 Samplers Samplers perform the actual work of JMeter. Each sampler (except [Flow Control Action](/user-manual/component-reference/#Flow_Control_Action)) generates one or more sample results. The sample results have various attributes (success/fail, elapsed time, data size etc.) and can be viewed in the various listeners. ## FTP Request ![FTP Request](/images/screenshots/ftptest/ftp-request.png) This controller lets you send an FTP "retrieve file" or "upload file" request to an FTP server. If you are going to send multiple requests to the same FTP server, consider using a [FTP Request Defaults](/user-manual/component-reference/#FTP_Request_Defaults) Configuration Element so you do not have to enter the same information for each FTP Request Generative Controller. When downloading a file, it can be stored on disk (Local File) or in the Response Data, or both. Latency is set to the time it takes to login. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Server Name or IP | Yes | Domain name or IP address of the FTP server. | | Port | No | Port to use. If this is `>0`, then this specific port is used, otherwise JMeter uses the default FTP port. | | Remote File: | Yes | File to retrieve or name of destination file to upload. | | Local File: | Yes, if uploading (*) | File to upload, or destination for downloads (defaults to remote file name). | | Local File Contents: | Yes, if uploading (*) | Provides the contents for the upload, overrides the Local File property. | | get(RETR) / put(STOR) | Yes | Whether to retrieve or upload a file. | | Use Binary mode | Yes | Check this to use Binary mode (default ASCII) | | Save File in Response | Yes, if downloading | Whether to store contents of retrieved file in response data. If the mode is ASCII, then the contents will be visible in the [View Results Tree](/user-manual/component-reference/#View_Results_Tree). | | Username | Usually | FTP account username. | | Password | Usually | FTP account password. N.B. This will be visible in the test plan. | ## HTTP Request ![HTTP Request](/images/screenshots/http-request.png) This sampler lets you send an HTTP/HTTPS request to a web server. It also lets you control whether or not JMeter parses HTML files for images and other embedded resources and sends HTTP requests to retrieve them. The following types of embedded resource are retrieved: - images - applets - stylesheets (CSS) and resources referenced from those files - external scripts - frames, iframes - background images (body, table, TD, TR) - background sound The default parser is `org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser`. This can be changed by using the property "`htmlparser.className`" - see `jmeter.properties` for details. If you are going to send multiple requests to the same web server, consider using an [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) Configuration Element so you do not have to enter the same information for each HTTP Request. Or, instead of manually adding HTTP Requests, you may want to use JMeter's [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder) to create them. This can save you time if you have a lot of HTTP requests or requests with many parameters. **There are three different test elements used to define the samplers:** **AJP/1.3 Sampler** : uses the Tomcat mod_jk protocol (allows testing of Tomcat in AJP mode without needing Apache httpd) The AJP Sampler does not support multiple file upload; only the first file will be used. **HTTP Request** : this has an implementation drop-down box, which selects the HTTP protocol implementation to be used: **`Java`** : uses the HTTP implementation provided by the JVM. This has some limitations in comparison with the HttpClient implementations - see below. **`HTTPClient4`** : uses Apache HttpComponents HttpClient 4.x. **Blank Value** : does not set implementation on HTTP Samplers, so relies on HTTP Request Defaults if present or on `jmeter.httpsampler` property defined in `jmeter.properties` **GraphQL HTTP Request** : this is a GUI variation of the **HTTP Request** to provide more convenient UI elements to view or edit GraphQL **Query**, **Variables** and **Operation Name**, while converting them into HTTP Arguments automatically under the hood using the same sampler. This hides or customizes the following UI elements as they are less convenient for or irrelevant to GraphQL over HTTP/HTTPS requests: - **Method**: Only POST and GET methods are available conforming the GraphQL over HTTP specification. POST method is selected by default. - **Parameters** and **Post Body** tabs: you may view or edit parameter content through Query, Variables and Operation Name UI elements instead. - **File Upload** tab: irrelevant to GraphQL queries. - **Embedded Resources from HTML Files** section in the Advanced tab: irrelevant in GraphQL JSON responses. The Java HTTP implementation has some limitations: - There is no control over how connections are re-used. When a connection is released by JMeter, it may or may not be re-used by the same thread. - The API is best suited to single-threaded usage - various settings are defined via system properties, and therefore apply to all connections. - No support of Kerberos authentication - It does not support client based certificate testing with Keystore Config. - Better control of Retry mechanism - It does not support virtual hosts. - It supports only the following methods: `GET`, `POST`, `HEAD`, `OPTIONS`, `PUT`, `DELETE` and `TRACE` - Better control on DNS Caching with [DNS Cache Manager](/user-manual/component-reference/#DNS_Cache_Manager) :::note Note: the `FILE` protocol is intended for testing purposes only. It is handled by the same code regardless of which HTTP Sampler is used. ::: If the request requires server or proxy login authorization (i.e. where a browser would create a pop-up dialog box), you will also have to add an [HTTP Authorization Manager](/user-manual/component-reference/#HTTP_Authorization_Manager) Configuration Element. For normal logins (i.e. where the user enters login information in a form), you will need to work out what the form submit button does, and create an HTTP request with the appropriate method (usually `POST`) and the appropriate parameters from the form definition. If the page uses HTTP, you can use the JMeter Proxy to capture the login sequence. A separate SSL context is used for each thread. If you want to use a single SSL context (not the standard behaviour of browsers), set the JMeter property: ``` https.sessioncontext.shared=true ``` By default, since version 5.0, the SSL context is retained during a Thread Group iteration and reset for each test iteration. If in your test plan the same user iterates multiple times, then you should set this to false. ``` httpclient.reset_state_on_thread_group_iteration=true ``` :::note Note: this does not apply to the Java HTTP implementation. ::: JMeter defaults to the SSL protocol level TLS. If the server needs a different level, e.g. `SSLv3`, change the JMeter property, for example: ``` https.default.protocol=SSLv3 ``` JMeter also allows one to enable additional protocols, by changing the property `https.socket.protocols`. If the request uses cookies, then you will also need an [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager). You can add either of these elements to the Thread Group or the HTTP Request. If you have more than one HTTP Request that needs authorizations or cookies, then add the elements to the Thread Group. That way, all HTTP Request controllers will share the same Authorization Manager and Cookie Manager elements. If the request uses a technique called "URL Rewriting" to maintain sessions, then see section [6.1 Handling User Sessions With URL Rewriting](/user-manual/build-adv-web-test-plan/#session_url_rewriting) for additional configuration steps. ![HTTP Request Advanced config fields](/images/screenshots/http-request-advanced-tab.png) _HTTP Request Advanced config fields_ ![Screenshot of Control-Panel of GraphQL HTTP Request](/images/screenshots/graphql-http-request.png) _Screenshot of Control-Panel of GraphQL HTTP Request_ ![Variables field for GraphQL HTTP Request](/images/screenshots/graphql-http-request-vars.png) _Variables field for GraphQL HTTP Request_ | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Server | No | Domain name or IP address of the web server, e.g. `www.example.com`. [Do not include the `http://` prefix.] Note: If the "`Host`" header is defined in a Header Manager, then this will be used as the virtual host name. :::note Server is required, unless: - it is provided by [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) - or a full URL including scheme, host and port (`scheme://host:port`) is set in **Path** field ::: | | Port | No | Port the web server is listening to. Default: `80` | | Connect Timeout | No | Connection Timeout. Number of milliseconds to wait for a connection to open. | | Response Timeout | No | Response Timeout. Number of milliseconds to wait for a response. Note that this applies to each wait for a response. If the server response is sent in several chunks, the overall elapsed time may be longer than the timeout. A [Duration Assertion](/user-manual/component-reference/#Duration_Assertion) can be used to detect responses that take too long to complete. | | Server (proxy) | No | Hostname or IP address of a proxy server to perform request. [Do not include the `http://` prefix.] | | Port | No, unless proxy hostname is specified | Port the proxy server is listening to. | | Username | No | (Optional) username for proxy server. | | Password | No | (Optional) password for proxy server. (N.B. this is stored unencrypted in the test plan) | | Implementation | No | `Java`, `HttpClient4`. If not specified (and not defined by HTTP Request Defaults), the default depends on the value of the JMeter property `jmeter.httpsampler`, failing that, the HttpClient4 implementation is used. | | Protocol | No | `HTTP`, `HTTPS` or `FILE`. Default: `HTTP` | | Method | Yes | `GET`, `POST`, `HEAD`, `TRACE`, `OPTIONS`, `PUT`, `DELETE`, `PATCH` (not supported for `JAVA` implementation). With `HttpClient4`, the following methods related to WebDav are also allowed: `COPY`, `LOCK`, `MKCOL`, `MOVE`, `PROPFIND`, `PROPPATCH`, `UNLOCK`, `REPORT`, `MKCALENDAR`, `SEARCH`. More methods can be pre-defined for the HttpClient4 by using the JMeter property `httpsampler.user_defined_methods`. | | Content Encoding | No | Content encoding to be used (for `POST`, `PUT`, `PATCH` and `FILE`). This is the character encoding to be used, and is not related to the Content-Encoding HTTP header. | | Redirect Automatically | No | Sets the underlying http protocol handler to automatically follow redirects, so they are not seen by JMeter, and thus will not appear as samples. Should only be used for `GET` and `HEAD` requests. The HttpClient sampler will reject attempts to use it for `POST` or `PUT`. :::note Warning: see below for information on cookie and header handling. ::: | | Follow Redirects | No | This only has any effect if "`Redirect Automatically`" is not enabled. If set, the JMeter sampler will check if the response is a redirect and follow it if so. The initial redirect and further responses will appear as additional samples. The URL and data fields of the parent sample will be taken from the final (non-redirected) sample, but the parent byte count and elapsed time include all samples. The latency is taken from the initial response. Note that the HttpClient sampler may log the following message: ``` "Redirect requested but followRedirects is disabled" ``` This can be ignored. JMeter will collapse paths of the form '`/../segment`' in both absolute and relative redirect URLs. For example `http://host/one/../two` will be collapsed into `http://host/two`. If necessary, this behaviour can be suppressed by setting the JMeter property `httpsampler.redirect.removeslashdotdot=false` | | Use KeepAlive | No | JMeter sets the Connection: `keep-alive` header. This does not work properly with the default HTTP implementation, as connection re-use is not under user-control. It does work with the Apache HttpComponents HttpClient implementations. | | Use multipart/form-data for HTTP POST | No | Use a `multipart/form-data` or `application/x-www-form-urlencoded` post request | | Browser-compatible headers | No | When using `multipart/form-data`, this suppresses the `Content-Type` and `Content-Transfer-Encoding` headers; only the `Content-Disposition` header is sent. | | Path | No | The path to resource (for example, `/servlets/myServlet`). If the resource requires query string parameters, add them below in the "Send Parameters With the Request" section. :::note As a special case, if the path starts with "`http://`" or "`https://`" then this is used as the full URL. ::: In this case, the server, port and protocol fields are ignored; parameters are also ignored for `GET` and `DELETE` methods. Also please note that the path is not encoded - apart from replacing spaces with `%20` - so unsafe characters may need to be encoded to avoid errors such as `URISyntaxException`. | | Send Parameters With the Request | No | The query string will be generated from the list of parameters you provide. Each parameter has a `name` and `value`, the options to encode the parameter, and an option to include or exclude an equals sign (some applications don't expect an equals sign when the value is the empty string). The query string will be generated in the correct fashion, depending on the choice of "Method" you made (i.e. if you chose `GET` or `DELETE`, the query string will be appended to the URL, if `POST` or `PUT`, then it will be sent separately). Also, if you are sending a file using a multipart form, the query string will be created using the multipart form specifications. **See below for some further information on parameter handling.** Additionally, you can specify whether each parameter should be URL encoded. If you are not sure what this means, it is probably best to select it. If your values contain characters such as the following then encoding is usually required.: - ASCII Control Chars - Non-ASCII characters - Reserved characters:URLs use some characters for special use in defining their syntax. When these characters are not used in their special role inside a URL, they need to be encoded, example: '`$`', '`&`', '`+`', '`,`' , '`/`', '`:`', '`;`', '`=`', '`?`', '`@`' - Unsafe characters: Some characters present the possibility of being misunderstood within URLs for various reasons. These characters should also always be encoded, example: '` `', '`<`', '`>`', '`#`', '`%`', … | | File Path: | No | Name of the file to send. If left blank, JMeter does not send a file, if filled in, JMeter automatically sends the request as a multipart form request. When `MIME Type` is empty, JMeter will try to guess the MIME type of the given file. If it is a `POST` or `PUT` or `PATCH` request and there is a single file whose '`Parameter name`' attribute (below) is omitted, then the file is sent as the entire body of the request, i.e. no wrappers are added. This allows arbitrary bodies to be sent. This functionality is present for `POST` requests, and also for `PUT` requests. **See below for some further information on parameter handling.** | | Parameter name: | No | Value of the "`name`" web request parameter. | | MIME Type | No | MIME type (for example, `text/plain`). If it is a `POST` or `PUT` or `PATCH` request and either the '`name`' attribute (below) are omitted or the request body is constructed from parameter values only, then the value of this field is used as the value of the `content-type` request header. | | Retrieve All Embedded Resources from HTML Files | No | Tell JMeter to parse the HTML file and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file. See below for more details. | | Save response as MD5 hash | No | If this is selected, then the response is not stored in the sample result. Instead, the 32 character MD5 hash of the data is calculated and stored instead. This is intended for testing large amounts of data. | | URLs must match: | No | If present, this must be a regular expression that is used to match against any embedded URLs found. So if you only want to download embedded resources from `http://example.invalid/`, use the expression: `http://example\.invalid/.*` | | URLs must not match: | No | If present, this must be a regular expression that is used to filter out any embedded URLs found. So if you don't want to download PNG or SVG files from any source, use the expression: `.*\.(?i:svg|png)` | | Use concurrent pool | No | Use a pool of concurrent connections to get embedded resources. | | Size | No | Pool size for concurrent connections used to get embedded resources. | | Source address type | No | _[Only for HTTP Request with HTTPClient implementation]_ To distinguish the source address value, select the type of these: - Select _IP/Hostname_ to use a specific IP address or a (local) hostname - Select _Device_ to pick the first available address for that interface which this may be either IPv4 or IPv6 - Select _Device IPv4_ to select the IPv4 address of the device name (like `eth0`, `lo`, `em0`, etc.) - Select _Device IPv6_ to select the IPv6 address of the device name (like `eth0`, `lo`, `em0`, etc.) | | Source address field | No | _[Only for HTTP Request with HTTPClient implementation]_ This property is used to enable IP Spoofing. It overrides the default local IP address for this sample. The JMeter host must have multiple IP addresses (i.e. IP aliases, network interfaces, devices). The value can be a host name, IP address, or a network interface device such as "`eth0`" or "`lo`" or "`wlan0`". If the property `httpclient.localaddress` is defined, that is used for all HttpClient requests. | The following parameters are available only for **GraphQL HTTP Request**: | Name | Required | Description | |------|----------|-------------| | Query | Yes | GraphQL query (or mutation) statement. | | Variables | No | GraphQL query (or mutation) variables in a valid JSON string. **Note**: If the input string is not a valid JSON string, this will be ignored with an ERROR log. | | Operation Name | No | Optional GraphQL operation name when making a request for multi-operation documents. | :::note When using Automatic Redirection, cookies are only sent for the initial URL. This can cause unexpected behaviour for web-sites that redirect to a local server. E.g. if `www.example.com` redirects to `www.example.co.uk`. In this case the server will probably return cookies for both URLs, but JMeter will only see the cookies for the last host, i.e. `www.example.co.uk`. If the next request in the test plan uses `www.example.com`, rather than `www.example.co.uk`, it will not get the correct cookies. Likewise, Headers are sent for the initial request, and won't be sent for the redirect. This is generally only a problem for manually created test plans, as a test plan created using a recorder would continue from the redirected URL. ::: **Parameter Handling:** For the `POST` and `PUT` method, if there is no file to send, and the name(s) of the parameter(s) are omitted, then the body is created by concatenating all the value(s) of the parameters. Note that the values are concatenated without adding any end-of-line characters. These can be added by using the `[__char()](/user-manual/functions/#__char__)` function in the value fields. This allows arbitrary bodies to be sent. The values are encoded if the encoding flag is set. See also the MIME Type above how you can control the `content-type` request header that is sent. For other methods, if the name of the parameter is missing, then the parameter is ignored. This allows the use of optional parameters defined by variables. You have the option to switch to `Body Data` tab when a request has only unnamed parameters (or no parameters at all). This option is useful in the following cases (amongst others): - GWT RPC HTTP Request - JSON REST HTTP Request - XML REST HTTP Request - SOAP HTTP Request :::note Note that once you leave the Tree node, you cannot switch back to the parameter tab unless you clear the `Body Data` tab from its data. ::: In `Body Data` mode, each line will be sent with `CRLF` appended, apart from the last line. To send a `CRLF` after the last line of data, just ensure that there is an empty line following it. (This cannot be seen, except by noting whether the cursor can be placed on the subsequent line.) ![Figure 1 - HTTP Request with one unnamed parameter](/images/screenshots/http-request-raw-single-parameter.png) _Figure 1 - HTTP Request with one unnamed parameter_ ![Figure 2 - Confirm dialog to switch](/images/screenshots/http-request-confirm-raw-body.png) _Figure 2 - Confirm dialog to switch_ ![Figure 3 - HTTP Request using Body Data](/images/screenshots/http-request-raw-body.png) _Figure 3 - HTTP Request using Body Data_ **Method Handling:** The `GET`, `DELETE`, `POST`, `PUT` and `PATCH` request methods work similarly, except that as of 3.1, only `POST` method supports multipart requests or file upload. The `PUT` and `PATCH` method body must be provided as one of the following: - define the body as a file with empty Parameter name field; in which case the MIME Type is used as the Content-Type - define the body as parameter value(s) with no name - use the `Body Data` tab The `GET`, `DELETE` and `POST` methods have an additional way of passing parameters by using the `Parameters` tab. `GET`, `DELETE`, `PUT` and `PATCH` require a Content-Type. If not using a file, attach a Header Manager to the sampler and define the Content-Type there. JMeter scan responses from embedded resources. It uses the property `HTTPResponse.parsers`, which is a list of parser ids, e.g. `htmlParser`, `cssParser` and `wmlParser`. For each id found, JMeter checks two further properties: - `id.types` - a list of content types - `id.className` - the parser to be used to extract the embedded resources See `jmeter.properties` file for the details of the settings. If the `HTTPResponse.parser` property is not set, JMeter reverts to the previous behaviour, i.e. only `text/html` responses will be scanned **Emulating slow connections:** `HttpClient4` and `Java` Sampler support emulation of slow connections; see the following entries in `jmeter.properties`: ```properties # Define characters per second > 0 to emulate slow connections #httpclient.socket.http.cps=0 #httpclient.socket.https.cps=0 ``` However the `Java` sampler only supports slow HTTPS connections. **Response size calculation** :::note The `Java` implementation does not include transport overhead such as chunk headers in the response body size. The `HttpClient4` implementation does include the overhead in the response body size, so the value may be greater than the number of bytes in the response content. ::: **Retry handling** By default retry has been set to 0 for both HttpClient4 and Java implementations, meaning no retry is attempted. For HttpClient4, the retry count can be overridden by setting the relevant JMeter property, for example: ``` httpclient4.retrycount=3 ``` :::note With HC4 Implementation, retry will be done on Idempotent Http Methods by default. If you want to retry for all methods, then set property ``` httpclient4.request_sent_retry_enabled=true ``` ::: Note that the Java implementation does not retry neither by default, you can change this by setting ``` http.java.sampler.retries=3 ``` **Note: Certificates does not conform to algorithm constraints** You may encounter the following error: `java.security.cert.CertificateException: Certificates does not conform to algorithm constraints` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. ## JDBC Request ![JDBC Request](/images/screenshots/jdbctest/jdbc-request.png) This sampler lets you send a JDBC Request (an SQL query) to a database. Before using this you need to set up a [JDBC Connection Configuration](/user-manual/component-reference/#JDBC_Connection_Configuration) Configuration element If the Variable Names list is provided, then for each row returned by a Select statement, the variables are set up with the value of the corresponding column (if a variable name is provided), and the count of rows is also set up. For example, if the Select statement returns 2 rows of 3 columns, and the variable list is `A,,C`, then the following variables will be set up: ``` A_#=2 (number of rows) A_1=column 1, row 1 A_2=column 1, row 2 C_#=2 (number of rows) C_1=column 3, row 1 C_2=column 3, row 2 ``` If the Select statement returns zero rows, then the `A_#` and `C_#` variables would be set to `0`, and no other variables would be set. Old variables are cleared if necessary - e.g. if the first select retrieves six rows and a second select returns only three rows, the additional variables for rows four, five and six will be removed. :::note The latency time is set from the time it took to acquire a connection. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Variable Name of Pool declared in JDBC Connection Configuration | Yes | Name of the JMeter variable that the connection pool is bound to. This must agree with the '`Variable Name`' field of a [JDBC Connection Configuration](/user-manual/component-reference/#JDBC_Connection_Configuration). | | Query Type | Yes | Set this according to the statement type: - Select Statement - Update Statement - use this for Inserts and Deletes as well - Callable Statement - Prepared Select Statement - Prepared Update Statement - use this for Inserts and Deletes as well - Commit - Rollback - Autocommit(false) - Autocommit(true) - Edit - this should be a variable reference that evaluates to one of the above :::note The types `Commit`, `Rollback`, `Autocommit(false)` and `Autocommit(true)` are special, as they are ignoring the given SQL statements and are changing the state of the connection, only. ::: | | SQL Query | Yes | SQL query. :::note Do not enter a trailing semi-colon. ::: There is generally no need to use `{` and `}` to enclose Callable statements; however they may be used if the database uses a non-standard syntax. :::note The JDBC driver automatically converts the statement if necessary when it is enclosed in `{}`. ::: For example: - `select * from t_customers where id=23` - `CALL SYSCS_UTIL.SYSCS_EXPORT_TABLE (null, ?, ?, null, null, null)` - Parameter values: `tablename`,`filename` - Parameter types: `VARCHAR`,`VARCHAR` The second example assumes you are using Apache Derby. | | Parameter values | Yes, if a prepared or callable statement has parameters | Comma-separated list of parameter values. Use `]NULL[` to indicate a `NULL` parameter. (If required, the null string can be changed by defining the property "`jdbcsampler.nullmarker`".) The list must be enclosed in double-quotes if any of the values contain a comma or double-quote, and any embedded double-quotes must be doubled-up, for example: ``` "Dbl-Quote: "" and Comma: ," ``` :::note There must be as many values as there are placeholders in the statement even if your parameters are `OUT` ones. Be sure to set a value even if the value will not be used (for example in a CallableStatement). ::: | | Parameter types | Yes, if a prepared or callable statement has parameters | Comma-separated list of SQL parameter types (e.g. `INTEGER`, `DATE`, `VARCHAR`, `DOUBLE`) or integer values of Constants. Those integer values can be used, when you use custom database types proposed by driver (For example `OracleTypes.CURSOR` could be represented by its integer value `-10`). These are defined as fields in the class `java.sql.Types`, see for example: [Javadoc for java.sql.Types](http://docs.oracle.com/javase/8/docs/api/java/sql/Types.html). :::note Note: JMeter will use whatever types are defined by the runtime JVM, so if you are running on a different JVM, be sure to check the appropriate documentation ::: If the callable statement has `INOUT` or `OUT` parameters, then these must be indicated by prefixing the appropriate parameter types, e.g. instead of "`INTEGER`", use "`INOUT INTEGER`". If not specified, "`IN`" is assumed, i.e. "`DATE`" is the same as "`IN DATE`". If the type is not one of the fields found in `java.sql.Types`, JMeter also accepts the corresponding integer number, e.g. since `OracleTypes.CURSOR == -10`, you can use "`INOUT -10`". There must be as many types as there are placeholders in the statement. | | Variable Names | No | Comma-separated list of variable names to hold values returned by Select statements, Prepared Select Statements or CallableStatement. Note that when used with CallableStatement, list of variables must be in the same sequence as the `OUT` parameters returned by the call. If there are less variable names than `OUT` parameters only as many results shall be stored in the thread-context variables as variable names were supplied. If more variable names than `OUT` parameters exist, the additional variables will be ignored | | Result Variable Name | No | If specified, this will create an Object variable containing a list of row maps. Each map contains the column name as the key and the column data as the value. Usage: ``` columnValue = vars.getObject("resultObject").get(0).get("Column Name"); ``` | | Query timeout(s) | No | Set a timeout in seconds for query, empty value means 0 which is infinite. `-1` means don't set any query timeout which might be needed for use case or when certain drivers don't support timeout. Defaults to 0. | | Limit ResultSet | No | Limits the number of rows to iterate through the ResultSet. Empty value means `-1`, e.g. no limitation, which is also the default. This can help to reduce the amount of data to be fetched from the database via the JDBC driver, but affects all possible options of `Handle ResultSet` respectively – e.g. incomplete ResultSet and a record count ≤ the limit. | | Handle ResultSet | No | Defines how ResultSet returned from callable statements be handled: - `Store As String` (default) - All variables on Variable Names list are stored as strings, will not iterate through a `ResultSet` when present on the list. `CLOB`s will be converted to Strings. `BLOB`s will be converted to Strings as if they were an UTF-8 encoded byte-array. Both `CLOB`s and `BLOB`s will be cut off after `jdbcsampler.max_retain_result_size` bytes. - `Store As Object` - Variables of `ResultSet` type on Variables Names list will be stored as Object and can be accessed in subsequent tests/scripts and iterated, will not iterate through the `ResultSet`. `CLOB`s will be handled as if `Store As String` was selected. `BLOBs` will be stored as a byte array. Both `CLOB`s and `BLOB`s will be cut off after `jdbcsampler.max_retain_result_size` bytes. - `Count Records` - Variables of `ResultSet` types will be iterated through showing the count of records as result. Variables will be stored as Strings. For `BLOB`s the size of the object will be stored. | :::note Current Versions of JMeter use UTF-8 as the character encoding. Previously the platform default was used. ::: :::note Ensure Variable Name is unique across Test Plan. ::: ## Java Request ![Java Request](/images/screenshots/java_request.png) This sampler lets you control a java class that implements the `org.apache.jmeter.protocol.java.sampler.JavaSamplerClient` interface. By writing your own implementation of this interface, you can use JMeter to harness multiple threads, input parameter control, and data collection. The pull-down menu provides the list of all such implementations found by JMeter in its classpath. The parameters can then be specified in the table below - as defined by your implementation. Two simple examples (`JavaTest` and `SleepTest`) are provided. The `JavaTest` example sampler can be useful for checking test plans, because it allows one to set values in almost all the fields. These can then be used by Assertions, etc. The fields allow variables to be used, so the values of these can readily be seen. :::note If the method `teardownTest` is not overridden by a subclass of `[AbstractJavaSamplerClient](https://jmeter.apache.org/api/org/apache/jmeter/protocol/java/sampler/AbstractJavaSamplerClient.html)`, its `teardownTest` method will not be called. This reduces JMeter memory requirements. This will not have any impact on existing Test plans. ::: :::note The Add/Delete buttons don't serve any purpose at present. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Classname | Yes | The specific implementation of the JavaSamplerClient interface to be sampled. | | Send Parameters with Request | No | A list of arguments that will be passed to the sampled class. All arguments are sent as Strings. See below for specific settings. | The following parameters apply to the `SleepTest` and `JavaTest` implementations: | Name | Required | Description | |------|----------|-------------| | Sleep_time | Yes | How long to sleep for (ms) | | Sleep_mask | Yes | How much "randomness" to add: The sleep time is calculated as follows: ``` totalSleepTime = SleepTime + (System.currentTimeMillis() % SleepMask) ``` | The following parameters apply additionally to the `JavaTest` implementation: | Name | Required | Description | |------|----------|-------------| | Label | No | The label to use. If provided, overrides `Name` | | ResponseCode | No | If provided, sets the SampleResult ResponseCode. | | ResponseMessage | No | If provided, sets the SampleResult ResponseMessage. | | Status | No | If provided, sets the SampleResult Status. If this equals "`OK`" (ignoring case) then the status is set to success, otherwise the sample is marked as failed. | | SamplerData | No | If provided, sets the SampleResult SamplerData. | | ResultData | No | If provided, sets the SampleResult ResultData. | ## LDAP Request ![LDAP Request](/images/screenshots/ldap_request.png) This Sampler lets you send a different LDAP request(`Add`, `Modify`, `Delete` and `Search`) to an LDAP server. If you are going to send multiple requests to the same LDAP server, consider using an [LDAP Request Defaults](/user-manual/component-reference/#LDAP_Request_Defaults) Configuration Element so you do not have to enter the same information for each LDAP Request. The same way the [Login Config Element](/user-manual/component-reference/#Login_Config_Element) also using for Login and password. There are two ways to create test cases for testing an LDAP Server. 1. Inbuilt Test cases. 2. User defined Test cases. There are four test scenarios of testing LDAP. The tests are given below: 1. Add Test 1. Inbuilt test: This will add a pre-defined entry in the LDAP Server and calculate the execution time. After execution of the test, the created entry will be deleted from the LDAP Server. 2. User defined test: This will add the entry in the LDAP Server. User has to enter all the attributes in the table.The entries are collected from the table to add. The execution time is calculated. The created entry will not be deleted after the test. 2. Modify Test 1. Inbuilt test: This will create a pre-defined entry first, then will modify the created entry in the LDAP Server.And calculate the execution time. After execution of the test, the created entry will be deleted from the LDAP Server. 2. User defined test: This will modify the entry in the LDAP Server. User has to enter all the attributes in the table. The entries are collected from the table to modify. The execution time is calculated. The entry will not be deleted from the LDAP Server. 3. Search Test 1. Inbuilt test: This will create the entry first, then will search if the attributes are available. It calculates the execution time of the search query. At the end of the execution,created entry will be deleted from the LDAP Server. 2. User defined test: This will search the user defined entry(Search filter) in the Search base (again, defined by the user). The entries should be available in the LDAP Server. The execution time is calculated. 4. Delete Test 1. Inbuilt test: This will create a pre-defined entry first, then it will be deleted from the LDAP Server. The execution time is calculated. 2. User defined test: This will delete the user-defined entry in the LDAP Server. The entries should be available in the LDAP Server. The execution time is calculated. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Server Name or IP | Yes | Domain name or IP address of the LDAP server. JMeter assumes the LDAP server is listening on the default port (`389`). | | Port | Yes | Port to connect to (default is `389`). | | root DN | Yes | Base DN to use for LDAP operations | | Username | Usually | LDAP server username. | | Password | Usually | LDAP server password. (N.B. this is stored unencrypted in the test plan) | | Entry DN | Yes, if User Defined Test and Add Test or Modify Test is selected | the name of the context to create or Modify; may not be empty. :::note You have to set the right attributes of the object yourself. So if you want to add `cn=apache,ou=test` you have to add in the table `name` and `value` to `cn` and `apache`. ::: | | Delete | Yes, if User Defined Test and Delete Test is selected | the name of the context to Delete; may not be empty | | Search base | Yes, if User Defined Test and Search Test is selected | the name of the context or object to search | | Search filter | Yes, if User Defined Test and Search Test is selected | the filter expression to use for the search; may not be null | | add test | Yes, if User Defined Test and add Test is selected | Use these `name`, `value` pairs for creation of the new object in the given context | | modify test | Yes, if User Defined Test and Modify Test is selected | Use these `name`, `value` pairs for modification of the given context object | ## LDAP Extended Request ![LDAP Extended Request](/images/screenshots/ldapext_request.png) This Sampler can send all 8 different LDAP requests to an LDAP server. It is an extended version of the LDAP sampler, therefore it is harder to configure, but can be made much closer resembling a real LDAP session. If you are going to send multiple requests to the same LDAP server, consider using an [LDAP Extended Request Defaults](/user-manual/component-reference/#LDAP_Extended_Request_Defaults) Configuration Element so you do not have to enter the same information for each LDAP Request. There are nine test operations defined. These operations are given below: ****Thread bind**** : Any LDAP request is part of an LDAP session, so the first thing that should be done is starting a session to the LDAP server. For starting this session a thread bind is used, which is equal to the LDAP "`bind`" operation. The user is requested to give a `username` (Distinguished name) and `password`, which will be used to initiate a session. When no password, or the wrong password is specified, an anonymous session is started. Take care, omitting the password will not fail this test, a wrong password will. (N.B. this is stored unencrypted in the test plan) | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Servername | Yes | The name (or IP-address) of the LDAP server. | | Port | No | The port number that the LDAP server is listening to. If this is omitted JMeter assumes the LDAP server is listening on the default port(389). | | DN | No | The distinguished name of the base object that will be used for any subsequent operation. It can be used as a starting point for all operations. You cannot start any operation on a higher level than this DN! | | Username | No | Full distinguished name of the user as which you want to bind. | | Password | No | Password for the above user. If omitted it will result in an anonymous bind. If it is incorrect, the sampler will return an error and revert to an anonymous bind. (N.B. this is stored unencrypted in the test plan) | | Connection timeout (in milliseconds) | No | Timeout for connection, if exceeded connection will be aborted | | Use Secure LDAP Protocol | No | Use `ldaps://` scheme instead of `ldap://` | | Trust All Certificates | No | Trust all certificates, only used if `Use Secure LDAP Protocol` is checked | ****Thread unbind**** : This is simply the operation to end a session. It is equal to the LDAP "`unbind`" operation. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | ****Single bind/unbind**** : This is a combination of the LDAP "`bind`" and "`unbind`" operations. It can be used for an authentication request/password check for any user. It will open a new session, just to check the validity of the user/password combination, and end the session again. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Username | Yes | Full distinguished name of the user as which you want to bind. | | Password | No | Password for the above user. If omitted it will result in an anonymous bind. If it is incorrect, the sampler will return an error. (N.B. this is stored unencrypted in the test plan) | ****Rename entry**** : This is the LDAP "`moddn`" operation. It can be used to rename an entry, but also for moving an entry or a complete subtree to a different place in the LDAP tree. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Old entry name | Yes | The current distinguished name of the object you want to rename or move, relative to the given DN in the thread bind operation. | | New distinguished name | Yes | The new distinguished name of the object you want to rename or move, relative to the given DN in the thread bind operation. | ****Add test**** : This is the LDAP "`add`" operation. It can be used to add any kind of object to the LDAP server. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Entry DN | Yes | Distinguished name of the object you want to add, relative to the given DN in the thread bind operation. | | Add test | Yes | A list of attributes and their values you want to use for the object. If you need to add a multiple value attribute, you need to add the same attribute with their respective values several times to the list. | ****Delete test**** : This is the LDAP "`delete`" operation, it can be used to delete an object from the LDAP tree | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Delete | Yes | Distinguished name of the object you want to delete, relative to the given DN in the thread bind operation. | ****Search test**** : This is the LDAP "`search`" operation, and will be used for defining searches. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Search base | No | Distinguished name of the subtree you want your search to look in, relative to the given DN in the thread bind operation. | | Search Filter | Yes | searchfilter, must be specified in LDAP syntax. | | Scope | No | Use `0` for baseobject-, `1` for onelevel- and `2` for a subtree search. (Default=`0`) | | Size Limit | No | Specify the maximum number of results you want back from the server. (default=`0`, which means no limit.) When the sampler hits the maximum number of results, it will fail with errorcode `4` | | Time Limit | No | Specify the maximum amount of (cpu)time (in milliseconds) that the server can spend on your search. Take care, this does not say anything about the response time. (default is `0`, which means no limit) | | Attributes | No | Specify the attributes you want to have returned, separated by a semicolon. An empty field will return all attributes | | Return object | No | Whether the object will be returned (`true`) or not (`false`). Default=`false` | | Dereference aliases | No | If `true`, it will dereference aliases, if `false`, it will not follow them (default=`false`) | | Parse the search results | No | If `true`, the search results will be added to the response data. If `false`, a marker - whether results where found or not - will be added to the response data. | ****Modification test**** : This is the LDAP "`modify`" operation. It can be used to modify an object. It can be used to add, delete or replace values of an attribute. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Entry name | Yes | Distinguished name of the object you want to modify, relative to the given DN in the thread bind operation | | Modification test | Yes | The attribute-value-opCode triples. The `opCode` can be any valid LDAP operationCode (`add`, `delete`, `remove` or `replace`). If you don't specify a value with a `delete` operation, all values of the given attribute will be deleted. If you do specify a value in a `delete` operation, only the given value will be deleted. If this value is non-existent, the sampler will fail the test. | ****Compare**** : This is the LDAP "`compare`" operation. It can be used to compare the value of a given attribute with some already known value. In reality this is mostly used to check whether a given person is a member of some group. In such a case you can compare the DN of the user as a given value, with the values in the attribute "`member`" of an object of the type `groupOfNames`. If the compare operation fails, this test fails with errorcode `49`. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Entry DN | Yes | The current distinguished name of the object of which you want to compare an attribute, relative to the given DN in the thread bind operation. | | Compare filter | Yes | In the form "`attribute=value`" | ## Access Log Sampler ![Access Log Sampler](/images/screenshots/accesslogsampler.png) ### (Beta Code) AccessLogSampler was designed to read access logs and generate http requests. For those not familiar with the access log, it is the log the webserver maintains of every request it accepted. This means every image, CSS file, JavaScript file, html file, … Tomcat uses the common format for access logs. This means any webserver that uses the common log format can use the AccessLogSampler. Server that use common log format include: Tomcat, Resin, Weblogic, and SunOne. Common log format looks like this: ``` 127.0.0.1 - - [21/Oct/2003:05:37:21 -0500] "GET /index.jsp?%2Findex.jsp= HTTP/1.1" 200 8343 ``` :::note The current implementation of the parser only looks at the text within the quotes that contains one of the HTTP protocol methods (`GET`, `PUT`, `POST`, `DELETE`, …). Everything else is stripped out and ignored. For example, the response code is completely ignored by the parser. ::: For the future, it might be nice to filter out entries that do not have a response code of `200`. Extending the sampler should be fairly simple. There are two interfaces you have to implement: - `org.apache.jmeter.protocol.http.util.accesslog.LogParser` - `org.apache.jmeter.protocol.http.util.accesslog.Generator` The current implementation of AccessLogSampler uses the generator to create a new HTTPSampler. The servername, port and get images are set by AccessLogSampler. Next, the parser is called with integer `1`, telling it to parse one entry. After that, `HTTPSampler.sample()` is called to make the request. ``` samp = (HTTPSampler) GENERATOR.generateRequest(); samp.setDomain(this.getDomain()); samp.setPort(this.getPort()); samp.setImageParser(this.isImageParser()); PARSER.parse(1); res = samp.sample(); res.setSampleLabel(samp.toString()); ``` The required methods in `LogParser` are: - `setGenerator(Generator)` - `parse(int)` Classes implementing `Generator` interface should provide concrete implementation for all the methods. For an example of how to implement either interface, refer to `StandardGenerator` and `TCLogParser`. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Server | Yes | Domain name or IP address of the web server. | | Protocol | No (defaults to http | Scheme | | Port | No (defaults to 80) | Port the web server is listening to. | | Log parser class | Yes (default provided) | The log parser class is responsible for parsing the logs. | | Filter | No | The filter class is used to filter out certain lines. | | Location of log file | Yes | The location of the access log file. | The `TCLogParser` processes the access log independently for each thread. The `SharedTCLogParser` and `OrderPreservingLogParser` share access to the file, i.e. each thread gets the next entry in the log. The `SessionFilter` is intended to handle Cookies across threads. It does not filter out any entries, but modifies the cookie manager so that the cookies for a given IP are processed by a single thread at a time. If two threads try to process samples from the same client IP address, then one will be forced to wait until the other has completed. The `LogFilter` is intended to allow access log entries to be filtered by filename and regex, as well as allowing for the replacement of file extensions. However, it is not currently possible to configure this via the GUI, so it cannot really be used. ## BeanShell Sampler ![BeanShell Sampler](/images/screenshots/beanshellsampler.png) This sampler allows you to write a sampler using the BeanShell scripting language. **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 Sampler](/user-manual/component-reference/#JSR223_Sampler)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: The test element supports the `ThreadListener` and `TestListener` interface methods. These must be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. The BeanShell sampler also supports the `Interruptible` interface. The `interrupt()` method can be defined in the script or the init file. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. The name is stored in the script variable Label | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. This is intended for use with script files; for scripts defined in the GUI, you can use whatever variable and function references you need within the script itself. The parameters are stored in the following variables: **`Parameters`** : string containing the parameters as a single variable **`bsh.args`** : String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. The file name is stored in the script variable `FileName` | | Script | Yes (unless script file is provided) | The BeanShell script to run. The return value (if not `null`) is stored as the sampler result. | :::note N.B. Each Sampler instance has its own BeanShell interpreter, and Samplers are only called from a single thread ::: If the property "`beanshell.sampler.init`" is defined, it is passed to the Interpreter as the name of a sourced file. This can be used to define common methods and variables. There is a sample init file in the bin directory: `BeanShellSampler.bshrc`. If a script file is supplied, that will be used, otherwise the script will be used. :::note JMeter processes function and variable references before passing the script field to the interpreter, so the references will only be resolved once. Variable and function references in script files will be passed verbatim to the interpreter, which is likely to cause a syntax error. In order to use runtime variables, please use the appropriate props methods, e.g.`props.get("START.HMS"); props.put("PROP1","1234");` BeanShell does not currently support Java 5 syntax such as generics and the enhanced for loop. ::: Before invoking the script, some variables are set up in the BeanShell interpreter: The contents of the Parameters field is put into the variable "`Parameters`". The string is also split into separate tokens using a single space as the separator, and the resulting list is stored in the String array `bsh.args`. The full list of BeanShell variables that is set up is as follows: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) - `Label` - the Sampler label - `FileName` - the file name, if any - `Parameters` - text from the Parameters field - `bsh.args` - the parameters, split as described above - `SampleResult` - pointer to the current [`SampleResult`](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) - `ResponseCode` defaults to `200` - `ResponseMessage` defaults to "`OK`" - `IsSuccess` defaults to `true` - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) - e.g. ``` vars.get("VAR1"); vars.put("VAR2","value"); vars.remove("VAR3"); vars.putObject("OBJ1",new Object()); ``` - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. ``` props.get("START.HMS"); props.put("PROP1","1234"); ``` When the script completes, control is returned to the Sampler, and it copies the contents of the following script variables into the corresponding variables in the [`SampleResult`](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html): - `ResponseCode` - for example `200` - `ResponseMessage` - for example "`OK`" - `IsSuccess` - `true` or `false` The SampleResult ResponseData is set from the return value of the script. If the script returns null, it can set the response directly, by using the method `SampleResult.setResponseData(data)`, where data is either a String or a byte array. The data type defaults to "`text`", but can be set to binary by using the method `SampleResult.setDataType(SampleResult.BINARY)`. The `SampleResult` variable gives the script full access to all the fields and methods in the `SampleResult`. For example, the script has access to the methods `setStopThread(boolean)` and `setStopTest(boolean)`. Here is a simple (not very useful!) example script: ``` if (bsh.args[0].equalsIgnoreCase("StopThread")) { log.info("Stop Thread detected!"); SampleResult.setStopThread(true); } return "Data from sample with Label "+Label; //or SampleResult.setResponseData("My data"); return null; ``` Another example: ensure that the property `beanshell.sampler.init=BeanShellSampler.bshrc` is defined in `jmeter.properties`. The following script will show the values of all the variables in the `ResponseData` field: ``` return getVariables(); ``` For details on the methods available for the various classes ([`JMeterVariables`](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html), [`SampleResult`](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) etc.) please check the Javadoc or the source code. Beware however that misuse of any methods can cause subtle faults that may be difficult to find. ## JSR223 Sampler ![JSR223 Sampler](/images/screenshots/jsr223-sampler.png) The JSR223 Sampler allows JSR223 script code to be used to perform a sample or some computation required to create/update variables. :::note If you don't want to generate a [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) when this sampler is run, call the following method: ``` SampleResult.setIgnore(); ``` This call will have the following impact: - SampleResult will not be delivered to SampleListeners like View Results Tree, Summariser ... - SampleResult will not be evaluated in Assertions nor PostProcessors - SampleResult will be evaluated to computing last sample status (\$\{JMeterThread.last_sample_ok\}), and ThreadGroup "Action to be taken after a Sampler error" (since JMeter 5.4) ::: The JSR223 test elements have a feature (compilation) that can significantly increase performance. To benefit from this feature: - Use Script files instead of inlining them. This will make JMeter compile them if this feature is available on ScriptEngine and cache them. - Or Use Script Text and check `Cache compiled script if available` property. :::note When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters. ::: :::note To benefit from caching and compilation, the language engine used for scripting must implement JSR223 `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not) ::: :::note When using Groovy as scripting language and not checking `Cache compiled script if available` (while caching is recommended), you should set this JVM Property `-Dgroovy.use.classvalue=true` due to a Groovy Memory leak as of version 2.4.6, see: - [GROOVY-7683](https://issues.apache.org/jira/browse/GROOVY-7683) - [GROOVY-7591](https://issues.apache.org/jira/browse/GROOVY-7591) - [JDK-8136353](https://bugs.openjdk.java.net/browse/JDK-8136353) ::: Cache size is controlled by the following JMeter property (`jmeter.properties`): ``` jsr223.compiled_scripts_cache_size=100 ``` :::note Unlike the [BeanShell Sampler](/user-manual/component-reference/#BeanShell_Sampler), the interpreter is not saved between invocations. ::: :::note JSR223 Test Elements using Script file or Script text + checked `Cache compiled script if available` are now compiled if ScriptEngine supports this feature, this enables great performance enhancements. ::: :::note JMeter processes function and variable references before passing the script field to the interpreter, so the references will only be resolved once. Variable and function references in script files will be passed verbatim to the interpreter, which is likely to cause a syntax error. In order to use runtime variables, please use the appropriate props methods, e.g. ``` props.get("START.HMS"); props.put("PROP1","1234"); ``` ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Scripting Language | Yes | Name of the JSR223 scripting language to be used. :::note There are other languages supported than those that appear in the drop-down list. Others may be available if the appropriate jar is installed in the JMeter lib directory. Notice that some languages such as Velocity may use a different syntax for JSR223 variables, e.g. ```bash $log.debug("Hello " + $vars.get("a")); ``` for Velocity. ::: | | Script File | No | Name of a file to be used as a JSR223 script, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property | | Parameters | No | List of parameters to be passed to the script file or the script. | | Cache compiled script if available | No | If checked (advised) and the language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not), JMeter will compile the Script and cache it using its MD5 hash as unique cache key | | Script | Yes (unless script file is provided) | Script to be passed to JSR223 language | If a script file is supplied, that will be used, otherwise the script will be used. Before invoking the script, some variables are set up. Note that these are JSR223 variables - i.e. they can be used directly in the script. - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) - `Label` - the Sampler label - `FileName` - the file name, if any - `Parameters` - text from the Parameters field - `args` - the parameters, split as described above - `SampleResult` - pointer to the current [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html)) - pointer to current Sampler - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) - e.g. ``` vars.get("VAR1"); vars.put("VAR2","value"); vars.remove("VAR3"); vars.putObject("OBJ1",new Object()); ``` - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. ``` props.get("START.HMS"); props.put("PROP1","1234"); ``` - `OUT` - System.out - e.g. `OUT.println("message")` The [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) ResponseData is set from the return value of the script. If the script returns `null`, it can set the response directly, by using the method `SampleResult.setResponseData(data)`, where data is either a String or a byte array. The data type defaults to "`text`", but can be set to binary by using the method `SampleResult.setDataType(SampleResult.BINARY)`. The SampleResult variable gives the script full access to all the fields and methods in the SampleResult. For example, the script has access to the methods `setStopThread(boolean)` and `setStopTest(boolean)`. Unlike the BeanShell Sampler, the JSR223 Sampler does not set the `ResponseCode`, `ResponseMessage` and sample status via script variables. Currently the only way to changes these is via the [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) methods: - `SampleResult.setSuccessful(true/false)` - `SampleResult.setResponseCode("code")` - `SampleResult.setResponseMessage("message")` ## TCP Sampler ![TCP Sampler](/images/screenshots/tcpsampler.png) The TCP Sampler opens a TCP/IP connection to the specified server. It then sends the text, and waits for a response. If "`Re-use connection`" is selected, connections are shared between Samplers in the same thread, provided that the exact same host name string and port are used. Different hosts/port combinations will use different connections, as will different threads. If both of "`Re-use connection`" and "`Close connection`" are selected, the socket will be closed after running the sampler. On the next sampler, another socket will be created. You may want to close a socket at the end of each thread loop. If an error is detected - or "`Re-use connection`" is not selected - the socket is closed. Another socket will be reopened on the next sample. The following properties can be used to control its operation: **`tcp.status.prefix`** : text that precedes a status number **`tcp.status.suffix`** : text that follows a status number **`tcp.status.properties`** : name of property file to convert status codes to messages **`tcp.handler`** : Name of TCP Handler class (default `TCPClientImpl`) - only used if not specified on the GUI The class that handles the connection is defined by the GUI, failing that the property `tcp.handler`. If not found, the class is then searched for in the package `org.apache.jmeter.protocol.tcp.sampler`. Users can provide their own implementation. The class must extend `org.apache.jmeter.protocol.tcp.sampler.TCPClient`. The following implementations are currently provided. - `TCPClientImpl` - `BinaryTCPClientImpl` - `LengthPrefixedBinaryTCPClientImpl` The implementations behave as follows: **`TCPClientImpl`** : This implementation is fairly basic. When reading the response, it reads until the end of line byte, if this is defined by setting the property `tcp.eolByte`, otherwise until the end of the input stream. You can control charset encoding by setting `tcp.charset`, which will default to Platform default encoding. **`BinaryTCPClientImpl`** : This implementation converts the GUI input, which must be a hex-encoded string, into binary, and performs the reverse when reading the response. When reading the response, it reads until the end of message byte, if this is defined by setting the property `tcp.BinaryTCPClient.eomByte`, otherwise until the end of the input stream. **`LengthPrefixedBinaryTCPClientImpl`** : This implementation extends BinaryTCPClientImpl by prefixing the binary message data with a binary length byte. The length prefix defaults to 2 bytes. This can be changed by setting the property `tcp.binarylength.prefix.length`. ****Timeout handling**** : If the timeout is set, the read will be terminated when this expires. So if you are using an `eolByte`/`eomByte`, make sure the timeout is sufficiently long, otherwise the read will be terminated early. ****Response handling**** : If `tcp.status.prefix` is defined, then the response message is searched for the text following that up to the suffix. If any such text is found, it is used to set the response code. The response message is then fetched from the properties file (if provided). #### Usage of pre- and suffix For example, if the prefix = "`[`" and the suffix = "`]`", then the following response: ```json [J28] XI123,23,GBP,CR ``` would have the response code `J28`. Response codes in the range "`400`"-"`499`" and "`500`"-"`599`" are currently regarded as failures; all others are successful. [This needs to be made configurable!] :::note The login name/password are not used by the supplied TCP implementations. ::: Sockets are disconnected at the end of a test run. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | TCPClient classname | No | Name of the TCPClient class. Defaults to the property `tcp.handler`, failing that `TCPClientImpl`. | | ServerName or IP | Yes | Name or IP of TCP server | | Port Number | Yes | Port to be used | | Re-use connection | Yes | If selected, the connection is kept open. Otherwise it is closed when the data has been read. | | Close connection | Yes | If selected, the connection will be closed after running the sampler. | | SO_LINGER | No | Enable/disable `SO_LINGER` with the specified linger time in seconds when a socket is created. If you set "`SO_LINGER`" value as `0`, you may prevent large numbers of sockets sitting around with a `TIME_WAIT` status. | | End of line(EOL) byte value | No | Byte value for end of line, set this to a value outside the range `-128` to `+127` to skip `eol` checking. You may set this in `jmeter.properties` file as well with `eolByte` property. If you set this in TCP Sampler Config and in `jmeter.properties` file at the same time, the setting value in the TCP Sampler Config will be used. | | Connect Timeout | No | Connect Timeout (milliseconds, `0` disables). | | Response Timeout | No | Response Timeout (milliseconds, `0` disables). | | Set NoDelay | Yes | See `java.net.Socket.setTcpNoDelay()`. If selected, this will disable Nagle's algorithm, otherwise Nagle's algorithm will be used. | | Text to Send | Yes | Text to be sent | | Login User | No | User Name - not used by default implementation | | Password | No | Password - not used by default implementation (N.B. this is stored unencrypted in the test plan) | ## JMS Publisher ![JMS Publisher](/images/screenshots/jmspublisher.png) JMS Publisher will publish messages to a given destination (topic/queue). For those not familiar with JMS, it is the J2EE specification for messaging. There are numerous JMS servers on the market and several open source options. :::note JMeter does not include any JMS implementation jar; this must be downloaded from the JMS provider and put in the lib directory ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | use JNDI properties file | Yes | use `jndi.properties`. Note that the file must be on the classpath - e.g. by updating the `user.classpath` JMeter property. If this option is not selected, JMeter uses the "`JNDI Initial Context Factory`" and "`Provider URL`" fields to create the connection. | | JNDI Initial Context Factory | No | Name of the context factory | | Provider URL | Yes, unless using jndi.properties | The URL for the JMS provider | | Destination | Yes | The message destination (topic or queue name) | | Setup | Yes | The destination setup type. With `At startup`, the destination name is static (i.e. always same name during the test), with `Each sample`, the destination name is dynamic and is evaluate at each sample (i.e. the destination name may be a variable) | | Authentication | Yes | Authentication requirement for the JMS provider | | User | No | User Name | | Password | No | Password (N.B. this is stored unencrypted in the test plan) | | Expiration | No | The expiration time (in milliseconds) of the message before it becomes obsolete. If you do not specify an expiration time, the default value is `0` (never expires). | | Priority | No | The priority level of the message. There are ten priority levels from `0` (lowest) to `9` (highest). If you do not specify a priority level, the default level is `4`. | | Reconnect on error codes (regex) | No | Regular expression for JMSException error codes which force reconnection. If empty no reconnection will be done | | Number of samples to aggregate | Yes | Number of samples to aggregate | | Message source | Yes | Where to obtain the message: **`From File`** : means the referenced file will be read and reused by all samples. If file name changes it is reloaded since JMeter 3.0 **`Random File from folder specified below`** : means a random file will be selected from folder specified below, this folder must contain either files with extension `.dat` for Bytes Messages, or files with extension `.txt` or `.obj` for Object or Text messages **`Text area`** : The Message to use either for Text or Object message | | Message type | Yes | Text, Map, Object message or Bytes Message | | Content encoding | Yes | Specify the encoding for reading the message source file: **`RAW`:** : No variable support from the file and load it with default system charset. **`DEFAULT`:** : Load file with default system encoding, except for XML which relies on XML prolog. If the file contain variables, they will be processed. **`Standard charsets`:** : The specified encoding (valid or not) is used for reading the file and processing variables | | Use non-persistent delivery mode | No | Whether to set `DeliveryMode.NON_PERSISTENT` (defaults to `false`) | | JMS Properties | No | The JMS Properties are properties specific for the underlying messaging system. You can setup the name, the value and the class (type) of value. Default type is `String`. For example: for WebSphere 5.1 web services you will need to set the JMS Property targetService to test webservices through JMS. | For the MapMessage type, JMeter reads the source as lines of text. Each line must have 3 fields, delimited by commas. The fields are: - Name of entry - Object class name, e.g. "`String`" (assumes `java.lang` package if not specified) - Object string value For each entry, JMeter adds an Object with the given name. The value is derived by creating an instance of the class, and using the `valueOf(String)` method to convert the value if necessary. For example: ``` name,String,Example size,Integer,1234 ``` This is a very simple implementation; it is not intended to support all possible object types. :::note The Object message is implemented and works as follow: - Put the JAR that contains your object and its dependencies in `jmeter_home/lib/` folder - Serialize your object as XML using XStream - Either put result in a file suffixed with `.txt` or `.obj` or put XML content directly in Text Area Note that if message is in a file, replacement of properties will not occur while it will if you use Text Area. ::: The following table shows some values which may be useful when configuring JMS: | | | | | --- | --- | --- | | Context Factory | `org.apache.activemq.jndi.ActiveMQInitialContextFactory` | . | | Provider URL | `vm://localhost` | | | Provider URL | `vm:(broker:(vm://localhost)?persistent=false)` | Disable persistence | | Queue Reference | `dynamicQueues/QUEUENAME` | [Dynamically define](http://activemq.apache.org/jndi-support.html#JNDISupport-Dynamicallycreatingdestinations) the QUEUENAME to JNDI | | Topic Reference | `dynamicTopics/TOPICNAME` | [Dynamically define](http://activemq.apache.org/jndi-support.html#JNDISupport-Dynamicallycreatingdestinations) the TOPICNAME to JNDI | ## JMS Subscriber ![JMS Subscriber](/images/screenshots/jmssubscriber.png) JMS Subscriber will subscribe to messages in a given destination (topic or queue). For those not familiar with JMS, it is the J2EE specification for messaging. There are numerous JMS servers on the market and several open source options. :::note JMeter does not include any JMS implementation jar; this must be downloaded from the JMS provider and put in the lib directory ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | use JNDI properties file | Yes | use `jndi.properties`. Note that the file must be on the classpath - e.g. by updating the `user.classpath` JMeter property. If this option is not selected, JMeter uses the "`JNDI Initial Context Factory`" and "`Provider URL`" fields to create the connection. | | JNDI Initial Context Factory | No | Name of the context factory | | Provider URL | No | The URL for the JMS provider | | Destination | Yes | the message destination (topic or queue name) | | Durable Subscription ID | No | The ID to use for a durable subscription. On first use the respective queue will automatically be generated by the JMS provider if it does not exist yet. | | Client ID | No | The Client ID to use when you use a durable subscription. Be sure to add a variable like `\${__threadNum}` when you have more than one Thread. | | JMS Selector | No | Message Selector as defined by JMS specification to extract only messages that respect the Selector condition. Syntax uses subpart of SQL 92. | | Setup | Yes | The destination setup type. With `At startup`, the destination name is static (i.e. always same name during the test), with `Each sample`, the destination name is dynamic and is evaluated at each sample (i.e. the destination name may be a variable) | | Authentication | Yes | Authentication requirement for the JMS provider | | User | No | User Name | | Password | No | Password (N.B. this is stored unencrypted in the test plan) | | Number of samples to aggregate | Yes | number of samples to aggregate | | Save response | Yes | should the sampler store the response. If not, only the response length is returned. | | Timeout | Yes | Specify the timeout to be applied, in milliseconds. `0`=none. This is the overall aggregate timeout, not per sample. | | Client | Yes | Which client implementation to use. Both of them create connections which can read messages. However they use a different strategy, as described below: **`MessageConsumer.receive()`** : calls `receive()` for every requested message. Retains the connection between samples, but does not fetch messages unless the sampler is active. This is best suited to Queue subscriptions. **`MessageListener.onMessage()`** : establishes a Listener that stores all incoming messages on a queue. The listener remains active after the sampler completes. This is best suited to Topic subscriptions. | | Stop between samples | Yes | If selected, then JMeter calls `Connection.stop()` at the end of each sample (and calls `start()` before each sample). This may be useful in some cases where multiple samples/threads have connections to the same queue. If not selected, JMeter calls `Connection.start()` at the start of the thread, and does not call `stop()` until the end of the thread. | | Separator | No | Separator used to separate messages when there is more than one (related to setting Number of samples to aggregate). Note that `\n`, `\r`, `\t` are accepted. | | Reconnect on error codes (regex) | No | Regular expression for JMSException error codes which force reconnection. If empty no reconnection will be done | | Pause between errors (ms) | No | Pause in milliseconds that Subscriber will make when an error occurs | ## JMS Point-to-Point ![JMS Point-to-Point](/images/screenshots/jms/JMS_Point-to-Point.png) This sampler sends and optionally receives JMS Messages through point-to-point connections (queues). It is different from pub/sub messages and is generally used for handling transactions. `request_only` will typically be used to put load on a JMS System. `request_reply` will be used when you want to test response time of a JMS service that processes messages sent to the Request Queue as this mode will wait for the response on the Reply queue sent by this service. `browse` returns the current queue depth, i.e. the number of messages on the queue. `read` reads a message from the queue (if any). `clear` clears the queue, i.e. remove all messages from the queue. JMeter use the properties `java.naming.security.[principal|credentials]` - if present - when creating the Queue Connection. If this behaviour is not desired, set the JMeter property `JMSSampler.useSecurity.properties=false` :::note JMeter does not include any JMS implementation jar; this must be downloaded from the JMS provider and put in the lib directory ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | QueueConnection Factory | Yes | The JNDI name of the queue connection factory to use for connecting to the messaging system. | | JNDI Name Request queue | Yes | This is the JNDI name of the queue to which the messages are sent. | | JNDI Name Reply queue | No | The JNDI name of the receiving queue. If a value is provided here and the communication style is `Request Response` this queue will be monitored for responses to the requests sent. | | Number of samples to aggregate | Yes | Number of samples to aggregate. Only applicable for Communication style Read. | | JMS Selector | No | Message Selector as defined by JMS specification to extract only messages that respect the Selector condition. Syntax uses subpart of SQL 92. | | Communication style | Yes | The Communication style can be `Request Only` (also known as Fire and Forget), `Request Response`, `Read`, `Browse`, `Clear`: **`Request Only`** : will only send messages and will not monitor replies. As such it can be used to put load on a system. **`Request Response`** : will send messages and monitor the replies it receives. Behaviour depends on the value of the JNDI Name Reply Queue. If JNDI Name Reply Queue has a value, this queue is used to monitor the results. Matching of request and reply is done with the message id of the request and the correlation id of the reply. If the JNDI Name Reply Queue is empty, then temporary queues will be used for the communication between the requestor and the server. This is very different from the fixed reply queue. With temporary queues the sending thread will block until the reply message has been received. With `Request Response` mode, you need to have a Server that listens to messages sent to Request Queue and sends replies to queue referenced by `message.getJMSReplyTo()`. **`Read`** : will read a message from an outgoing queue which has no listeners attached. This can be convenient for testing purposes. This method can be used if you need to handle queues without a binding file (in case the jmeter-jms-skip-jndi library is used), which only works with the JMS Point-to-Point sampler. In case binding files are used, one can also use the JMS Subscriber Sampler for reading from a queue. **`Browse`** : will determine the current queue depth without removing messages from the queue, returning the number of messages on the queue. **`Clear`** : will clear the queue, i.e. remove all messages from the queue. | | Use alternate fields for message correlation | Yes | These check-boxes select the fields which will be used for matching the response message with the original request. **`Use Request Message Id`** : if selected, the request JMSMessageID will be used, otherwise the request JMSCorrelationID will be used. In the latter case the correlation id must be specified in the request. **`Use Response Message Id`** : if selected, the response JMSMessageID will be used, otherwise the response JMSCorrelationID will be used. There are two frequently used JMS Correlation patterns: **JMS Correlation ID Pattern** : i.e. match request and response on their correlation Ids => deselect both checkboxes, and provide a correlation id. **JMS Message ID Pattern** : i.e. match request message id with response correlation id => select "Use Request Message Id" only. In both cases the JMS application is responsible for populating the correlation ID as necessary. :::note if the same queue is used to send and receive messages, then the response message will be the same as the request message. In which case, either provide a correlation id and clear both checkboxes; or select both checkboxes to use the message Id for correlation. This can be useful for checking raw JMS throughput. ::: | | Timeout | Yes | The timeout in milliseconds for the reply-messages. If a reply has not been received within the specified time, the specific testcase fails and the specific reply message received after the timeout is discarded. Default value is `2000` ms. `0` means no timeout. | | Expiration | No | The expiration time (in milliseconds) of the message before it becomes obsolete. If you do not specify an expiration time, the default value is `0` (never expires). | | Priority | No | The priority level of the message. There are ten priority levels from `0` (lowest) to `9` (highest). If you do not specify a priority level, the default level is `4`. | | Use non-persistent delivery mode | Yes | Whether to set `DeliveryMode.NON_PERSISTENT`. | | Content | No | The content of the message. | | JMS Properties | No | The JMS Properties are properties specific for the underlying messaging system. You can setup the name, the value and the class (type) of value. Default type is `String`. For example: for WebSphere 5.1 web services you will need to set the JMS Property targetService to test webservices through JMS. | | Initial Context Factory | No | The Initial Context Factory is the factory to be used to look up the JMS Resources. | | JNDI properties | No | The JNDI Properties are the specific properties for the underlying JNDI implementation. | | Provider URL | No | The URL for the JMS provider. | ## JUnit Request ![JUnit Request](/images/screenshots/junit_sampler.png) The current implementation supports standard JUnit convention and extensions. It also includes extensions like `oneTimeSetUp` and `oneTimeTearDown`. The sampler works like the [Java Request](/user-manual/component-reference/#Java_Request) with some differences. - rather than use JMeter's test interface, it scans the jar files for classes extending JUnit's `TestCase` class. That includes any class or subclass. - JUnit test jar files should be placed in `jmeter/lib/junit` instead of `/lib` directory. You can also use the "`user.classpath`" property to specify where to look for `TestCase` classes. - JUnit sampler does not use name/value pairs for configuration like the [Java Request](/user-manual/component-reference/#Java_Request). The sampler assumes `setUp` and `tearDown` will configure the test correctly. - The sampler measures the elapsed time only for the test method and does not include `setUp` and `tearDown`. - Each time the test method is called, JMeter will pass the result to the listeners. - Support for `oneTimeSetUp` and `oneTimeTearDown` is done as a method. Since JMeter is multi-threaded, we cannot call `oneTimeSetUp`/`oneTimeTearDown` the same way Maven does it. - The sampler reports unexpected exceptions as errors. There are some important differences between standard JUnit test runners and JMeter's implementation. Rather than make a new instance of the class for each test, JMeter creates 1 instance per sampler and reuses it. This can be changed with checkbox "`Create a new instance per sample`". The current implementation of the sampler will try to create an instance using the string constructor first. If the test class does not declare a string constructor, the sampler will look for an empty constructor. Example below: #### JUnit Constructors Empty Constructor: ```java public class myTestCase { public myTestCase() {} } ``` String Constructor: ```java public class myTestCase { public myTestCase(String text) { super(text); } } ``` By default, JMeter will provide some default values for the success/failure code and message. Users should define a set of unique success and failure codes and use them uniformly across all tests. :::note #### General Guidelines If you use `setUp` and `tearDown`, make sure the methods are declared public. If you do not, the test may not run properly. Here are some general guidelines for writing JUnit tests so they work well with JMeter. Since JMeter runs multi-threaded, it is important to keep certain things in mind. - Write the `setUp` and `tearDown` methods so they are thread safe. This generally means avoid using static members. - Make the test methods discrete units of work and not long sequences of actions. By keeping the test method to a discrete operation, it makes it easier to combine test methods to create new test plans. - Avoid making test methods depend on each other. Since JMeter allows arbitrary sequencing of test methods, the runtime behavior is different than the default JUnit behavior. - If a test method is configurable, be careful about where the properties are stored. Reading the properties from the Jar file is recommended. - Each sampler creates an instance of the test class, so write your test so the setup happens in `oneTimeSetUp` and `oneTimeTearDown`. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Search for JUnit4 annotations | Yes | Select this to search for JUnit4 tests (`@Test` annotations) | | Package filter | No | Comma separated list of packages to show. Example, `org.apache.jmeter`,`junit.framework`. | | Class name | Yes | Fully qualified name of the JUnit test class. | | Constructor string | No | String pass to the string constructor. If a string is set, the sampler will use the string constructor instead of the empty constructor. | | Test method | Yes | The method to test. | | Success message | No | A descriptive message indicating what success means. | | Success code | No | An unique code indicating the test was successful. | | Failure message | No | A descriptive message indicating what failure means. | | Failure code | No | An unique code indicating the test failed. | | Error message | No | A description for errors. | | Error code | No | Some code for errors. Does not need to be unique. | | Do not call setUp and tearDown | Yes | Set the sampler not to call `setUp` and `tearDown`. By default, `setUp` and `tearDown` should be called. Not calling those methods could affect the test and make it inaccurate. This option should only be used with calling `oneTimeSetUp` and `oneTimeTearDown`. If the selected method is `oneTimeSetUp` or `oneTimeTearDown`, this option should be checked. | | Append assertion errors | Yes | Whether or not to append assertion errors to the response message. | | Append runtime exceptions | Yes | Whether or not to append runtime exceptions to the response message. Only applies if "`Append assertion errors`" is not selected. | | Create a new Instance per sample | Yes | Whether or not to create a new JUnit instance for each sample. Defaults to false, meaning JUnit `TestCase` is created one and reused. | The following JUnit4 annotations are recognised: **`@Test`** : used to find test methods and classes. The "`expected`" and "`timeout`" attributes are supported. **`@Before`** : treated the same as `setUp()` in JUnit3 **`@After`** : treated the same as `tearDown()` in JUnit3 **`@BeforeClass`, `@AfterClass`** : treated as test methods so they can be run independently as required :::note Note that JMeter currently runs the test methods directly, rather than leaving it to JUnit. This is to allow the `setUp`/`tearDown` methods to be excluded from the sample time. As a consequence, the sampler time excludes the time taken to call `setUp`/`tearDown` methods and their annotation based alternatives. ::: ## Mail Reader Sampler ![Mail Reader Sampler](/images/screenshots/mailreader_sampler.png) The Mail Reader Sampler can read (and optionally delete) mail messages using POP3(S) or IMAP(S) protocols. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Server Type | Yes | The protocol used by the provider: e.g. `pop3`, `pop3s`, `imap`, `imaps`. or another string representing the server protocol. For example `file` for use with the read-only mail file provider. The actual provider names for POP3 and IMAP are `pop3` and `imap` | | Server | Yes | Hostname or IP address of the server. See below for use with `file` protocol. | | Port | No | Port to be used to connect to the server (optional) | | Username | No | User login name | | Password | No | User login password (N.B. this is stored unencrypted in the test plan) | | Folder | Yes, if using IMAP(S) | The IMAP(S) folder to use. See below for use with `file` protocol. | | Number of messages to retrieve | Yes | Set this to retrieve all or some messages | | Fetch headers only | Yes | If selected, only the message headers will be retrieved. | | Delete messages from the server | Yes | If set, messages will be deleted after retrieval | | Store the message using MIME | Yes | Whether to store the message as MIME. If so, then the entire raw message is stored in the Response Data; the headers are not stored as they are available in the data. If not, the message headers are stored as Response Headers. A few headers are stored (`Date`, `To`, `From`, `Subject`) in the body. | | Use no security features | No | Indicates that the connection to the server does not use any security protocol. | | Use SSL | No | Indicates that the connection to the server must use the SSL protocol. | | Use StartTLS | No | Indicates that the connection to the server should attempt to start the TLS protocol. | | Enforce StartTLS | No | If the server does not start the TLS protocol the connection will be terminated. | | Trust All Certificates | No | When selected it will accept all certificates independent of the CA. | | Use local truststore | No | When selected it will only accept certificates that are locally trusted. | | Local truststore | No | Path to file containing the trusted certificates. Relative paths are resolved against the current directory. Failing that, against the directory containing the test script (JMX file). | :::note You can pass mail related environment properties by adding to `user.properties` any of the properties described [here](https://javaee.github.io/javamail/docs/api/com/sun/mail/pop3/package-summary.html). ::: Messages are stored as subsamples of the main sampler. Multipart message parts are stored as subsamples of the message. **Special handling for "`file`" protocol:** The `file` JavaMail provider can be used to read raw messages from files. The `server` field is used to specify the path to the parent of the `folder`. Individual message files should be stored with the name `n.msg`, where `n` is the message number. Alternatively, the `server` field can be the name of a file which contains a single message. The current implementation is quite basic, and is mainly intended for debugging purposes. ## Flow Control Action _(formerly Test Action)_ ![Flow Control Action](/images/screenshots/test_action.png) The Flow Control Action sampler is a sampler that is intended for use in a conditional controller. Rather than generate a sample, the test element either pauses or stops the selected target. This sampler can also be useful in conjunction with the Transaction Controller, as it allows pauses to be included without needing to generate a sample. For variable delays, set the pause time to zero, and add a Timer as a child. The "`Stop`" action stops the thread or test after completing any samples that are in progress. The "`Stop Now`" action stops the test without waiting for samples to complete; it will interrupt any active samples. If some threads fail to stop within the 5 second time-limit, a message will be displayed in GUI mode. You can try using the `Stop` command to see if this will stop the threads, but if not, you should exit JMeter. In CLI mode, JMeter will exit if some threads fail to stop within the 5 second time limit. :::note The time to wait can be changed using the JMeter property `jmeterengine.threadstop.wait`. The time is given in milliseconds. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Target | Yes | `Current Thread` / `All Threads` (ignored for `Pause` and `Go to next loop iteration`) | | Action | Yes | `Pause` / `Stop` / `Stop Now` / `Go to next loop iteration` | | Duration | Yes, if Pause is selected | How long to pause for (milliseconds) | ## SMTP Sampler ![SMTP Sampler](/images/screenshots/smtp_sampler.png) The SMTP Sampler can send mail messages using SMTP/SMTPS protocol. It is possible to set security protocols for the connection (SSL and TLS), as well as user authentication. If a security protocol is used a verification on the server certificate will occur. Two alternatives to handle this verification are available: **`Trust all certificates`** : This will ignore certificate chain verification **`Use a local truststore`** : With this option the certificate chain will be validated against the local truststore file. | Name | Required | Description | |------|----------|-------------| | Server | Yes | Hostname or IP address of the server. See below for use with `file` protocol. | | Port | No | Port to be used to connect to the server. Defaults are: SMTP=25, SSL=465, StartTLS=587 | | Connection timeout | No | Connection timeout value in milliseconds (socket level). Default is infinite timeout. | | Read timeout | No | Read timeout value in milliseconds (socket level). Default is infinite timeout. | | Address From | Yes | The from address that will appear in the e-mail | | Address To | Yes, unless CC or BCC is specified | The destination e-mail address (multiple values separated by "`;`") | | Address To CC | No | Carbon copy destinations e-mail address (multiple values separated by "`;`") | | Address To BCC | No | Blind carbon copy destinations e-mail address (multiple values separated by "`;`") | | Address Reply-To | No | Alternate Reply-To address (multiple values separated by "`;`") | | Use Auth | No | Indicates if the SMTP server requires user authentication | | Username | No | User login name | | Password | No | User login password (N.B. this is stored unencrypted in the test plan) | | Use no security features | No | Indicates that the connection to the SMTP server does not use any security protocol. | | Use SSL | No | Indicates that the connection to the SMTP server must use the SSL protocol. | | Use StartTLS | No | Indicates that the connection to the SMTP server should attempt to start the TLS protocol. | | Enforce StartTLS | No | If the server does not start the TLS protocol the connection will be terminated. | | Trust All Certificates | No | When selected it will accept all certificates independent of the CA. | | Use local truststore | No | When selected it will only accept certificates that are locally trusted. | | Local truststore | No | Path to file containing the trusted certificates. Relative paths are resolved against the current directory. Failing that, against the directory containing the test script (JMX file). | | Override System SSL/TLS Protocols | No | Specify a custom SSL/TLS protocol as space separated list to use on handshake example `TLSv1 TLSv1.1 TLSv1.2`. Defaults to all supported protocols. | | Subject | No | The e-mail message subject. | | Suppress Subject Header | No | If selected, the "`Subject:`" header is omitted from the mail that is sent. This is different from sending an empty "`Subject:`" header, though some e-mail clients may display it identically. | | Include timestamp in subject | No | Includes the `System.currentTimemillis()` in the subject line. | | Add Header | No | Additional headers can be defined using this button. | | Message | No | The message body. | | Send plain body (i.e. not multipart/mixed) | No | If selected, then send the body as a plain message, i.e. not `multipart/mixed`, if possible. If the message body is empty and there is a single file, then send the file contents as the message body. :::note Note: If the message body is not empty, and there is at least one attached file, then the body is sent as `multipart/mixed`. ::: | | Attach files | No | Files to be attached to the message. | | Send .eml | No | If set, the `.eml` file will be sent instead of the entries in the `Subject`, `Message`, and `Attach file(s)` fields | | Calculate message size | No | Calculates the message size and stores it in the sample result. | | Enable debug logging | No | If set, then the "`mail.debug`" property is set to "`true`" | ## OS Process Sampler ![OS Process Sampler](/images/screenshots/os_process_sampler.png) The OS Process Sampler is a sampler that can be used to execute commands on the local machine. It should allow execution of any command that can be run from the command line. Validation of the return code can be enabled, and the expected return code can be specified. Note that OS shells generally provide command-line parsing. This varies between OSes, but generally the shell will split parameters on white-space. Some shells expand wild-card file names; some don't. The quoting mechanism also varies between OSes. The sampler deliberately does not do any parsing or quote handling. The command and its parameters must be provided in the form expected by the executable. This means that the sampler settings will not be portable between OSes. Many OSes have some built-in commands which are not provided as separate executables. For example the Windows `DIR` command is part of the command interpreter (`CMD.EXE`). These built-ins cannot be run as independent programs, but have to be provided as arguments to the appropriate command interpreter. For example, the Windows command-line: `DIR C:\TEMP` needs to be specified as follows: **Command:** : `CMD` **Param 1:** : `/C` **Param 2:** : `DIR` **Param 3:** : `C:\TEMP` | Name | Required | Description | |------|----------|-------------| | Command | Yes | The program name to execute. | | Working directory | No | Directory from which command will be executed, defaults to folder referenced by "`user.dir`" System property | | Command Parameters | No | Parameters passed to the program name. | | Environment Parameters | No | Key/Value pairs added to environment when running command. | | Standard input (stdin) | No | Name of file from which input is to be taken (`STDIN`). | | Standard output (stdout | No | Name of output file for standard output (`STDOUT`). If omitted, output is captured and returned as the response data. | | Standard error (stderr) | No | Name of output file for standard error (`STDERR`). If omitted, output is captured and returned as the response data. | | Check Return Code | No | If checked, sampler will compare return code with `Expected Return Code`. | | Expected Return Code | No | Expected return code for System Call, required if "`Check Return Code`" is checked. Note 500 is used as an error indicator in JMeter so you should not use it. | | Timeout | No | Timeout for command in milliseconds, defaults to `0`, which means _no_ timeout. If the timeout expires before the command finishes, JMeter will attempt to kill the OS process. | [^](#) ## Bolt Request ![Bolt Request](/images/screenshots/bolt-request.png) This sampler allows you to run Cypher queries through the Bolt protocol. Before using this you need to set up a [Bolt Connection Configuration](/user-manual/component-reference/#Bolt_Connection_Configuration) Every request uses a connection acquired from the pool and returns it to the pool when the sampler completes. The connection pool size defaults to 100 and is configurable. The measured response time corresponds to the "full" query execution, including both the time to execute the cypher query AND the time to consume the results sent back by the database. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Comments | No | Free text for additional details. | | Cypher statement | Yes | The query to execute. | | Params | No | The parameter values, JSON formatted. | | Record Query Results | No | Whether to add or not query result data to the sampler response (default false). Note that activating this has a memory overhead, use it wisely. | | Access Mode | Yes | Whether to access the database in WRITE or READ mode. Use WRITE for a standalone Neo4j instance. For a Neo4j cluster, select mode depending on whether the query writes to the database. That setting will allow correct routing to the cluster leader, followers or read replicas. | | Database | No | The database to run the query against. Required for Neo4j 4.0+, unless querying the default database. Must be undefined for Neo4j 3.5. | | Transaction timeout | No | Timeout for the transaction. | :::note It is strongly advised to use query parameters, allowing the database to cache and reuse execution plans. ::: [^](#) ## 18.2 Logic Controllers ## Simple Controller ![Simple Controller](/images/screenshots/logic-controller/simple-controller.png) The Simple Logic Controller lets you organize your Samplers and other Logic Controllers. Unlike other Logic Controllers, this controller provides no functionality beyond that of a storage device. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | #### Using the Simple Controller [Download](../demos/SimpleTestPlan.jmx) this example (see Figure 6). In this example, we created a Test Plan that sends two Ant HTTP requests and two Log4J HTTP requests. We grouped the Ant and Log4J requests by placing them inside Simple Logic Controllers. Remember, the Simple Logic Controller has no effect on how JMeter processes the controller(s) you add to it. So, in this example, JMeter sends the requests in the following order: Ant Home Page, Ant News Page, Log4J Home Page, Log4J History Page. Note, the File Reporter is configured to store the results in a file named "`simple-test.dat`" in the current directory. ![Figure 6 Simple Controller Example](/images/screenshots/logic-controller/simple-example.png) _Figure 6 Simple Controller Example_ ## Loop Controller ![Loop Controller](/images/screenshots/logic-controller/loop-controller.png) If you add Generative or Logic Controllers to a Loop Controller, JMeter will loop through them a certain number of times, in addition to the loop value you specified for the Thread Group. For example, if you add one HTTP Request to a Loop Controller with a loop count of two, and configure the Thread Group loop count to three, JMeter will send a total of `2 * 3 = 6` HTTP Requests. :::note JMeter will expose the looping index as a variable named `__jm__<Name of your element>__idx`. So for example, if your Loop Controller is named LC, then you can access the looping index through `\${__jm__LC__idx}`. Index starts at 0 ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Loop Count | Yes, unless "Forever" is checked | The number of times the subelements of this controller will be iterated each time through a test run. The value `-1` is equivalent to checking the `Forever` toggle. **Special Case:** The Loop Controller embedded in the [Thread Group](/user-manual/test-plan/#thread_group) element behaves slightly different. Unless set to forever, it stops the test after the given number of iterations have been done. :::note When using a function in this field, be aware it may be evaluated multiple times. Example using `[__Random](/user-manual/functions/#__Random)` will evaluate it to a different value for each child samplers of Loop Controller and result into unwanted behaviour. ::: | #### Looping Example [Download](../demos/LoopTestPlan.jmx) this example (see Figure 4). In this example, we created a Test Plan that sends a particular HTTP Request only once and sends another HTTP Request five times. ![Figure 4 - Loop Controller Example](/images/screenshots/logic-controller/loop-example.png) _Figure 4 - Loop Controller Example_ We configured the Thread Group for a single thread and a loop count value of one. Instead of letting the Thread Group control the looping, we used a Loop Controller. You can see that we added one HTTP Request to the Thread Group and another HTTP Request to a Loop Controller. We configured the Loop Controller with a loop count value of five. JMeter will send the requests in the following order: Home Page, News Page, News Page, News Page, News Page, and News Page. :::note Note, the File Reporter is configured to store the results in a file named "`loop-test.dat`" in the current directory. ::: ## Once Only Controller ![Once Only Controller](/images/screenshots/logic-controller/once-only-controller.png) The Once Only Logic Controller tells JMeter to process the controller(s) inside it only once per Thread, and pass over any requests under it during further iterations through the test plan. The Once Only Controller will now execute always during the first iteration of any looping parent controller. Thus, if the Once Only Controller is placed under a Loop Controller specified to loop 5 times, then the Once Only Controller will execute only on the first iteration through the Loop Controller (i.e. every 5 times). Note this means the Once Only Controller will still behave as previously expected if put under a Thread Group (runs only once per test per Thread), but now the user has more flexibility in the use of the Once Only Controller. For testing that requires a login, consider placing the login request in this controller since each thread only needs to login once to establish a session. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | #### Once Only Example [Download](../demos/OnceOnlyTestPlan.jmx) this example (see Figure 5). In this example, we created a Test Plan that has two threads that send HTTP request. Each thread sends one request to the Home Page, followed by three requests to the Bug Page. Although we configured the Thread Group to iterate three times, each JMeter thread only sends one request to the Home Page because this request lives inside a Once Only Controller. ![Figure 5. Once Only Controller Example](/images/screenshots/logic-controller/once-only-example.png) _Figure 5. Once Only Controller Example_ Each JMeter thread will send the requests in the following order: Home Page, Bug Page, Bug Page, Bug Page. Note, the File Reporter is configured to store the results in a file named "`loop-test.dat`" in the current directory. ## Interleave Controller ![Interleave Controller](/images/screenshots/logic-controller/interleave-controller.png) If you add Generative or Logic Controllers to an Interleave Controller, JMeter will alternate among each of the other controllers for each loop iteration. | Name | Required | Description | |------|----------|-------------| | name | No | Descriptive name for this controller that is shown in the tree. | | ignore sub-controller blocks | No | If checked, the interleave controller will treat sub-controllers like single request elements and only allow one request per controller at a time. | | Interleave across threads | No | If checked, the interleave controller will alternate among each of its children controllers for each loop iteration but across all threads, for example in a configuration with 4 threads and 3 child controllers, on first iteration thread 1 will run first child, thread 2 second child, thread 3 third child, thread 4 first child, on next iteration each thread will run the following child controller | #### Simple Interleave Example [Download](../demos/InterleaveTestPlan.jmx) this example (see Figure 1). In this example, we configured the Thread Group to have two threads and a loop count of five, for a total of ten requests per thread. See the table below for the sequence JMeter sends the HTTP Requests. ![Figure 1 - Interleave Controller Example 1](/images/screenshots/logic-controller/interleave.png) _Figure 1 - Interleave Controller Example 1_ | | | | --- | --- | | 1 | News Page | | 1 | Log Page | | 2 | FAQ Page | | 2 | Log Page | | 3 | Gump Page | | 3 | Log Page | | 4 | Because there are no more requests in the controller, JMeter starts over and sends the first HTTP Request, which is the News Page. | | 4 | Log Page | | 5 | FAQ Page | | 5 | Log Page | #### Useful Interleave Example [Download](../demos/InterleaveTestPlan2.jmx) another example (see Figure 2). In this example, we configured the Thread Group to have a single thread and a loop count of eight. Notice that the Test Plan has an outer Interleave Controller with two Interleave Controllers inside of it. ![Figure 2 - Interleave Controller Example 2](/images/screenshots/logic-controller/interleave2.png) _Figure 2 - Interleave Controller Example 2_ The outer Interleave Controller alternates between the two inner ones. Then, each inner Interleave Controller alternates between each of the HTTP Requests. Each JMeter thread will send the requests in the following order: Home Page, Interleaved, Bug Page, Interleaved, CVS Page, Interleaved, and FAQ Page, Interleaved. Note, the File Reporter is configured to store the results in a file named "`interleave-test2.dat`" in the current directory. ![Figure 3 - Interleave Controller Example 3](/images/screenshots/logic-controller/interleave3.png) _Figure 3 - Interleave Controller Example 3_ If the two interleave controllers under the main interleave controller were instead simple controllers, then the order would be: Home Page, CVS Page, Interleaved, Bug Page, FAQ Page, Interleaved. However, if "`ignore sub-controller blocks`" was checked on the main interleave controller, then the order would be: Home Page, Interleaved, Bug Page, Interleaved, CVS Page, Interleaved, and FAQ Page, Interleaved. ## Random Controller ![Random Controller](/images/screenshots/logic-controller/random-controller.png) The Random Logic Controller acts similarly to the Interleave Controller, except that instead of going in order through its sub-controllers and samplers, it picks one at random at each pass. :::note Interactions between multiple controllers can yield complex behavior. This is particularly true of the Random Controller. Experiment before you assume what results any given interaction will give ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | ignore sub-controller blocks | No | If checked, the interleave controller will treat sub-controllers like single request elements and only allow one request per controller at a time. | ## Random Order Controller ![Random Order Controller](/images/screenshots/randomordercontroller.png) The Random Order Controller is much like a Simple Controller in that it will execute each child element at most once, but the order of execution of the nodes will be random. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | ## Throughput Controller ![Throughput Controller](/images/screenshots/throughput_controller.png) The Throughput Controller allows the user to control how often it is executed. There are two modes: - percent execution - total executions **`Percent executions`** : causes the controller to execute a certain percentage of the iterations through the test plan. **`Total executions`** : causes the controller to stop executing after a certain number of executions have occurred. Like the Once Only Controller, this setting is reset when a parent Loop Controller restarts. :::note This controller is badly named, as it does not control throughput. Please refer to the [Constant Throughput Timer](/user-manual/component-reference/#Constant_Throughput_Timer) for an element that can be used to adjust the throughput. ::: :::note The Throughput Controller can yield very complex behavior when combined with other controllers - in particular with interleave or random controllers as parents (also very useful). ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Execution Style | Yes | Whether the controller will run in percent executions or total executions mode. | | Throughput | Yes | A number. For percent execution mode, a number from `0`-`100` that indicates the percentage of times the controller will execute. "`50`" means the controller will execute during half the iterations through the test plan. For total execution mode, the number indicates the total number of times the controller will execute. | | Per User | No | If checked, per user will cause the controller to calculate whether it should execute on a per user (per thread) basis. If unchecked, then the calculation will be global for all users. For example, if using total execution mode, and uncheck "`per user`", then the number given for throughput will be the total number of executions made. If "`per user`" is checked, then the total number of executions would be the number of users times the number given for throughput. | ## Runtime Controller ![Runtime Controller](/images/screenshots/runtimecontroller.png) The Runtime Controller controls how long its children will run. Controller will run its children until configured `Runtime(s)` is exceeded. | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this controller that is shown in the tree, and used to name the transaction. | | Runtime (seconds) | Yes | Desired runtime in seconds. 0 means no run. | ## If Controller ![If Controller](/images/screenshots/if_controller_expression.png) The If Controller allows the user to control whether the test elements below it (its children) are run or not. By default, the condition is evaluated only once on initial entry, but you have the option to have it evaluated for every runnable element contained in the controller. The best option (default one) is to check `Interpret Condition as Variable Expression`, then in the condition field you have 2 options: - Option 1: Use a variable that contains `true` or `false` :::note If you want to test if last sample was successful, you can use `\${JMeterThread.last_sample_ok}` ![If Controller using Variable](/images/screenshots/if_controller_variable.png) _If Controller using Variable_ ::: - Option 2: Use a function (`\${__jexl3()}` is advised) to evaluate an expression that must return `true` or `false` ![If Controller using expression](/images/screenshots/if_controller_expression.png) _If Controller using expression_ For example, previously one could use the condition: `\${__jexl3(\${VAR} == 23)}` and this would be evaluated as `true`/`false`, the result would then be passed to JavaScript which would then return `true`/`false`. If the Variable Expression option is selected, then the expression is evaluated and compared with "`true`", without needing to use JavaScript. :::note To test if a variable is undefined (or null) do the following, suppose var is named `myVar`, expression will be: ``` "\${myVar}" == "\\${myVar}" ``` Or use: ``` "\${myVar}" != "\\${myVar}" ``` to test if a variable is defined and is not null. ::: If you uncheck `Interpret Condition as Variable Expression`, `If Controller` will internally use javascript to evaluate the condition which has a performance penalty that can be very big and make your test less scalable. ![If Controller using javascript](/images/screenshots/if_controller_javascript.png) _If Controller using javascript_ | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Condition (default JavaScript) | Yes | By default the condition is interpreted as **JavaScript** code that returns "`true`" or "`false`", but this can be overridden (see below) | | Interpret Condition as Variable Expression | Yes | If this is selected, then the condition must be an expression that evaluates to "`true`" (case is ignored). For example, `\${FOUND}` or `\${__jexl3(\${VAR} > 100)}`. Unlike the JavaScript case, the condition is only checked to see if it matches "`true`" (case is ignored). :::note Checking this and using `[__jexl3](/user-manual/functions/#__jexl3)` or `[__groovy](/user-manual/functions/#__groovy)` function in Condition is advised for performances ::: | | Evaluate for all children | Yes | Should condition be evaluated for all children? If not checked, then the condition is only evaluated on entry. | #### Examples (JavaScript) - `\${COUNT} < 10` - `"\${VAR}" == "abcd"` If there is an error interpreting the code, the condition is assumed to be `false`, and a message is logged in `jmeter.log`. :::note Note it is advised to avoid using JavaScript mode for performance. When using `[__groovy](/user-manual/functions/#__groovy)` take care to not use variable replacement in the string, otherwise if using a variable that changes the script cannot be cached. Instead get the variable using: `vars.get("myVar").` See the Groovy examples below. ::: #### Examples (Variable Expression) - `\${__groovy(vars.get("myVar") != "Invalid" )}` (Groovy check myVar is not equal to Invalid) - `\${__groovy(vars.get("myInt").toInteger() <=4 )}` (Groovy check myInt is less then or equal to 4) - `\${__groovy(vars.get("myMissing") != null )}` (Groovy check if the myMissing variable is not set) - `\${__jexl3(\${COUNT} < 10)}` - `\${RESULT}` - `\${JMeterThread.last_sample_ok}` (check if the last sample succeeded) ## While Controller ![While Controller](/images/screenshots/whilecontroller.png) The While Controller runs its children until the condition is "`false`". :::note JMeter will expose the looping index as a variable named `__jm__<Name of your element>__idx`. So for example, if your While Controller is named WC, then you can access the looping index through `\${__jm__WC__idx}`. Index starts at 0 ::: Possible condition values: - blank - exit loop when last sample in loop fails - `LAST` - exit loop when last sample in loop fails. If the last sample just before the loop failed, don't enter loop. - Otherwise - exit (or don't enter) the loop when the condition is equal to the string "`false`" :::note The condition can be any variable or function that eventually evaluates to the string "`false`". This allows the use of `[__jexl3](/user-manual/functions/#__jexl3)`, `[__groovy](/user-manual/functions/#__groovy)` function, properties or variables as needed. ::: :::note Note that the condition is evaluated twice, once before starting sampling children and once at end of children sampling, so putting non idempotent functions in Condition (like `[__counter](/user-manual/functions/#__counter)`) can introduce issues. ::: For example: - `\${VAR}` - where `VAR` is set to false by some other test element - `\${__jexl3(\${C}==10)}` - `\${__jexl3("\${VAR2}"=="abcd")}` - `\${_P(property)}` - where property is set to "`false`" somewhere else | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree, and used to name the transaction. | | Condition | No | blank, `LAST`, or variable/function | ## Switch Controller ![Switch Controller](/images/screenshots/switchcontroller.png) The Switch Controller acts like the [Interleave Controller](/user-manual/component-reference/#Interleave_Controller) in that it runs one of the subordinate elements on each iteration, but rather than run them in sequence, the controller runs the element defined by the switch value. :::note The switch value can also be a name. ::: If the switch value is out of range, it will run the zeroth element, which therefore acts as the default for the numeric case. It also runs the zeroth element if the value is the empty string. If the value is non-numeric (and non-empty), then the Switch Controller looks for the element with the same name (case is significant). If none of the names match, then the element named "`default`" (case not significant) is selected. If there is no default, then no element is selected, and the controller will not run anything. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Switch Value | No | The number (or name) of the subordinate element to be invoked. Elements are numbered from 0. Defaults to 0 | ## ForEach Controller ![ForEach Controller](/images/screenshots/logic-controller/foreach-controller.png) A ForEach controller loops through the values of a set of related variables. When you add samplers (or controllers) to a ForEach controller, every sample (or controller) is executed one or more times, where during every loop the variable has a new value. The input should consist of several variables, each extended with an underscore and a number. Each such variable must have a value. So for example when the input variable has the name `inputVar`, the following variables should have been defined: - `inputVar_1 = wendy` - `inputVar_2 = charles` - `inputVar_3 = peter` - `inputVar_4 = john` Note: the "`_`" separator is now optional. When the return variable is given as "`returnVar`", the collection of samplers and controllers under the ForEach controller will be executed `4` consecutive times, with the return variable having the respective above values, which can then be used in the samplers. :::note JMeter will expose the looping index as a variable named `__jm__<Name of your element>__idx`. So for example, if your Loop Controller is named FEC, then you can access the looping index through `\${__jm__FEC__idx}`. Index starts at 0 ::: It is especially suited for running with the regular expression post-processor. This can "create" the necessary input variables out of the result data of a previous request. By omitting the "`_`" separator, the ForEach Controller can be used to loop through the groups by using the input variable `refName_g`, and can also loop through all the groups in all the matches by using an input variable of the form `refName_\${C}_g`, where `C` is a counter variable. :::note The ForEach Controller does not run any samples if `inputVar_1` is `null`. This would be the case if the Regular Expression returned no matches. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Input variable prefix | No | Prefix for the variable names to be used as input. Defaults to an empty string as prefix. | | Start index for loop | No | Start index (exclusive) for loop over variables (first element is at start index + 1) | | End index for loop | No | End index (inclusive) for loop over variables | | Output variable | No | The name of the variable which can be used in the loop for replacement in the samplers. Defaults to an empty variable name, which is most probably not wanted. | | Use Separator | Yes | If not checked, the "`_`" separator is omitted. | #### ForEach Example [Download](../demos/forEachTestPlan.jmx) this example (see Figure 7). In this example, we created a Test Plan that sends a particular HTTP Request only once and sends another HTTP Request to every link that can be found on the page. ![Figure 7 - ForEach Controller Example](/images/screenshots/logic-controller/foreach-example.png) _Figure 7 - ForEach Controller Example_ We configured the Thread Group for a single thread and a loop count value of one. You can see that we added one HTTP Request to the Thread Group and another HTTP Request to the ForEach Controller. After the first HTTP request, a regular expression extractor is added, which extracts all the html links out of the return page and puts them in the `inputVar` variable In the ForEach loop, a HTTP sampler is added which requests all the links that were extracted from the first returned HTML page. #### ForEach Example Here is [another example](../demos/ForEachTest2.jmx) you can download. This has two Regular Expressions and ForEach Controllers. The first RE matches, but the second does not match, so no samples are run by the second ForEach Controller ![Figure 8 - ForEach Controller Example 2](/images/screenshots/logic-controller/foreach-example2.png) _Figure 8 - ForEach Controller Example 2_ The Thread Group has a single thread and a loop count of two. Sample 1 uses the JavaTest Sampler to return the string "`a b c d`". The Regex Extractor uses the expression `(\w)\s` which matches a letter followed by a space, and returns the letter (not the space). Any matches are prefixed with the string "`inputVar`". The ForEach Controller extracts all variables with the prefix "`inputVar_`", and executes its sample, passing the value in the variable "`returnVar`". In this case it will set the variable to the values "`a`" "`b`" and "`c`" in turn. The `For 1` Sampler is another Java Sampler which uses the return variable "`returnVar`" as part of the sample Label and as the sampler Data. `Sample 2`, `Regex 2` and `For 2` are almost identical, except that the Regex has been changed to "`(\w)\sx`", which clearly won't match. Thus the `For 2` Sampler will not be run. ## Module Controller ![Module Controller](/images/screenshots/module_controller.png) The Module Controller provides a mechanism for substituting test plan fragments into the current test plan at run-time. A test plan fragment consists of a Controller and all the test elements (samplers etc.) contained in it. The fragment can be located in any Thread Group. If the fragment is located in a Thread Group, then its Controller can be disabled to prevent the fragment being run except by the Module Controller. Or you can store the fragments in a dummy Thread Group, and disable the entire Thread Group. There can be multiple fragments, each with a different series of samplers under them. The module controller can then be used to easily switch between these multiple test cases simply by choosing the appropriate controller in its drop down box. This provides convenience for running many alternate test plans quickly and easily. A fragment name is made up of the Controller name and all its parent names. For example: ``` Test Plan / Protocol: JDBC / Control / Interleave Controller (Module1) ``` Any **fragments used by the Module Controller must have a unique name**, as the name is used to find the target controller when a test plan is reloaded. For this reason it is best to ensure that the Controller name is changed from the default - as shown in the example above - otherwise a duplicate may be accidentally created when new elements are added to the test plan. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | | Module to Run | Yes | The module controller provides a list of all controllers loaded into the gui. Select the one you want to substitute in at runtime. | ## Include Controller ![Include Controller](/images/screenshots/includecontroller.png) The include controller is designed to use an external JMX file. To use it, create a Test Fragment underneath the Test Plan and add any desired samplers, controllers etc. below it. Then save the Test Plan. The file is now ready to be included as part of other Test Plans. For convenience, a [Thread Group](/user-manual/component-reference/#Thread_Group) can also be added in the external JMX file for debugging purposes. A [Module Controller](/user-manual/component-reference/#Module_Controller) can be used to reference the Test Fragment. The [Thread Group](/user-manual/component-reference/#Thread_Group) will be ignored during the include process. If the test uses a Cookie Manager or User Defined Variables, these should be placed in the top-level test plan, not the included file, otherwise they are not guaranteed to work. :::note This element does not support variables/functions in the filename field. However, if the property `includecontroller.prefix` is defined, the contents are used to prefix the pathname. ::: :::note When using Include Controller and including the same JMX file, ensure you name the Include Controller differently to avoid facing known issue [Bug 50898](https://bz.apache.org/bugzilla/show_bug.cgi?id=50898). ::: If the file cannot be found at the location given by `prefix`+`Filename`, then the controller attempts to open the `Filename` relative to the JMX launch directory. | Name | Required | Description | |------|----------|-------------| | Filename | Yes | The file to include. | ## Transaction Controller ![Transaction Controller](/images/screenshots/transactioncontroller.png) The Transaction Controller generates an additional sample which measures the overall time taken to perform the nested test elements. :::note Note: when the check box "`Include duration of timer and pre-post processors in generated sample`" is checked, the time includes all processing within the controller scope, not just the samples. ::: There are two modes of operation: - additional sample is added after the nested samples - additional sample is added as a parent of the nested samples The generated sample time includes all the times for the nested samplers excluding by default (since 2.11) timers and processing time of pre/post processors unless checkbox "`Include duration of timer and pre-post processors in generated sample`" is checked. Depending on the clock resolution, it may be slightly longer than the sum of the individual samplers plus timers. The clock might tick after the controller recorded the start time but before the first sample starts. Similarly at the end. The generated sample is only regarded as successful if all its sub-samples are successful. In parent mode, the individual samples can still be seen in the Tree View Listener, but no longer appear as separate entries in other Listeners. Also, the sub-samples do not appear in CSV log files, but they can be saved to XML files. :::note In parent mode, Assertions (etc.) can be added to the Transaction Controller. However by default they will be applied to both the individual samples and the overall transaction sample. To limit the scope of the Assertions, use a Simple Controller to contain the samples, and add the Assertions to the Simple Controller. Parent mode controllers do not currently properly support nested transaction controllers of either type. ::: | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this controller that is shown in the tree, and used to name the transaction. | | Generate Parent Sample | Yes | If checked, then the sample is generated as a parent of the other samples, otherwise the sample is generated as an independent sample. | | Include duration of timer and pre-post processors in generated sample | Yes | Whether to include timer, pre- and post-processing delays in the generated sample. Default is `false` | ## Recording Controller ![Recording Controller](/images/screenshots/logic-controller/recording-controller.png) The Recording Controller is a place holder indicating where the proxy server should record samples to. During test run, it has no effect, similar to the Simple Controller. But during recording using the [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder), all recorded samples will by default be saved under the Recording Controller. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this controller that is shown in the tree. | ## Critical Section Controller ![Critical Section Controller](/images/screenshots/logic-controller/critical-section-controller.png) The Critical Section Controller ensures that its children elements (samplers/controllers, etc.) will be executed by only one thread as a named lock will be taken before executing children of controller. The figure below shows an example of using Critical Section Controller, in the figure below 2 Critical Section Controllers ensure that: - `DS2-\${__threadNum}` is executed only by one thread at a time - `DS4-\${__threadNum}` is executed only by one thread at a time ![Test Plan using Critical Section Controller](/images/screenshots/logic-controller/critical-section-controller-tp.png) _Test Plan using Critical Section Controller_ | Name | Required | Description | |------|----------|-------------| | Lock Name | Yes | Lock that will be taken by controller, ensure you use different lock names for unrelated sections | :::note Critical Section Controller takes locks only within one JVM, so if using Distributed testing ensure your use case does not rely on all threads of all JVMs blocking. ::: [^](#) ## 18.3 Listeners Most of the listeners perform several roles in addition to "listening" to the test results. They also provide means to view, save, and read saved test results. Note that Listeners are processed at the end of the scope in which they are found. The saving and reading of test results is generic. The various listeners have a panel whereby one can specify the file to which the results will be written (or read from). By default, the results are stored as XML files, typically with a "`.jtl`" extension. Storing as CSV is the most efficient option, but is less detailed than XML (the other available option). Listeners do _not_ process sample data in CLI mode, but the raw data will be saved if an output file has been configured. In order to analyse the data generated by a CLI run, you need to load the file into the appropriate Listener. :::note To read existing results and display them, use the file panel Browse button to open the file. ::: If you want to clear any current data before loading a new file, use the menu item **Run → Clear → (Ctrl+Shift+E)** or **Run → Clear All → (Ctrl+E)** before loading the file. Results can be read from XML or CSV format files. When reading from CSV results files, the header (if present) is used to determine which fields are present. **In order to interpret a header-less CSV file correctly, the appropriate properties must be set in `jmeter.properties`.** :::note XML files written by JMeter have version 1.0 declared in header while actual file is serialized with 1.1 rules. (This is done for historical compatibility reasons; see [Bug 59973](https://bz.apache.org/bugzilla/show_bug.cgi?id=59973) and [Bug 58679](https://bz.apache.org/bugzilla/show_bug.cgi?id=58679)) This causes strict XML parsers to fail. Consider using non-strict XML parsers to read JTL files. ::: :::note The file name can contain function and/or variable references. However variable references do not work in client-server mode (functions work OK). This is because the file is created on the client, and the client does not run the test locally so does not set up variables. ::: **Listeners can use a lot of memory if there are a lot of samples.** Most of the listeners currently keep a copy of every sample in their scope, apart from: - Simple Data Writer - BeanShell/JSR223 Listener - Mailer Visualizer - Summary Report The following Listeners no longer need to keep copies of every single sample. Instead, samples with the same elapsed time are aggregated. Less memory is now needed, especially if most samples only take a second or two at most. - Aggregate Report - Aggregate Graph To minimise the amount of memory needed, use the Simple Data Writer, and use the CSV format. :::note JMeter variables can be saved to the output files. This can only be specified using a property. See the [Listener Sample Variables](/user-manual/listeners/#sample_variables) for details ::: For full details on setting up the default items to be saved see the [Listener Default Configuration](/user-manual/listeners/#defaults) documentation. For details of the contents of the output files, see the [CSV log](/user-manual/listeners/#csvlogformat) format or the [XML log](/user-manual/listeners/#xmlformat2.1) format. :::note The entries in `jmeter.properties` are used to define the defaults; these can be overridden for individual listeners by using the Configure button, as shown below. The settings in `jmeter.properties` also apply to the listener that is added by using the `-l` command-line flag. ::: The figure below shows an example of the result file configuration panel ![Result file configuration panel](/images/screenshots/simpledatawriter.png) _Result file configuration panel_ | Name | Required | Description | |------|----------|-------------| | Filename | No | Name of the file containing sample results. The file name can be specified using either a relative or an absolute path name. Relative paths are resolved relative to the current working directory (which defaults to the `bin/` directory). JMeter also support paths relative to the directory containing the current test plan (JMX file). If the path name begins with "`~/`" (or whatever is in the `jmeter.save.saveservice.base_prefix` JMeter property), then the path is assumed to be relative to the JMX file location. | | Browse … | No | File Browse Button | | Errors | No | Select this to write/read only results with errors | | Successes | No | Select this to write/read only results without errors. If neither `Errors` nor `Successes` is selected, then all results are processed. | | Configure | No | Configure Button, see below | ## Sample Result Save Configuration ![Sample Result Save Configuration](/images/screenshots/sample_result_config.png) Listeners can be configured to save different items to the result log files (JTL) by using the Config popup as shown below. The defaults are defined as described in the [Listener Default Configuration](/user-manual/listeners/#defaults) documentation. Items with (`CSV`) after the name only apply to the CSV format; items with (`XML`) only apply to XML format. CSV format cannot currently be used to save any items that include line-breaks. Note that cookies, method and the query string are saved as part of the "`Sampler Data`" option. ## Graph Results ![Graph Results](/images/screenshots/graph_results.png) :::note Graph Results MUST NOT BE USED during load test as it consumes a lot of resources (memory and CPU). Use it only for either functional testing or during Test Plan debugging and Validation. ::: The Graph Results listener generates a simple graph that plots all sample times. Along the bottom of the graph, the current sample (black), the current average of all samples (blue), the current standard deviation (red), and the current throughput rate (green) are displayed in milliseconds. The throughput number represents the actual number of requests/minute the server handled. This calculation includes any delays you added to your test and JMeter's own internal processing time. The advantage of doing the calculation like this is that this number represents something real - your server in fact handled that many requests per minute, and you can increase the number of threads and/or decrease the delays to discover your server's maximum throughput. Whereas if you made calculations that factored out delays and JMeter's processing, it would be unclear what you could conclude from that number. The following table briefly describes the items on the graph. Further details on the precise meaning of the statistical terms can be found on the web - e.g. Wikipedia - or by consulting a book on statistics. - `Data` - plot the actual data values - `Average` - plot the Average - `Median` - plot the [Median](/user-manual/glossary/#Median) (midway value) - `Deviation` - plot the [Standard Deviation](/user-manual/glossary/#StandardDeviation) (a measure of the variation) - `Throughput` - plot the number of samples per unit of time The individual figures at the bottom of the display are the current values. "`Latest Sample`" is the current elapsed sample time, shown on the graph as "`Data`". The value displayed on the top left of graph is the max of 90th percentile of response time. ## Assertion Results ![Assertion Results](/images/screenshots/assertion_results.png) :::note Assertion Results MUST NOT BE USED during load test as it consumes a lot of resources (memory and CPU). Use it only for either functional testing or during Test Plan debugging and Validation. ::: The Assertion Results visualizer shows the Label of each sample taken. It also reports failures of any [Assertions](/user-manual/test-plan/#assertions) that are part of the test plan. ## View Results Tree ![View Results Tree](/images/screenshots/view_results_tree.png) :::note View Results Tree MUST NOT BE USED during load test as it consumes a lot of resources (memory and CPU). Use it only for either functional testing or during Test Plan debugging and Validation. ::: The View Results Tree shows a tree of all sample responses, allowing you to view the response for any sample. In addition to showing the response, you can see the time it took to get this response, and some response codes. Note that the Request panel only shows the headers added by JMeter. It does not show any headers (such as `Host`) that may be added by the HTTP protocol implementation. There are several ways to view the response, selectable by a drop-down box at the bottom of the left hand panel. | | | | --- | --- | | `CSS/JQuery Tester` | The _CSS/JQuery Tester_ only works for text responses. It shows the plain text in the upper panel. The "`Test`" button allows the user to apply the CSS/JQuery to the upper panel and the results will be displayed in the lower panel. The CSS/JQuery expression engine can be JSoup or Jodd, syntax of these 2 implementation differs slightly. For example, the Selector `a[class=sectionlink]` with attribute `href` applied to the current JMeter functions page gives the following output: ``` Match count: 74 Match[1]=#functions Match[2]=#what_can_do Match[3]=#where Match[4]=#how Match[5]=#function_helper Match[6]=#functions Match[7]=#__regexFunction Match[8]=#__regexFunction_parms Match[9]=#__counter … and so on … ``` | | `Document` | The _Document view_ will show the extract text from various type of documents like Microsoft Office (Word, Excel, PowerPoint 97-2003, 2007-2010 (openxml), Apache OpenOffice (writer, calc, impress), HTML, gzip, jar/zip files (list of content), and some meta-data on "multimedia" files like mp3, mp4, flv, etc. The complete list of support format is available on [Apache Tika format page.](http://tika.apache.org/1.2/formats.html) :::note A requirement to the `Document view` is to download the [Apache Tika binary package](http://tika.apache.org/download.html) (`tika-app-x.x.jar`) and put this in `JMETER_HOME/lib` directory. ::: If the document is larger than 10 MB, then it won't be displayed. To change this limit, set the JMeter property `document.max_size` (unit is byte) or set to `0` to remove the limit. | | `HTML` | The _HTML view_ attempts to render the response as HTML. The rendered HTML is likely to compare poorly to the view one would get in any web browser; however, it does provide a quick approximation that is helpful for initial result evaluation. Images, style-sheets, etc. aren't downloaded. | | `HTML (download resources)` | If the _HTML (download resources) view_ option is selected, the renderer may download images, style-sheets, etc. referenced by the HTML code. | | `HTML Source formatted` | If the _HTML Source formatted view_ option is selected, the renderer will display the HTML source code formatted and cleaned by [Jsoup](https://jsoup.org/). | | `JSON` | The _JSON view_ will show the response in tree style (also handles JSON embedded in JavaScript). | | `JSON Path Tester` | The _JSON Path Tester view_ will let you test your JSON-PATH expressions and see the extracted data from a particular response. | | `JSON JMESPath Tester` | The _JSON JMESPath Tester view_ will let you test your [JMESPath](http://jmespath.org/) expressions and see the extracted data from a particular response. | | `Regexp Tester` | The _Regexp Tester view_ only works for text responses. It shows the plain text in the upper panel. The "`Test`" button allows the user to apply the Regular Expression to the upper panel and the results will be displayed in the lower panel. The regular expression engine is the same as that used in the Regular Expression Extractor. For example, the RE `(JMeter\w*).*` applied to the current JMeter home page gives the following output: ``` Match count: 26 Match[1][0]=JMeter - Apache JMeter</title> Match[1][1]=JMeter Match[2][0]=JMeter" title="JMeter" border="0"/></a> Match[2][1]=JMeter Match[3][0]=JMeterCommitters">Contributors</a> Match[3][1]=JMeterCommitters … and so on … ``` The first number in `[]` is the match number; the second number is the group. Group `[0]` is whatever matched the whole RE. Group `[1]` is whatever matched the 1st group, i.e. `(JMeter\w*)` in this case. See Figure 9b (below). | | `Text` | The default _Text view_ shows all of the text contained in the response. Note that this will only work if the response `content-type` is considered to be text. If the `content-type` begins with any of the following, it is considered as binary, otherwise it is considered to be text. ``` image/ audio/ video/ ``` | | `XML` | The _XML view_ will show response in tree style. Any DTD nodes or Prolog nodes will not show up in tree; however, response may contain those nodes. You can right-click on any node and expand or collapse all nodes below it. | | `XPath Tester` | The _XPath Tester_ only works for text responses. It shows the plain text in the upper panel. The "`Test`" button allows the user to apply the XPath query to the upper panel and the results will be displayed in the lower panel. | | `Boundary Extractor Tester ` | The _Boundary Extractor Tester_ only works for text responses. It shows the plain text in the upper panel. The "`Test`" button allows the user to apply the Boundary Extractor query to the upper panel and the results will be displayed in the lower panel. | `Scroll automatically` option permit to have last node display in tree selection :::note Starting with version 3.2 the number of entries in the View is restricted to the value of the property `view.results.tree.max_results` which defaults to `500` entries. The old behaviour can be restored by setting the property to `0`. Beware, that this might consume a lot of memory. ::: With `Search` option, most of the views also allow the displayed data to be searched; the result of the search will be high-lighted in the display above. For example the Control panel screenshot below shows one result of searching for "`Java`". Note that the search operates on the visible text, so you may get different results when searching the Text and HTML views. Note: The regular expression uses the Java engine (not ORO engine like the Regular Expression Extractor or Regexp Tester view). If there is no `content-type` provided, then the content will not be displayed in the any of the Response Data panels. You can use [Save Responses to a file](/user-manual/component-reference/#Save_Responses_to_a_file) to save the data in this case. Note that the response data will still be available in the sample result, so can still be accessed using Post-Processors. If the response data is larger than 200K, then it won't be displayed. To change this limit, set the JMeter property `view.results.tree.max_size`. You can also use save the entire response to a file using [Save Responses to a file](/user-manual/component-reference/#Save_Responses_to_a_file). Additional renderers can be created. The class must implement the interface `org.apache.jmeter.visualizers.ResultRenderer` and/or extend the abstract class `org.apache.jmeter.visualizers.SamplerResultTab`, and the compiled code must be available to JMeter (e.g. by adding it to the `lib/ext` directory). The Control Panel (above) shows an example of an HTML display. Figure 9 (below) shows an example of an XML display. Figure 9a (below) shows an example of a Regexp tester display. Figure 9b (below) shows an example of a Document display. ![Figure 9 Sample XML display](/images/screenshots/view_results_tree_xml.png) _Figure 9 Sample XML display_ ![Figure 9a Sample Regexp Test display](/images/screenshots/view_results_tree_regex.png) _Figure 9a Sample Regexp Test display_ ![Figure 9b Sample Document (here PDF) display](/images/screenshots/view_results_tree_document.png) _Figure 9b Sample Document (here PDF) display_ ## Aggregate Report ![Aggregate Report](/images/screenshots/aggregate_report.png) The aggregate report creates a table row for each differently named request in your test. For each request, it totals the response information and provides request count, min, max, average, error rate, approximate throughput (request/second) and Kilobytes per second throughput. Once the test is done, the throughput is the actual through for the duration of the entire test. The throughput is calculated from the point of view of the sampler target (e.g. the remote server in the case of HTTP samples). JMeter takes into account the total time over which the requests have been generated. If other samplers and timers are in the same thread, these will increase the total time, and therefore reduce the throughput value. So two identical samplers with different names will have half the throughput of two samplers with the same name. It is important to choose the sampler names correctly to get the best results from the Aggregate Report. Calculation of the [Median](/user-manual/glossary/#Median) and 90 % Line (90th [percentile](/user-manual/glossary/#Percentile)) values requires additional memory. JMeter now combines samples with the same elapsed time, so far less memory is used. However, for samples that take more than a few seconds, the probability is that fewer samples will have identical times, in which case more memory will be needed. Note you can use this listener afterwards to reload a CSV or XML results file which is the recommended way to avoid performance impacts. See the [Summary Report](/user-manual/component-reference/#Summary_Report) for a similar Listener that does not store individual samples and so needs constant memory. :::note Starting with JMeter 2.12, you can configure the 3 percentile values you want to compute, this can be done by setting properties: - `aggregate_rpt_pct1`: defaults to 90th [percentile](/user-manual/glossary/#Percentile) - `aggregate_rpt_pct2`: defaults to 95th [percentile](/user-manual/glossary/#Percentile) - `aggregate_rpt_pct3`: defaults to 99th [percentile](/user-manual/glossary/#Percentile) ::: - `Label` - The label of the sample. If "`Include group name in label`" is selected, then the name of the thread group is added as a prefix. This allows identical labels from different thread groups to be collated separately if required. - `# Samples` - The number of samples with the same label - `Average` - The average time of a set of results - `Median` - The [median](/user-manual/glossary/#Median) is the time in the middle of a set of results. 50 % of the samples took no more than this time; the remainder took at least as long. - `90% Line` - 90 % of the samples took no more than this time. The remaining samples took at least as long as this. (90th [percentile](/user-manual/glossary/#Percentile)) - `95% Line` - 95 % of the samples took no more than this time. The remaining samples took at least as long as this. (95th [percentile](/user-manual/glossary/#Percentile)) - `99% Line` - 99 % of the samples took no more than this time. The remaining samples took at least as long as this. (99th [percentile](/user-manual/glossary/#Percentile)) - `Min` - The shortest time for the samples with the same label - Max - The longest time for the samples with the same label - `Error %` - Percent of requests with errors - `Throughput` - the [Throughput](/user-manual/glossary/#Throughput) is measured in requests per second/minute/hour. The time unit is chosen so that the displayed rate is at least 1.0. When the throughput is saved to a CSV file, it is expressed in requests/second, i.e. 30.0 requests/minute is saved as 0.5. - `Received KB/sec` - The throughput measured in received Kilobytes per second - `Sent KB/sec` - The throughput measured in sent Kilobytes per second Times are in milliseconds. The figure below shows an example of selecting the "`Include group name`" checkbox. ![Sample "`Include group name`" display](/images/screenshots/aggregate_report_grouped.png) _Sample "`Include group name`" display_ ## View Results in Table ![View Results in Table](/images/screenshots/table_results.png) This visualizer creates a row for every sample result. Like the [View Results Tree](/user-manual/component-reference/#View_Results_Tree), this visualizer uses a lot of memory. By default, it only displays the main (parent) samples; it does not display the sub-samples (child samples). JMeter has a "`Child Samples`" check-box. If this is selected, then the sub-samples are displayed instead of the main samples. ## Simple Data Writer ![Simple Data Writer](/images/screenshots/simpledatawriter.png) This listener can record results to a file but not to the UI. It is meant to provide an efficient means of recording data by eliminating GUI overhead. When running in CLI mode, the `-l` flag can be used to create a data file. The fields to save are defined by JMeter properties. See the `jmeter.properties` file for details. ## Aggregate Graph ![Aggregate Graph](/images/screenshots/aggregate_graph.png) The aggregate graph is similar to the aggregate report. The primary difference is the aggregate graph provides an easy way to generate bar graphs and save the graph as a PNG file. The figure below shows an example of settings to draw this graph. ![Aggregate graph settings](/images/screenshots/aggregate_graph_settings.png) _Aggregate graph settings_ :::note Please note: All this parameters _aren't_ saved in JMeter JMX script. ::: | Name | Required | Description | |------|----------|-------------| | Column settings | Yes | - `Columns to display:` Choose the column(s) to display in graph. - `Rectangles color:` Click on right color rectangle open a popup dialog to choose a custom color for column. - `Foreground color` Allow to change the value text color. - `Value font:` Allow to define font settings for the text. - `Draw outlines bar` To draw or not the border line on bar chart - `Show number grouping` Show or not the number grouping in Y Axis labels. - `Value labels vertical` Change orientation for value label. (Default is horizontal) - `Column label selection:` Filter by result label. A regular expression can be used, example: `.*Transaction.*` Before display the graph, click on `Apply filter` button to refresh internal data. | | Title | No | Define the graph's title on the head of chart. Empty value is the default value: "`Aggregate Graph`". The button `Synchronize with name` define the title with the label of the listener. And define font settings for graph title | | Graph size | No | Compute the graph size by the width and height depending of the current JMeter's window size. Use `Width` and `Height` fields to define a custom size. The unit is pixel. | | X Axis settings | No | Define the max length of X Axis label (in pixel). | | Y Axis settings | No | Define a custom maximum value for Y Axis. | | Legend | Yes | Define the placement and font settings for chart legend | ## Response Time Graph ![Response Time Graph](/images/screenshots/response_time_graph.png) The Response Time Graph draws a line chart showing the evolution of response time during the test, for each labelled request. If many samples exist for the same timestamp, the mean value is displayed. The figure below shows an example of settings to draw this graph. ![Response time graph settings](/images/screenshots/response_time_graph_settings.png) _Response time graph settings_ :::note Please note: All this parameters are saved in JMeter `.jmx` file. ::: | Name | Required | Description | |------|----------|-------------| | Interval (ms) | Yes | The time in milliseconds for X axis interval. Samples are grouped according to this value. Before display the graph, click on `Apply interval` button to refresh internal data. | | Sampler label selection | No | Filter by result label. A regular expression can be used, ex. `.*Transaction.*`. Before display the graph, click on `Apply filter` button to refresh internal data. | | Title | No | Define the graph's title on the head of chart. Empty value is the default value: "`Response Time Graph`". The button `Synchronize with name` define the title with the label of the listener. And define font settings for graph title | | Line settings | Yes | Define the width of the line. Define the type of each value point. Choose `none` to have a line without mark | | Graph size | No | Compute the graph size by the width and height depending of the current JMeter's window size. Use `Width` and `Height` fields to define a custom size. The unit is pixel. | | X Axis settings | No | Customize the date format of X axis label. The syntax is the Java [SimpleDateFormat API](http://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html). | | Y Axis settings | No | Define a custom maximum value for Y Axis in milli-seconds. Define the increment for the scale (in ms) Show or not the number grouping in Y Axis labels. | | Legend | Yes | Define the placement and font settings for chart legend | ## Mailer Visualizer ![Mailer Visualizer](/images/screenshots/mailervisualizer.png) The mailer visualizer can be set up to send email if a test run receives too many failed responses from the server. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | From | Yes | Email address to send messages from. | | Addressee(s) | Yes | Email address to send messages to, comma-separated. | | Success Subject | No | Email subject line for success messages. | | Success Limit | Yes | Once this number of successful responses is exceeded **after previously reaching the failure limit**, a success email is sent. The mailer will thus only send out messages in a sequence of failed-succeeded-failed-succeeded, etc. | | Failure Subject | No | Email subject line for fail messages. | | Failure Limit | Yes | Once this number of failed responses is exceeded, a failure email is sent - i.e. set the count to `0` to send an e-mail on the first failure. | | Host | No | IP address or host name of SMTP server (email redirector) server. | | Port | No | Port of SMTP server (defaults to `25`). | | Login | No | Login used to authenticate. | | Password | No | Password used to authenticate. | | Connection security | No | Type of encryption for SMTP authentication (SSL, TLS or none). | | Test Mail | No | Press this button to send a test mail | | Failures | No | A field that keeps a running total of number of failures so far received. | ## BeanShell Listener ![BeanShell Listener](/images/screenshots/beanshell_listener.png) The BeanShell Listener allows the use of BeanShell for processing samples for saving etc. **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 Listener](/user-manual/component-reference/#JSR223_Listener)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: The test element supports the `ThreadListener` and `TestListener` methods. These should be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. The name is stored in the script variable Label | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. The parameters are stored in the following variables: **`Parameters`** : string containing the parameters as a single variable **`bsh.args`** : String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. The file name is stored in the script variable `FileName` | | Script | Yes (unless script file is provided) | The BeanShell script to run. The return value is ignored. | Before invoking the script, some variables are set up in the BeanShell interpreter: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); ``` - `props` - (JMeterProperties - class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `sampleResult`, `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) - `sampleEvent` ([SampleEvent](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleEvent.html)) gives access to the current sample event For details of all the methods available on each of the above variables, please check the Javadoc If the property `beanshell.listener.init` is defined, this is used to load an initialisation file, which can be used to define methods etc. for use in the BeanShell script. ## Summary Report ![Summary Report](/images/screenshots/summary_report.png) The summary report creates a table row for each differently named request in your test. This is similar to the [Aggregate Report](/user-manual/component-reference/#Aggregate_Report) , except that it uses less memory. The throughput is calculated from the point of view of the sampler target (e.g. the remote server in the case of HTTP samples). JMeter takes into account the total time over which the requests have been generated. If other samplers and timers are in the same thread, these will increase the total time, and therefore reduce the throughput value. So two identical samplers with different names will have half the throughput of two samplers with the same name. It is important to choose the sampler labels correctly to get the best results from the Report. - `Label` - The label of the sample. If "`Include group name in label`" is selected, then the name of the thread group is added as a prefix. This allows identical labels from different thread groups to be collated separately if required. - `# Samples` - The number of samples with the same label - `Average` - The average elapsed time of a set of results - `Min` - The lowest elapsed time for the samples with the same label - `Max` - The longest elapsed time for the samples with the same label - `Std. Dev.` - the [Standard Deviation](/user-manual/glossary/#StandardDeviation) of the sample elapsed time - `Error %` - Percent of requests with errors - `Throughput` - the [Throughput](/user-manual/glossary/#Throughput) is measured in requests per second/minute/hour. The time unit is chosen so that the displayed rate is at least `1.0`. When the throughput is saved to a CSV file, it is expressed in requests/second, i.e. 30.0 requests/minute is saved as `0.5`. - `Received KB/sec` - The throughput measured in Kilobytes per second - `Sent KB/sec` - The throughput measured in Kilobytes per second - `Avg. Bytes` - average size of the sample response in bytes. Times are in milliseconds. The figure below shows an example of selecting the "`Include group name`" checkbox. ![Sample "`Include group name`" display](/images/screenshots/summary_report_grouped.png) _Sample "`Include group name`" display_ ## Save Responses to a file ![Save Responses to a file](/images/screenshots/savetofile.png) This test element can be placed anywhere in the test plan. For each sample in its scope, it will create a file of the response Data. The primary use for this is in creating functional tests, but it can also be useful where the response is too large to be displayed in the [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Listener. The file name is created from the specified prefix, plus a number (unless this is disabled, see below). The file extension is created from the document type, if known. If not known, the file extension is set to '`unknown`'. If numbering is disabled, and adding a suffix is disabled, then the file prefix is taken as the entire file name. This allows a fixed file name to be generated if required. The generated file name is stored in the sample response, and can be saved in the test log output file if required. The current sample is saved first, followed by any sub-samples (child samples). If a variable name is provided, then the names of the files are saved in the order that the sub-samples appear. See below. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Filename Prefix (can include folders) | Yes | Prefix for the generated file names; this can include a directory name. Relative paths are resolved relative to the current working directory (which defaults to the `bin/` directory). JMeter also supports paths relative to the directory containing the current test plan (JMX file). If the path name begins with "`~/`" (or whatever is in the `jmeter.save.saveservice.base_prefix` JMeter property), then the path is assumed to be relative to the JMX file location. If parent folders in prefix do not exists, JMeter will create them and stop test if it fails. :::note Please note that Filename Prefix must not contain Thread related data, so don't use any Variable (`\${varName}`) or functions like `\${__threadNum}` in this field ::: | | Variable Name containing saved file name | No | Name of a variable in which to save the generated file name (so it can be used later in the test plan). If there are sub-samples then a numeric suffix is added to the variable name. E.g. if the variable name is `FILENAME`, then the parent sample file name is saved in the variable `FILENAME`, and the filenames for the child samplers are saved in `FILENAME1`, `FILENAME2` etc. | | Minimum Length of sequence number | No | If "`Don't add number to prefix`" is not checked, then numbers added to prefix will be padded by `0` so that prefix is has size of this value. Defaults to `0`. | | Save Failed Responses only | Yes | If selected, then only failed responses are saved | | Save Successful Responses only | Yes | If selected, then only successful responses are saved | | Don't add number to prefix | Yes | If selected, then no number is added to the prefix. If you select this option, make sure that the prefix is unique or the file may be overwritten. | | Don't add content type suffix | Yes | If selected, then no suffix is added. If you select this option, make sure that the prefix is unique or the file may be overwritten. | | Add timestamp | Yes | If selected, then date will be included in file suffix following format `yyyyMMdd-HHmm_` | | Don't Save Transaction Controller SampleResult | Yes | If selected, then SamplerResult generated by Transaction Controller will be ignored | ## JSR223 Listener The JSR223 Listener allows JSR223 script code to be applied to sample results. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Language | Yes | The JSR223 language to be used | | Parameters | No | Parameters to pass to the script. The parameters are stored in the following variables: **`Parameters`** : string containing the parameters as a single variable **`args`** : String array containing parameters, split on white-space | | Script file | No | A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property | | Script compilation caching | No | Unique String across Test Plan that JMeter will use to cache result of Script compilation if language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not). :::note See note in JSR223 Sampler Java System property if you're using Groovy without checking this option ::: | | Script | Yes (unless script file is provided) | The script to run. | Before invoking the script, some variables are set up. Note that these are JSR223 variables - i.e. they can be used directly in the script. **`log`** : ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file **`Label`** : the String Label **`FileName`** : the script file name (if any) **`Parameters`** : the parameters (as a String) **`args`** : the parameters as a String array (split on whitespace) **`ctx`** : ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context **`vars`** : ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); vars.getObject("OBJ2"); ``` **`props`** : (JMeterProperties - class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` **`sampleResult`, `prev`** : ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the SampleResult **`sampleEvent`** : ([SampleEvent](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleEvent.html)) - gives access to the SampleEvent **`sampler`** : ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html))- gives access to the last sampler **`OUT`** : `System.out` - e.g. `OUT.println("message")` For details of all the methods available on each of the above variables, please check the Javadoc ## Generate Summary Results ![Generate Summary Results](/images/screenshots/summary.png) This test element can be placed anywhere in the test plan. Generates a summary of the test run so far to the log file and/or standard output. Both running and differential totals are shown. Output is generated every `n` seconds (default 30 seconds) on the appropriate time boundary, so that multiple test runs on the same time will be synchronised. :::note Since a summary/differential line is written only if there are samples emitted, the interval for generation may not be respected if your test has no sample generated within the interval ::: See `jmeter.properties` file for the summariser configuration items: ```properties # Define the following property to automatically start a summariser with that name # (applies to CLI mode only) #summariser.name=summary # # interval between summaries (in seconds) default 3 minutes #summariser.interval=30 # # Write messages to log file #summariser.log=true # # Write messages to System.out #summariser.out=true ``` This element is mainly intended for batch (CLI) runs. The output looks like the following: ``` label + 16 in 0:00:12 = 1.3/s Avg: 1608 Min: 1163 Max: 2009 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label + 82 in 0:00:30 = 2.7/s Avg: 1518 Min: 1003 Max: 2020 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 98 in 0:00:42 = 2.3/s Avg: 1533 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 85 in 0:00:30 = 2.8/s Avg: 1505 Min: 1008 Max: 2005 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 183 in 0:01:13 = 2.5/s Avg: 1520 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 79 in 0:00:30 = 2.7/s Avg: 1578 Min: 1089 Max: 2012 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 262 in 0:01:43 = 2.6/s Avg: 1538 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 80 in 0:00:30 = 2.7/s Avg: 1531 Min: 1013 Max: 2014 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 342 in 0:02:12 = 2.6/s Avg: 1536 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 83 in 0:00:31 = 2.7/s Avg: 1512 Min: 1003 Max: 1982 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 425 in 0:02:43 = 2.6/s Avg: 1531 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 83 in 0:00:29 = 2.8/s Avg: 1487 Min: 1023 Max: 2013 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 508 in 0:03:12 = 2.6/s Avg: 1524 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 78 in 0:00:30 = 2.6/s Avg: 1594 Min: 1013 Max: 2016 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 586 in 0:03:43 = 2.6/s Avg: 1533 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 80 in 0:00:30 = 2.7/s Avg: 1516 Min: 1013 Max: 2005 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 666 in 0:04:12 = 2.6/s Avg: 1531 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 86 in 0:00:30 = 2.9/s Avg: 1449 Min: 1004 Max: 2017 Err: 0 (0.00%) Active: 5 Started: 5 Finished: 0 label = 752 in 0:04:43 = 2.7/s Avg: 1522 Min: 1003 Max: 2020 Err: 0 (0.00%) label + 65 in 0:00:24 = 2.7/s Avg: 1579 Min: 1007 Max: 2003 Err: 0 (0.00%) Active: 0 Started: 5 Finished: 5 label = 817 in 0:05:07 = 2.7/s Avg: 1526 Min: 1003 Max: 2020 Err: 0 (0.00%) ``` The "`label`" is the name of the element. The `"+"` means that the line is a delta line, i.e. shows the changes since the last output. The `"="` means that the line is a total line, i.e. it shows the running total. Entries in the JMeter log file also include time-stamps. The example "`817 in 0:05:07 = 2.7/s`" means that there were 817 samples recorded in 5 minutes and 7 seconds, and that works out at 2.7 samples per second. The `Avg` (Average), `Min` (Minimum) and `Max` (Maximum) times are in milliseconds. "`Err`" means number of errors (also shown as percentage). The last two lines will appear at the end of a test. They will not be synchronised to the appropriate time boundary. Note that the initial and final deltas may be for less than the interval (in the example above this is 30 seconds). The first delta will generally be lower, as JMeter synchronizes to the interval boundary. The last delta will be lower, as the test will generally not finish on an exact interval boundary. The label is used to group sample results together. So if you have multiple Thread Groups and want to summarize across them all, then use the same label - or add the summariser to the Test Plan (so all thread groups are in scope). Different summary groupings can be implemented by using suitable labels and adding the summarisers to appropriate parts of the test plan. :::note In CLI mode by default a Generate Summary Results listener named "`summariser`" is configured, if you have already added one to your Test Plan, ensure you name it differently otherwise results will be accumulated under this label (summary) leading to wrong results (sum of total samples + samples located under the Parent of Generate Summary Results listener). This is not a bug but a design choice allowing to summarize across thread groups. ::: | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. It appears as the "`label`" in the output. Details for all elements with the same label will be added together. | ## Comparison Assertion Visualizer ![Comparison Assertion Visualizer](/images/screenshots/comparison_assertion_visualizer.png) The Comparison Assertion Visualizer shows the results of any [Compare Assertion](/user-manual/component-reference/#Compare_Assertion) elements. | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. | ## Backend Listener ![Backend Listener](/images/screenshots/backend_listener.png) The backend listener is an Asynchronous listener that enables you to plug custom implementations of [BackendListenerClient](https://jmeter.apache.org/api/org/apache/jmeter/visualizers/backend/BackendListenerClient.html). By default, a Graphite implementation is provided. | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. | | Backend Listener implementation | Yes | Class of the `BackendListenerClient` implementation. | | Async Queue size | Yes | Size of the queue that holds the SampleResults while they are processed asynchronously. | | Parameters | Yes | Parameters of the `BackendListenerClient` implementation. | The following parameters apply to the [GraphiteBackendListenerClient](https://jmeter.apache.org/api/org/apache/jmeter/visualizers/backend/graphite/GraphiteBackendListenerClient.html) implementation: | Name | Required | Description | |------|----------|-------------| | graphiteMetricsSender | Yes | `org.apache.jmeter.visualizers.backend.graphite.TextGraphiteMetricsSender` or `org.apache.jmeter.visualizers.backend.graphite.PickleGraphiteMetricsSender` | | graphiteHost | Yes | Graphite or InfluxDB (with Graphite plugin enabled) server host | | graphitePort | Yes | Graphite or InfluxDB (with Graphite plugin enabled) server port, defaults to `2003`. Note `PickleGraphiteMetricsSender` (port `2004`) can only talk to Graphite server. | | rootMetricsPrefix | Yes | Prefix of metrics sent to backend. Defaults to "`jmeter`." Note that JMeter does not add a separator between the root prefix and the samplerName which is why the trailing dot is currently needed. | | summaryOnly | Yes | Only send a summary with no detail. Defaults to `true`. | | samplersList | Yes | Defines the names (labels) of sample results to be sent to the back end. If `useRegexpForSamplersList=false` this is a list of semi-colon separated names. If `useRegexpForSamplersList=true` this is a regular expression which will be matched against the names. | | useRegexpForSamplersList | Yes | Consider samplersList as a regular expression to select the samplers for which you want to report metrics to backend. Defaults to `false`. | | percentiles | Yes | The percentiles you want to send to the backend. A percentile may contain a fractional part, for example `12.5`. (The separator is always ".") List must be semicolon separated. Generally 3 or 4 values should be sufficient. | See also [Real-time results](/user-manual/realtime-results/) for more details. ![Grafana dashboard](/images/screenshots/grafana_dashboard.png) _Grafana dashboard_ Since JMeter 3.2, an implementation that allows writing directly in InfluxDB with a custom schema. It is called `InfluxdbBackendListenerClient`. The following parameters apply to the [InfluxdbBackendListenerClient](https://jmeter.apache.org/api/org/apache/jmeter/visualizers/backend/influxdb/InfluxdbBackendListenerClient.html) implementation: | Name | Required | Description | |------|----------|-------------| | influxdbMetricsSender | Yes | `org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender` | | influxdbUrl | Yes | Influx URL (example: `http://influxHost:8086/write?db=jmeter`) | | influxdbToken | No | InfluxDB 2 [authentication token](https://v2.docs.influxdata.com/v2.0/security/) (example: `HE9yIdAPzWJDspH_tCc2UvdKZpX==`); since 5.2. | | application | Yes | Name of tested application. This value is stored in the '`events`' measurement as a tag named '`application`' | | measurement | Yes | Measurement as per [Influx Line Protocol Reference](https://docs.influxdata.com/influxdb/v1.1/write_protocols/line_protocol_reference/). Defaults to "`jmeter`". | | summaryOnly | Yes | Only send a summary with no detail. Defaults to `true`. | | samplersRegex | Yes | Regular expression which will be matched against the names of samples and sent to the back end. | | testTitle | Yes | Test name. Defaults to `Test name`. This value is stored in the '`events`' measurement as a field named '`text`'. JMeter generate automatically at the start and the end of the test an annotation with this value ending with ' started' and ' ended' | | eventTags | No | Grafana allow to display tag for each annotation. You can fill them here. This value is stored in the '`events`' measurement as a tag named '`tags`'. | | percentiles | Yes | The percentiles you want to send to the backend. A percentile may contain a fractional part, for example `12.5` (The separator is always "`.`"). List must be semicolon separated. Generally three or four values should be sufficient. | | TAG_WhatEverYouWant | No | You can add as many custom tags as you want. For each of them, create a new line and prefix its name by "`TAG_`" | See also [Real-time results](/user-manual/realtime-results/) and [Influxdb annotations in Grafana](http://docs.grafana.org/reference/annotations/#influxdb-annotations) for more details. There is also a [subsection on configuring the listener for InfluxDB v2](/user-manual/realtime-results/#influxdb_v2). Since JMeter 5.4, an implementation that writes all sample results to InfluxDB. It is called `InfluxDBRawBackendListenerClient`. It is worth noting that this will use more resources than the `InfluxdbBackendListenerClient`, both by JMeter and InfluxDB due to the increase in data and individual writes. The following parameters apply to the [InfluxDBRawBackendListenerClient](/../api/org/apache/jmeter/visualizers/backend/influxdb/InfluxDBRawBackendListenerClient/) implementation: | Name | Required | Description | |------|----------|-------------| | influxdbMetricsSender | Yes | `org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender` | | influxdbUrl | Yes | Influx URL (e.g. http://influxHost:8086/write?db=jmeter or, for the cloud, https://eu-central-1-1.aws.cloud2.influxdata.com/api/v2/write?org=org-id&bucket=jmeter) | | influxdbToken | No | InfluxDB 2 [authentication token](https://v2.docs.influxdata.com/v2.0/security/) (e.g. HE9yIdAPzWJDspH_tCc2UvdKZpX==) | | measurement | Yes | Measurement as per [Influx Line Protocol Reference](https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/). Defaults to "`jmeter`." | [^](#) ## 18.4 Configuration Elements Configuration elements can be used to set up defaults and variables for later use by samplers. Note that these elements are processed at the start of the scope in which they are found, i.e. before any samplers in the same scope. ## CSV Data Set Config ![CSV Data Set Config](/images/screenshots/csvdatasetconfig.png) CSV Data Set Config is used to read lines from a file, and split them into variables. It is easier to use than the `[__CSVRead()](/user-manual/functions/#__CSVRead__)` and `[__StringFromFile()](/user-manual/functions/#__StringFromFile__)` functions. It is well suited to handling large numbers of variables, and is also useful for testing with "random" and unique values. Generating unique random values at run-time is expensive in terms of CPU and memory, so just create the data in advance of the test. If necessary, the "random" data from the file can be used in conjunction with a run-time parameter to create different sets of values from each run - e.g. using concatenation - which is much cheaper than generating everything at run-time. JMeter allows values to be quoted; this allows the value to contain a delimiter. If "`allow quoted data`" is enabled, a value may be enclosed in double-quotes. These are removed. To include double-quotes within a quoted field, use two double-quotes. For example: ``` 1,"2,3","4""5" => 1 2,3 4"5 ``` JMeter supports CSV files which have a header line defining the column names. To enable this, leave the "`Variable Names`" field empty. The correct delimiter must be provided. JMeter supports CSV files with quoted data that includes new-lines. By default, the file is only opened once, and each thread will use a different line from the file. However the order in which lines are passed to threads depends on the order in which they execute, which may vary between iterations. Lines are read at the start of each test iteration. The file name and mode are resolved in the first iteration. See the description of the Share mode below for additional options. If you want each thread to have its own set of values, then you will need to create a set of files, one for each thread. For example `test1.csv`, `test2.csv`, …, `test_n_.csv`. Use the filename `test\${__threadNum}.csv` and set the "`Sharing mode`" to "`Current thread`". :::note CSV Dataset variables are defined at the start of each test iteration. As this is after configuration processing is completed, they cannot be used for some configuration items - such as JDBC Config - that process their contents at configuration time (see [Bug 40394](https://bz.apache.org/bugzilla/show_bug.cgi?id=40394)) However the variables do work in the HTTP Auth Manager, as the `username` etc. are processed at run-time. ::: As a special case, the string "`\t`" (without quotes) in the delimiter field is treated as a Tab. When the end of file (`EOF`) is reached, and the recycle option is `true`, reading starts again with the first line of the file. If the recycle option is `false`, and stopThread is `false`, then all the variables are set to `<EOF>` when the end of file is reached. This value can be changed by setting the JMeter property `csvdataset.eofstring`. If the Recycle option is `false`, and Stop Thread is `true`, then reaching `EOF` will cause the thread to be stopped. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Filename | Yes | Name of the file to be read. **Relative file names are resolved with respect to the path of the active test plan.** **For distributed testing, the CSV file must be stored on the server host system in the correct relative directory to where the JMeter server is started.** Absolute file names are also supported, but note that they are unlikely to work in remote mode, unless the remote server has the same directory structure. If the same physical file is referenced in two different ways - e.g. `csvdata.txt` and `./csvdata.txt` - then these are treated as different files. If the OS does not distinguish between upper and lower case, `csvData.TXT` would also be opened separately. | | File Encoding | No | The encoding to be used to read the file, if not the platform default. | | Variable Names | No | List of variable names. The names must be separated by the delimiter character. They can be quoted using double-quotes. JMeter supports CSV header lines: if the variable name field empty, then the first line of the file is read and interpreted as the list of column names. | | Use first line as Variable Names | No | Ignore first line of CSV file, it will only be used if Variable Names is not empty, if Variable Names is empty the first line must contain the headers. | | Delimiter | Yes | Delimiter to be used to split the records in the file. If there are fewer values on the line than there are variables the remaining variables are not updated - so they will retain their previous value (if any). | | Allow quoted data? | Yes | Should the CSV file allow values to be quoted? If enabled, then values can be enclosed in `"` - double-quote - allowing values to contain a delimiter. | | Recycle on EOF? | Yes | Should the file be re-read from the beginning on reaching `EOF`? (default is `true`) | | Stop thread on EOF? | Yes | Should the thread be stopped on `EOF`, if Recycle is false? (default is `false`) | | Sharing mode | Yes | - `All threads` - (the default) the file is shared between all the threads. - `Current thread group` - each file is opened once for each thread group in which the element appears - `Current thread` - each file is opened separately for each thread - `Identifier` - all threads sharing the same identifier share the same file. So for example if you have 4 thread groups, you could use a common id for two or more of the groups to share the file between them. Or you could use the thread number to share the file between the same thread numbers in different thread groups. | ## FTP Request Defaults ![FTP Request Defaults](/images/screenshots/ftp-config/ftp-request-defaults.png) ## DNS Cache Manager ![DNS Cache Manager](/images/screenshots/dns-cache-manager.png) :::note DNS Cache Manager is designed for using in the root of Thread Group or Test Plan. Do not place it as child element of particular HTTP Sampler ::: :::note DNS Cache Manager works only with HTTP requests using HTTPClient4 implementation. ::: The DNS Cache Manager element allows to test applications, which have several servers behind load balancers (CDN, etc.), when user receives content from different IP's. By default JMeter uses JVM DNS cache. That's why only one server from the cluster receives load. DNS Cache Manager resolves names for each thread separately each iteration and saves results of resolving to its internal DNS Cache, which is independent from both JVM and OS DNS caches. A mapping for static hosts can be used to simulate something like `/etc/hosts` file. These entries will be preferred over the custom resolver. `Use custom DNS resolver` has to be enabled, if you want to use this mapping. #### Usage of static host table Say, you have a test server, that you want to reach with a name, that is not (yet) set up in your DNS servers. For our example, this would be `www.example.com` for the server name, which you want to reach at the IP of the server `a123.another.example.org`. You could change your workstation and add an entry to your `/etc/hosts` file - or the equivalent for your OS, or add an entry to the Static Host Table of the DNS Cache Manager. You would type `www.example.com` into the first column (`Host`) and `a123.another.example.org` into the second column (`Hostname or IP address`). As the name of the second column implies, you could even use the IP address of your test server there. The IP address for the test server will be looked up by using the custom DNS resolver. When none is given, the system DNS resolver will be used. Now you can use `www.example.com` in your HTTPClient4 samplers and the requests will be made against `a123.another.example.org` with all headers set to `www.example.com`. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Clear cache each Iteration | No | If selected, DNS cache of every Thread is cleared each time new iteration is started. | | Use system DNS resolver | N/A | System DNS resolver will be used. For correct work edit `$JAVA_HOME/jre/lib/security/java.security` and add `networkaddress.cache.ttl=0` | | Use custom DNS resolver | N/A | Custom DNS resolver (from dnsjava library) will be used. | | Hostname or IP address | No | List of DNS servers to use. If empty, network configuration DNS will used. | | Add Button | N/A | Add an entry to the DNS servers table. | | Delete Button | N/A | Delete the currently selected table entry. | | Host and Hostname or IP address | No | Mapping of hostnames to a static host entry which will be resolved using the custom DNS resolver. | | Add static host Button | N/A | Add an entry to the static hosts table. | | Delete static host Button | N/A | Delete the currently selected static host in the table. | ## HTTP Authorization Manager ![HTTP Authorization Manager](/images/screenshots/http-config/http-auth-manager.png) :::note If there is more than one Authorization Manager in the scope of a Sampler, there is currently no way to specify which one is to be used. ::: The Authorization Manager lets you specify one or more user logins for web pages that are restricted using server authentication. You see this type of authentication when you use your browser to access a restricted page, and your browser displays a login dialog box. JMeter transmits the login information when it encounters this type of page. The Authorization headers may not be shown in the Tree View Listener "`Request`" tab. The Java implementation does pre-emptive authentication, but it does not return the Authorization header when JMeter fetches the headers. The HttpComponents (HC 4.5.X) implementation defaults to pre-emptive since 3.2 and the header will be shown. To disable this, set the values as below, in which case authentication will only be performed in response to a challenge. In the file `jmeter.properties` set `httpclient4.auth.preemptive=false` :::note Note: the above settings only apply to the HttpClient sampler. ::: :::note When looking for a match against a URL, JMeter checks each entry in turn, and stops when it finds the first match. Thus the most specific URLs should appear first in the list, followed by less specific ones. Duplicate URLs will be ignored. If you want to use different usernames/passwords for different threads, you can use variables. These can be set up using a [CSV Data Set Config](/user-manual/component-reference/#CSV_Data_Set_Config) Element (for example). ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Clear auth on each iteration | Yes | Used by Kerberos authentication. If checked, authentication will be done on each iteration of Main Thread Group loop even if it has already been done in a previous one. This is usually useful if each main thread group iteration represents behaviour of one Virtual User. | | Base URL | Yes | A partial or complete URL that matches one or more HTTP Request URLs. As an example, say you specify a Base URL of "`http://localhost/restricted/`" with a `Username` of "`jmeter`" and a `Password` of "`jmeter`". If you send an HTTP request to the URL "`http://localhost/restricted/ant/myPage.html`", the Authorization Manager sends the login information for the user named, "`jmeter`". | | Username | Yes | The username to authorize. | | Password | Yes | The password for the user. (N.B. this is stored unencrypted in the test plan) | | Domain | No | The domain to use for NTLM. | | Realm | No | The realm to use for NTLM. | | Mechanism | No | Type of authentication to perform. JMeter can perform different types of authentications based on used Http Samplers: **Java** : `BASIC` **HttpClient 4** : `BASIC`, `DIGEST` and `Kerberos` | :::note The Realm only applies to the HttpClient sampler. ::: **Kerberos Configuration:** To configure Kerberos you need to setup at least two JVM system properties: - `-Djava.security.krb5.conf=krb5.conf` - `-Djava.security.auth.login.config=jaas.conf` You can also configure those two properties in the file `bin/system.properties`. Look at the two sample configuration files (`krb5.conf` and `jaas.conf`) located in the JMeter `bin` folder for references to more documentation, and tweak them to match your Kerberos configuration. Delegation of credentials is disabled by default for SPNEGO. If you want to enable it, you can do so by setting the property `kerberos.spnego.delegate_cred` to `true`. When generating a SPN for Kerberos SPNEGO authentication IE and Firefox will omit the port number from the URL. Chrome has an option (`--enable-auth-negotiate-port`) to include the port number if it differs from the standard ones (`80` and `443`). That behavior can be emulated by setting the following JMeter property as below. In `jmeter.properties` or `user.properties`, set: - `kerberos.spnego.strip_port=false` **Controls:** - `Add` Button - Add an entry to the authorization table. - `Delete` Button - Delete the currently selected table entry. - `Load` Button - Load a previously saved authorization table and add the entries to the existing authorization table entries. - `Save As` Button - Save the current authorization table to a file. :::note When you save the Test Plan, JMeter automatically saves all of the authorization table entries - including any passwords, which are not encrypted. ::: #### Authorization Example [Download](../demos/AuthManagerTestPlan.jmx) this example. In this example, we created a Test Plan on a local server that sends three HTTP requests, two requiring a login and the other is open to everyone. See figure 10 to see the makeup of our Test Plan. On our server, we have a restricted directory named, "`secret`", which contains two files, "`index.html`" and "`index2.html`". We created a login id named, "`kevin`", which has a password of "`spot`". So, in our Authorization Manager, we created an entry for the restricted directory and a username and password (see figure 11). The two HTTP requests named "`SecretPage1`" and "`SecretPage2`" make requests to "`/secret/index.html`" and "`/secret/index2.html`". The other HTTP request, named "`NoSecretPage`" makes a request to "`/index.html`". ![Figure 10 - Test Plan](/images/screenshots/http-config/auth-manager-example1a.png) _Figure 10 - Test Plan_ ![Figure 11 - Authorization Manager Control Panel](/images/screenshots/http-config/auth-manager-example1b.png) _Figure 11 - Authorization Manager Control Panel_ When we run the Test Plan, JMeter looks in the Authorization table for the URL it is requesting. If the Base URL matches the URL, then JMeter passes this information along with the request. :::note You can download the Test Plan, but since it is built as a test for our local server, you will not be able to run it. However, you can use it as a reference in constructing your own Test Plan. ::: ## HTTP Cache Manager ![HTTP Cache Manager](/images/screenshots/http-config/http-cache-manager.png) The HTTP Cache Manager is used to add caching functionality to HTTP requests within its scope to simulate browser cache feature. Each Virtual User thread has its own Cache. By default, Cache Manager will store up to 5000 items in cache per Virtual User thread, using LRU algorithm. Use property "`maxSize`" to modify this value. Note that the more you increase this value the more HTTP Cache Manager will consume memory, so be sure to adapt the `-Xmx` JVM option accordingly. If a sample is successful (i.e. has response code `2xx`) then the `Last-Modified` and `Etag` (and `Expired` if relevant) values are saved for the URL. Before executing the next sample, the sampler checks to see if there is an entry in the cache, and if so, the `If-Last-Modified` and `If-None-Match` conditional headers are set for the request. Additionally, if the "`Use Cache-Control/Expires header`" option is selected, then the `Cache-Control`/`Expires` value is checked against the current time. If the request is a `GET` request, and the timestamp is in the future, then the sampler returns immediately, without requesting the URL from the remote server. This is intended to emulate browser behaviour. Note that if `Cache-Control` header is "`no-cache`", the response will be stored in cache as pre-expired, so will generate a conditional `GET` request. If `Cache-Control` has any other value, the "`max-age`" expiry option is processed to compute entry lifetime, if missing then expire header will be used, if also missing entry will be cached as specified in [RFC 2616 section 13.2.4](https://tools.ietf.org/html/2616#section-13.2.4) using `Last-Modified` time and response Date. :::note If the requested document has not changed since it was cached, then the response body will be empty. Likewise if the `Expires` date is in the future. This may cause problems for Assertions. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Clear cache each iteration | Yes | If selected, then the cache is cleared at the start of the thread. | | Use Cache Control/Expires header when processing GET requests | Yes | See description above. | | Max Number of elements in cache | Yes | See description above. | ## HTTP Cookie Manager ![HTTP Cookie Manager](/images/screenshots/http-config/http-cookie-manager.png) :::note If there is more than one Cookie Manager in the scope of a Sampler, there is currently no way to specify which one is to be used. Also, a cookie stored in one cookie manager is not available to any other manager, so use multiple Cookie Managers with care. ::: The Cookie Manager element has two functions: First, it stores and sends cookies just like a web browser. If you have an HTTP Request and the response contains a cookie, the Cookie Manager automatically stores that cookie and will use it for all future requests to that particular web site. Each JMeter thread has its own "cookie storage area". So, if you are testing a web site that uses a cookie for storing session information, each JMeter thread will have its own session. Note that such cookies do not appear on the Cookie Manager display, but they can be seen using the [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Listener. JMeter checks that received cookies are valid for the URL. This means that cross-domain cookies are not stored. If you have bugged behaviour or want Cross-Domain cookies to be used, define the JMeter property "`CookieManager.check.cookies=false`". Received Cookies can be stored as JMeter thread variables. To save cookies as variables, define the property "`CookieManager.save.cookies=true`". Also, cookies names are prefixed with "`COOKIE_`" before they are stored (this avoids accidental corruption of local variables) To revert to the original behaviour, define the property "`CookieManager.name.prefix= `" (one or more spaces). If enabled, the value of a cookie with the name `TEST` can be referred to as `\${COOKIE_TEST}`. Second, you can manually add a cookie to the Cookie Manager. However, if you do this, the cookie will be shared by all JMeter threads. Note that such Cookies are created with an Expiration time far in the future Cookies with `null` values are ignored by default. This can be changed by setting the JMeter property: `CookieManager.delete_null_cookies=false`. Note that this also applies to manually defined cookies - any such cookies will be removed from the display when it is updated. Note also that the cookie name must be unique - if a second cookie is defined with the same name, it will replace the first. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Clear Cookies each Iteration | Yes | If selected, all server-defined cookies are cleared each time the main Thread Group loop is executed. Any cookie defined in the GUI are not cleared. | | Cookie Policy | Yes | The cookie policy that will be used to manage the cookies. "`standard`" is the default since 3.0, and should work in most cases. See [Cookie specifications](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/statemgmt.html#d5e515) and [CookieSpec implementations](http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/cookie/CookieSpec.html) [Note: "`ignoreCookies`" is equivalent to omitting the CookieManager.] | | Implementation | Yes | `HC4CookieHandler` (HttpClient 4.5.X API). Default is `HC4CookieHandler` since 3.0. _[Note: If you have a website to test with IPv6 address, choose `HC4CookieHandler` (IPv6 compliant)]_ | | User-Defined Cookies | No (discouraged, unless you know what you're doing) | This gives you the opportunity to use hardcoded cookies that will be used by all threads during the test execution. The "`domain`" is the hostname of the server (without `http://`); the port is currently ignored. | | Add Button | N/A | Add an entry to the cookie table. | | Delete Button | N/A | Delete the currently selected table entry. | | Load Button | N/A | Load a previously saved cookie table and add the entries to the existing cookie table entries. | | Save As Button | N/A | Save the current cookie table to a file (does not save any cookies extracted from HTTP Responses). | ## HTTP Request Defaults ![HTTP Request Defaults](/images/screenshots/http-config/http-request-defaults.png) This element lets you set default values that your HTTP Request controllers use. For example, if you are creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server, you could add a single HTTP Request Defaults element with the "`Server Name or IP`" field filled in. Then, when you add the 25 HTTP Request controllers, leave the "`Server Name or IP`" field empty. The controllers will inherit this field value from the HTTP Request Defaults element. :::note All port values are treated equally; a sampler that does not specify a port will use the HTTP Request Defaults port, if one is provided. ::: ![HTTP Request Advanced config fields](/images/screenshots/http-config/http-request-defaults-advanced-tab.png) _HTTP Request Advanced config fields_ | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Server | No | Domain name or IP address of the web server. E.g. `www.example.com`. [Do not include the `http://` prefix. | | Port | No | Port the web server is listening to. | | Connect Timeout | No | Connection Timeout. Number of milliseconds to wait for a connection to open. | | Response Timeout | No | Response Timeout. Number of milliseconds to wait for a response. | | Implementation | No | `Java`, `HttpClient4`. If not specified the default depends on the value of the JMeter property `jmeter.httpsampler`, failing that, the `Java` implementation is used. | | Protocol | No | `HTTP` or `HTTPS`. | | Content encoding | No | The encoding to be used for the request. | | Path | No | The path to resource (for example, `/servlets/myServlet`). If the resource requires query string parameters, add them below in the "`Send Parameters With the Request`" section. Note that the path is the default for the full path, not a prefix to be applied to paths specified on the HTTP Request screens. | | Send Parameters With the Request | No | The query string will be generated from the list of parameters you provide. Each parameter has a _name_ and _value_. The query string will be generated in the correct fashion, depending on the choice of "`Method`" you made (i.e. if you chose `GET`, the query string will be appended to the URL, if `POST`, then it will be sent separately). Also, if you are sending a file using a multipart form, the query string will be created using the multipart form specifications. | | Server (proxy) | No | Hostname or IP address of a proxy server to perform request. [Do not include the `http://` prefix.] | | Port | No, unless proxy hostname is specified | Port the proxy server is listening to. | | Username | No | (Optional) username for proxy server. | | Password | No | (Optional) password for proxy server. (N.B. this is stored unencrypted in the test plan) | | Retrieve All Embedded Resources from HTML Files | No | Tell JMeter to parse the HTML file and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced in the file. | | Use concurrent pool | No | Use a pool of concurrent connections to get embedded resources. | | Size | No | Pool size for concurrent connections used to get embedded resources. | | URLs must match: | No | If present, this must be a regular expression that is used to match against any embedded URLs found. So if you only want to download embedded resources from `http://example.invalid/`, use the expression: `http://example\.invalid/.*` | | URLs must not match: | No | If present, this must be a regular expression that is used to filter out any embedded URLs found. So if you don't want to download PNG or SVG files from any source, use the expression: `.*\.(?i:svg|png)` | :::note Note: radio buttons only have two states - on or off. This makes it impossible to override settings consistently - does off mean off, or does it mean use the current default? JMeter uses the latter (otherwise defaults would not work at all). So if the button is off, then a later element can set it on, but if the button is on, a later element cannot set it off. ::: ## HTTP Header Manager ![HTTP Header Manager](/images/screenshots/http-config/http-header-manager.png) The Header Manager lets you add or override HTTP request headers. **JMeter now supports multiple Header Managers**. The header entries are merged to form the list for the sampler. If an entry to be merged matches an existing header name, it replaces the previous entry. This allows one to set up a default set of headers, and apply adjustments to particular samplers. Note that an empty value for a header does not remove an existing header, it justs replace its value. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Name (Header) | No (You should have at least one, however) | Name of the request header. Two common request headers you may want to experiment with are "`User-Agent`" and "`Referer`". | | Value | No (You should have at least one, however) | Request header value. | | Add Button | N/A | Add an entry to the header table. | | Delete Button | N/A | Delete the currently selected table entry. | | Load Button | N/A | Load a previously saved header table and add the entries to the existing header table entries. | | Save As Button | N/A | Save the current header table to a file. | #### Header Manager example [Download](../demos/HeaderManagerTestPlan.jmx) this example. In this example, we created a Test Plan that tells JMeter to override the default "`User-Agent`" request header and use a particular Internet Explorer agent string instead. (see figures 12 and 13). ![Figure 12 - Test Plan](/images/screenshots/http-config/header-manager-example1a.png) _Figure 12 - Test Plan_ ![Figure 13 - Header Manager Control Panel](/images/screenshots/http-config/header-manager-example1b.png) _Figure 13 - Header Manager Control Panel_ ## Java Request Defaults ![Java Request Defaults](/images/screenshots/java_defaults.png) The Java Request Defaults component lets you set default values for Java testing. See the [Java Request](/user-manual/component-reference/#Java_Request). ## JDBC Connection Configuration ![JDBC Connection Configuration](/images/screenshots/jdbc-config/jdbc-conn-config.png) Creates a database connection (used by [JDBC Request](/user-manual/component-reference/#JDBC_Request)Sampler) from the supplied JDBC Connection settings. The connection may be optionally pooled between threads. Otherwise each thread gets its own connection. The connection configuration name is used by the JDBC Sampler to select the appropriate connection. The used pool is DBCP, see [BasicDataSource Configuration Parameters](https://commons.apache.org/proper/commons-dbcp/configuration.html) | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for the connection configuration that is shown in the tree. | | Variable Name for created pool | Yes | The name of the variable the connection is tied to. Multiple connections can be used, each tied to a different variable, allowing JDBC Samplers to select the appropriate connection. :::note Each name must be different. If there are two configuration elements using the same name, only one will be saved. JMeter logs a message if a duplicate name is detected. ::: | | Max Number of Connections | Yes | Maximum number of connections allowed in the pool. In most cases, **set this to zero (0)**. This means that each thread will get its own pool with a single connection in it, i.e. the connections are not shared between threads. If you really want to use shared pooling (why?), then set the max count to the same as the number of threads to ensure threads don't wait on each other. | | Max Wait (ms) | Yes | Pool throws an error if the timeout period is exceeded in the process of trying to retrieve a connection, see [BasicDataSource.html#getMaxWaitMillis](https://commons.apache.org/proper/commons-dbcp/api-2.1.1/org/apache/commons/dbcp2/BasicDataSource.html#getMaxWaitMillis--) | | Time Between Eviction Runs (ms) | Yes | The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run. (Defaults to "`60000`", 1 minute). See [BasicDataSource.html#getTimeBetweenEvictionRunsMillis](https://commons.apache.org/proper/commons-dbcp/api-2.1.1/org/apache/commons/dbcp2/BasicDataSource.html#getTimeBetweenEvictionRunsMillis--) | | Auto Commit | Yes | Turn auto commit on or off for the connections. | | Transaction isolation | Yes | Transaction isolation level | | Pool Prepared Statements | Yes | Max number of Prepared Statements to pool per connection. `"-1`" disables the pooling and "`0`" means unlimited number of Prepared Statements to pool. (Defaults to "`-1`") | | Preinit Pool | No | The connection pool can be initialized instantly. If set to `False` (default), the JDBC request samplers using this pool might measure higher response times for the first queries – as the connection establishment time for the whole pool is included. | | Init SQL statements separated by new line | No | A Collection of SQL statements that will be used to initialize physical connections when they are first created. These statements are executed only once - when the configured connection factory creates the connection. | | Test While Idle | Yes | Test idle connections of the pool, see [BasicDataSource.html#getTestWhileIdle](https://commons.apache.org/proper/commons-dbcp/api-2.1.1/org/apache/commons/dbcp2/BasicDataSource.html#getTestWhileIdle--). Validation Query will be used to test it. | | Soft Min Evictable Idle Time(ms) | Yes | Minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the idle object evictor, with the extra condition that at least `minIdle` connections remain in the pool. See [BasicDataSource.html#getSoftMinEvictableIdleTimeMillis](https://commons.apache.org/proper/commons-dbcp/api-2.1.1/org/apache/commons/dbcp2/BasicDataSource.html#getSoftMinEvictableIdleTimeMillis--). Defaults to 5000 (5 seconds) | | Validation Query | No | A simple query used to determine if the database is still responding. This defaults to the '`isValid()`' method of the jdbc driver, which is suitable for many databases. However some may require a different query; for example Oracle something like '`SELECT 1 FROM DUAL`' could be used. The list of the validation queries can be configured with `jdbc.config.check.query` property and are by default: **hsqldb** : `select 1 from INFORMATION_SCHEMA.SYSTEM_USERS` **Oracle** : `select 1 from dual` **DB2** : `select 1 from sysibm.sysdummy1` **MySQL or MariaDB** : `select 1` **Microsoft SQL Server (MS JDBC driver)** : `select 1` **PostgreSQL** : `select 1` **Ingres** : `select 1` **Derby** : `values 1` **H2** : `select 1` **Firebird** : `select 1 from rdb$database` **Exasol** : `select 1` :::note The list come from [stackoverflow entry on different database validation queries](https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases) and it can be incorrect ::: :::note Note this validation query is used on pool creation to validate it even if "`Test While Idle`" suggests query would only be used on idle connections. This is DBCP behaviour. ::: | | Database URL | Yes | JDBC Connection string for the database. | | JDBC Driver class | Yes | Fully qualified name of driver class. (Must be in JMeter's classpath - easiest to copy `.jar` file into JMeter's `/lib` directory). The list of the preconfigured jdbc driver classes can be configured with `jdbc.config.jdbc.driver.class` property and are by default: **hsqldb** : `org.hsqldb.jdbc.JDBCDriver` **Oracle** : `oracle.jdbc.OracleDriver` **DB2** : `com.ibm.db2.jcc.DB2Driver` **MySQL** : `com.mysql.cj.jdbc.Driver` `com.mysql.jdbc.Driver` (deprecated) **Microsoft SQL Server (MS JDBC driver)** : `com.microsoft.sqlserver.jdbc.SQLServerDriver` or `com.microsoft.jdbc.sqlserver.SQLServerDriver` **PostgreSQL** : `org.postgresql.Driver` **Ingres** : `com.ingres.jdbc.IngresDriver` **Derby** : `org.apache.derby.jdbc.ClientDriver` **H2** : `org.h2.Driver` **Firebird** : `org.firebirdsql.jdbc.FBDriver` **Apache Derby** : `org.apache.derby.jdbc.ClientDriver` **MariaDB** : `org.mariadb.jdbc.Driver` **SQLite** : `org.sqlite.JDBC` **Sybase AES** : `net.sourceforge.jtds.jdbc.Driver` **Exasol** : `com.exasol.jdbc.EXADriver` | | Username | No | Name of user to connect as. | | Password | No | Password to connect with. (N.B. this is stored unencrypted in the test plan) | | Connection Properties | No | Connection Properties to set when establishing connection (like `internal_logon=sysdba` for Oracle for example) | Different databases and JDBC drivers require different JDBC settings. The Database URL and JDBC Driver class are defined by the provider of the JDBC implementation. Some possible settings are shown below. Please check the exact details in the JDBC driver documentation. If JMeter reports `No suitable driver`, then this could mean either: - The driver class was not found. In this case, there will be a log message such as `DataSourceElement: Could not load driver: {classname} java.lang.ClassNotFoundException: {classname}` - The driver class was found, but the class does not support the connection string. This could be because of a syntax error in the connection string, or because the wrong classname was used. If the database server is not running or is not accessible, then JMeter will report a `java.net.ConnectException`. Some examples for databases and their parameters are given below. **MySQL** : **Driver class** : `com.mysql.cj.jdbc.Driver` **Database URL** : `jdbc:mysql://host[:port]/dbname` **PostgreSQL** : **Driver class** : `org.postgresql.Driver` **Database URL** : `jdbc:postgresql:{dbname}` **Oracle** : **Driver class** : `oracle.jdbc.OracleDriver` **Database URL** : `jdbc:oracle:thin:@//host:port/service` OR `jdbc:oracle:thin:@(description=(address=(host={mc-name})(protocol=tcp)(port={port-no}))(connect_data=(sid={sid})))` **Ingress (2006)** : **Driver class** : `ingres.jdbc.IngresDriver` **Database URL** : `jdbc:ingres://host:port/db[;attr=value]` **Microsoft SQL Server (MS JDBC driver)** : **Driver class** : `com.microsoft.sqlserver.jdbc.SQLServerDriver` **Database URL** : `jdbc:sqlserver://host:port;DatabaseName=dbname` **Apache Derby** : **Driver class** : `org.apache.derby.jdbc.ClientDriver` **Database URL** : `jdbc:derby://server[:port]/databaseName[;URLAttributes=value[;…]]` **MariaDB** : **Driver class** : `org.mariadb.jdbc.Driver` **Database URL** : `jdbc:mariadb://host[:port]/dbname[;URLAttributes=value[;…]]` **Exasol (see also [JDBC driver documentation](https://docs.exasol.com/connect_exasol/drivers/jdbc.htm))** : **Driver class** : `com.exasol.jdbc.EXADriver` **Database URL** : `jdbc:exa:host[:port][;schema=SCHEMA_NAME][;prop_x=value_x]` :::note The above may not be correct - please check the relevant JDBC driver documentation. ::: ## Keystore Configuration ![Keystore Configuration](/images/screenshots/keystore_config.png) The Keystore Config Element lets you configure how Keystore will be loaded and which keys it will use. This component is typically used in HTTPS scenarios where you don't want to take into account keystore initialization into account in response time. To use this element, you need to setup first a Java Key Store with the client certificates you want to test, to do that: 1. Create your certificates either with Java `keytool` utility or through your PKI 2. If created by PKI, import your keys in Java Key Store by converting them to a format acceptable by JKS 3. Then reference the keystore file through the two JVM properties (or add them in `system.properties`): - `-Djavax.net.ssl.keyStore=path_to_keystore` - `-Djavax.net.ssl.keyStorePassword=password_of_keystore` To use PKCS11 as the source for the store, you need to set `javax.net.ssl.keyStoreType` to `PKCS11` and `javax.net.ssl.keyStore` to `NONE`. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Preload | Yes | Whether or not to preload Keystore. Setting it to `true` is usually the best option. | | Variable name holding certificate alias | False | Variable name that will contain the alias to use for authentication by client certificate. Variable value will be filled from CSV Data Set for example. In the screenshot, "`certificat_ssl`" will also be a variable in CSV Data Set. Defaults to `clientCertAliasVarName` | | Alias Start Index | Yes | The index of the first key to use in Keystore, 0-based. | | Alias End Index | Yes | The index of the last key to use in Keystore, 0-based. When using "`Variable name holding certificate alias`" ensure it is large enough so that all keys are loaded at startup. Default to -1 which means load all. | :::note To make JMeter use more than one certificate you need to ensure that: - `https.use.cached.ssl.context=false` is set in `jmeter.properties` or `user.properties` - You use HTTPClient 4 implementation for HTTP Request ::: ## Login Config Element ![Login Config Element](/images/screenshots/login-config.png) The Login Config Element lets you add or override username and password settings in samplers that use username and password as part of their setup. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Username | No | The default username to use. | | Password | No | The default password to use. (N.B. this is stored unencrypted in the test plan) | ## LDAP Request Defaults ![LDAP Request Defaults](/images/screenshots/ldap_defaults.png) The LDAP Request Defaults component lets you set default values for LDAP testing. See the [LDAP Request](/user-manual/component-reference/#LDAP_Request). ## LDAP Extended Request Defaults ![LDAP Extended Request Defaults](/images/screenshots/ldapext_defaults.png) The LDAP Extended Request Defaults component lets you set default values for extended LDAP testing. See the [LDAP Extended Request](/user-manual/component-reference/#LDAP_Extended_Request). ## TCP Sampler Config ![TCP Sampler Config](/images/screenshots/tcpsamplerconfig.png) The TCP Sampler Config provides default data for the TCP Sampler | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | TCPClient classname | No | Name of the TCPClient class. Defaults to the property `tcp.handler`, failing that `TCPClientImpl`. | | ServerName or IP | No | Name or IP of TCP server | | Port Number | No | Port to be used | | Re-use connection | Yes | If selected, the connection is kept open. Otherwise it is closed when the data has been read. | | Close connection | Yes | If selected, the connection will be closed after running the sampler. | | SO_LINGER | No | Enable/disable `SO_LINGER` with the specified linger time in seconds when a socket is created. If you set "`SO_LINGER`" value as `0`, you may prevent large numbers of sockets sitting around with a `TIME_WAIT` status. | | End of line(EOL) byte value | No | Byte value for end of line, set this to a value outside the range `-128` to `+127` to skip EOL checking. You may set this in `jmeter.properties` file as well with the `tcp.eolByte` property. If you set this in TCP Sampler Config and in `jmeter.properties` file at the same time, the setting value in the TCP Sampler Config will be used. | | Connect Timeout | No | Connect Timeout (milliseconds, 0 disables). | | Response Timeout | No | Response Timeout (milliseconds, 0 disables). | | Set Nodelay | No | Should the nodelay property be set? | | Text to Send | No | Text to be sent | ## User Defined Variables ![User Defined Variables](/images/screenshots/user_defined_variables.png) The User Defined Variables element lets you define an **initial set of variables**, just as in the [Test Plan](/user-manual/component-reference/#Test_Plan). :::note Note that all the UDV elements in a test plan - no matter where they are - are processed at the start. ::: So you cannot reference variables which are defined as part of a test run, e.g. in a Post-Processor. UDVs should not be used with functions that generate different results each time they are called. Only the result of the first function call will be saved in the variable. However, UDVs can be used with functions such as `[__P()](/user-manual/functions/#__P__)`, for example: ``` HOST \${__P(host,localhost)} ``` which would define the variable "`HOST`" to have the value of the JMeter property "`host`", defaulting to "`localhost`" if not defined. For defining variables during a test run, see [User Parameters](/user-manual/component-reference/#User_Parameters). UDVs are processed in the order they appear in the Plan, from top to bottom. For simplicity, it is suggested that UDVs are placed only at the start of a Thread Group (or perhaps under the Test Plan itself). Once the Test Plan and all UDVs have been processed, the resulting set of variables is copied to each thread to provide the initial set of variables. If a runtime element such as a User Parameters Pre-Processor or Regular Expression Extractor defines a variable with the same name as one of the UDV variables, then this will replace the initial value, and all other test elements in the thread will see the updated value. :::note If you have more than one Thread Group, make sure you use different names for different values, as UDVs are shared between Thread Groups. Also, the variables are not available for use until after the element has been processed, so you cannot reference variables that are defined in the same element. You can reference variables defined in earlier UDVs or on the Test Plan. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | User Defined Variables | No | Variable name/value pairs. The string under the "`Name`" column is what you'll need to place inside the brackets in `\${…}` constructs to use the variables later on. The whole `\${…}` will then be replaced by the string in the "`Value`" column. | ## Random Variable ![Random Variable](/images/screenshots/random_variable.png) The Random Variable Config Element is used to generate random numeric strings and store them in variable for use later. It's simpler than using [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) together with the `[__Random()](/user-manual/functions/#__Random__)` function. The output variable is constructed by using the random number generator, and then the resulting number is formatted using the format string. The number is calculated using the formula `minimum+Random.nextInt(maximum-minimum+1)`. `Random.nextInt()` requires a positive integer. This means that `maximum-minimum` - i.e. the range - must be less than `2147483647`, however the `minimum` and `maximum` values can be any `long` values so long as the range is OK. :::note As the random value is evaluated at the start of each iteration, it is probably not a good idea to use a variable other than a property as a value for the minimum or maximum. It would be zero on the first iteration. ::: | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. | | Variable Name | Yes | The name of the variable in which to store the random string. | | Format String | No | The `java.text.DecimalFormat` format string to be used. For example "`000`" which will generate numbers with at least 3 digits, or "`USER_000`" which will generate output of the form `USER_nnn`. If not specified, the default is to generate the number using `Long.toString()` | | Minimum Value | Yes | The minimum value (`long`) of the generated random number. | | Maximum Value | Yes | The maximum value (`long`) of the generated random number. | | Random Seed | No | The seed for the random number generator. If you use the same seed value with Per Thread set to `true`, you will get the same value for each Thread as per [Random](http://docs.oracle.com/javase/8/docs/api/java/util/Random.html) class. If no seed is set, Default constructor of Random will be used. | | Per Thread(User)? | Yes | If `False`, the generator is shared between all threads in the thread group. If `True`, then each thread has its own random generator. | ## Counter ![Counter](/images/screenshots/counter.png) Allows the user to create a counter that can be referenced anywhere in the Thread Group. The counter config lets the user configure a starting point, a maximum, and the increment. The counter will loop from the start to the max, and then start over with the start, continuing on like that until the test is ended. The counter uses a long to store the value, so the range is from `-2^63` to `2^63-1`. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Starting value | No | The starting value for the counter. The counter will equal this value during the first iteration (defaults to 0). | | Increment | Yes | How much to increment the counter by after each iteration (defaults to 0, meaning no increment). | | Maximum value | No | If the counter exceeds the maximum, then it is reset to the `Starting value`. Default is `Long.MAX_VALUE` | | Format | No | Optional format, e.g. `000` will format as `001`, `002`, etc. This is passed to `DecimalFormat`, so any valid formats can be used. If there is a problem interpreting the format, then it is ignored. [The default format is generated using `Long.toString()`] | | Exported Variable Name | No | This will be the variable name under which the counter value is available. If you name it `counterA`, you can then access it using `\${counterA}` as explained in [user-defined values](/user-manual/functions/) (By default, it creates an empty string variable that can be accessed using `\${}` but this is highly discouraged) | | Track Counter Independently for each User | No | In other words, is this a global counter, or does each user get their own counter? If unchecked, the counter is global (i.e., user #1 will get value "`1`", and user #2 will get value "`2`" on the first iteration). If checked, each user has an independent counter. | | Reset counter on each Thread Group Iteration | No | This option is only available when counter is tracked per User, if checked, counter will be reset to `Start` value on each Thread Group iteration. This can be useful when Counter is inside a Loop Controller. | ## Simple Config Element ![Simple Config Element](/images/screenshots/simple_config_element.png) The Simple Config Element lets you add or override arbitrary values in samplers. You can choose the name of the value and the value itself. Although some adventurous users might find a use for this element, it's here primarily for developers as a basic GUI that they can use while developing new JMeter components. | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. | | Parameter Name | Yes | The name of each parameter. These values are internal to JMeter's workings and are not generally documented. Only those familiar with the code will know these values. | | Parameter Value | Yes | The value to apply to that parameter. | [^](#) ## Bolt Connection Configuration ![Bolt Connection Configuration](/images/screenshots/bolt-connection-config.png) Creates a Bolt connection pool (used by [Bolt Request](/user-manual/component-reference/#Bolt_Request) Sampler) from the supplied Connection settings. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this sampler that is shown in the tree. | | Comments | No | Free text for additional details. | | Bolt URI | Yes | The database URI. | | Username | No | User account. | | Password | No | User credentials. | | Connection Pool Max Size | Yes | Max size of the Neo4j driver Bolt connection pool. Raise the value if running large number of concurrent threads, so that JMeter threads are not blocked waiting for a connection to be released to the pool. | [^](#) ## 18.5 Assertions Assertions are used to perform additional checks on samplers, and are processed after **every sampler** in the same scope. To ensure that an Assertion is applied only to a particular sampler, add it as a child of the sampler. :::note Note: Unless documented otherwise, Assertions are not applied to sub-samples (child samples) - only to the parent sample. In the case of JSR223 and BeanShell Assertions, the script can retrieve sub-samples using the method `prev.getSubResults()` which returns an array of SampleResults. The array will be empty if there are none. ::: Assertions can be applied to either the main sample, the sub-samples or both. The default is to apply the assertion to the main sample only. If the Assertion supports this option, then there will be an entry on the GUI which looks like the following: ![Assertion Scope](/images/screenshots/assertion/assertionscope.png) _Assertion Scope_ or the following ![Assertion Scope](/images/screenshots/assertion/assertionscopevar.png) _Assertion Scope_ If a sub-sampler fails and the main sample is successful, then the main sample will be set to failed status and an Assertion Result will be added. If the JMeter variable option is used, it is assumed to relate to the main sample, and any failure will be applied to the main sample only. :::note The variable `JMeterThread.last_sample_ok` is updated to "`true`" or "`false`" after all assertions for a sampler have been run. ::: ## Response Assertion ![Response Assertion](/images/screenshots/assertion/assertion.png) The response assertion control panel lets you add pattern strings to be compared against various fields of the request or response. The pattern strings are: - `Contains`, `Matches`: Perl5-style regular expressions - `Equals`, `Substring`: plain text, case-sensitive A summary of the pattern matching characters can be found at [ORO Perl5 regular expressions.](http://jakarta.apache.org/oro/api/org/apache/oro/text/regex/package-summary.html) You can also choose whether the strings will be expected to **match** the entire response, or if the response is only expected to **contain** the pattern. You can attach multiple assertions to any controller for additional flexibility. Note that the pattern string should not include the enclosing delimiters, i.e. use `Price: \d+` not `/Price: \d+/`. By default, the pattern is in multi-line mode, which means that the "`.`" meta-character does not match newline. In multi-line mode, "`^`" and "`$`" match the start or end of any line anywhere within the string - not just the start and end of the entire string. Note that `\s` does match new-line. Case is also significant. To override these settings, one can use the _extended regular expression_ syntax. For example: **`(?i)`** : ignore case **`(?s)`** : treat target as single line, i.e. "`.`" matches new-line **`(?is)`** : both the above These can be used anywhere within the expression and remain in effect until overridden. E.g. **`(?i)apple(?-i) Pie`** : matches "`ApPLe Pie`", but not "`ApPLe pIe`" **`(?s)Apple.+?Pie`** : matches `Apple` followed by `Pie`, which may be on a subsequent line. **`Apple(?s).+?Pie`** : same as above, but it's probably clearer to use the `(?s)` at the start. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - assertion is to be applied to the contents of the named variable | | Field to Test | Yes | Instructs JMeter which field of the Request or Response to test. - `Text Response` - the response text from the server, i.e. the body, excluding any HTTP headers. - `Request data` - the request text sent to the server, i.e. the body, excluding any HTTP headers. - `Response Code` - e.g. `200` - `Response Message` - e.g. `OK` - `Response Headers`, including Set-Cookie headers (if any) - `Request Headers` - `URL sampled` - `Document (text)` - the extract text from various type of documents via Apache Tika (see [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Document view section). | | Ignore status | Yes | Instructs JMeter to set the status to success initially. The overall success of the sample is determined by combining the result of the assertion with the existing Response status. When the `Ignore Status` checkbox is selected, the Response status is forced to successful before evaluating the Assertion. HTTP Responses with statuses in the `4xx` and `5xx` ranges are normally regarded as unsuccessful. The "`Ignore status`" checkbox can be used to set the status successful before performing further checks. :::note Note that this will have the effect of clearing any previous assertion failures, so make sure that this is only set on the first assertion. ::: | | Pattern Matching Rules | Yes | Indicates how the text being tested is checked against the pattern. - `Contains` - true if the text contains the regular expression pattern - `Matches` - true if the whole text matches the regular expression pattern - `Equals` - true if the whole text equals the pattern string (case-sensitive) - `Substring` - true if the text contains the pattern string (case-sensitive) `Equals` and `Substring` patterns are plain strings, not regular expressions. `NOT` may also be selected to invert the result of the check. `OR` Apply each assertion in OR combination (if 1 pattern to test matches, Assertion will be ok) instead of AND (All patterns must match so that Assertion is OK). | | Patterns to Test | Yes | A list of patterns to be tested. Each pattern is tested separately. If a pattern fails, then further patterns are not checked. There is no difference between setting up one Assertion with multiple patterns and setting up multiple Assertions with one pattern each (assuming the other options are the same). :::note However, when the `Ignore Status` checkbox is selected, this has the effect of cancelling any previous assertion failures - so make sure that the `Ignore Status` checkbox is only used on the first Assertion. ::: | | Custom failure message | No | Lets you define the failure message that will replace the generated one | The pattern is a Perl5-style regular expression, but without the enclosing brackets. #### Assertion Examples ![Figure 14 - Test Plan](/images/screenshots/assertion/example1a.png) _Figure 14 - Test Plan_ ![Figure 15 - Assertion Control Panel with Pattern](/images/screenshots/assertion/example1b.png) _Figure 15 - Assertion Control Panel with Pattern_ ![Figure 16 - Assertion Listener Results (Pass)](/images/screenshots/assertion/example1c-pass.png) _Figure 16 - Assertion Listener Results (Pass)_ ![Figure 17 - Assertion Listener Results (Fail)](/images/screenshots/assertion/example1c-fail.png) _Figure 17 - Assertion Listener Results (Fail)_ ## Duration Assertion ![Duration Assertion](/images/screenshots/duration_assertion.png) The Duration Assertion tests that each response was received within a given amount of time. Any response that takes longer than the given number of milliseconds (specified by the user) is marked as a failed response. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Duration in Milliseconds | Yes | The maximum number of milliseconds each response is allowed before being marked as failed. | ## Size Assertion ![Size Assertion](/images/screenshots/size_assertion.png) The Size Assertion tests that each response contains the right number of bytes in it. You can specify that the size be equal to, greater than, less than, or not equal to a given number of bytes. :::note An empty response is treated as being 0 bytes rather than reported as an error. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - assertion only applies to the main sample - `Sub-samples only` - assertion only applies to the sub-samples - `Main sample and sub-samples` - assertion applies to both. - `JMeter Variable Name to use` - assertion is to be applied to the contents of the named variable | | Size in bytes | Yes | The number of bytes to use in testing the size of the response (or value of the JMeter variable). | | Type of Comparison | Yes | Whether to test that the response is equal to, greater than, less than, or not equal to, the number of bytes specified. | ## XML Assertion ![XML Assertion](/images/screenshots/xml_assertion.png) The XML Assertion tests that the response data consists of a formally correct XML document. It does not validate the XML based on a DTD or schema or do any further validation. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | ## BeanShell Assertion ![BeanShell Assertion](/images/screenshots/beanshell_assertion.png) The BeanShell Assertion allows the user to perform assertion checking using a BeanShell script. **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 Assertion](/user-manual/component-reference/#JSR223_Assertion)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: Note that a different Interpreter is used for each independent occurrence of the assertion in each thread in a test script, but the same Interpreter is used for subsequent invocations. This means that variables persist across calls to the assertion. All Assertions are called from the same thread as the sampler. If the property "`beanshell.assertion.init`" is defined, it is passed to the Interpreter as the name of a sourced file. This can be used to define common methods and variables. There is a sample init file in the `bin` directory: `BeanShellAssertion.bshrc` The test element supports the `ThreadListener` and `TestListener` methods. These should be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. The name is stored in the script variable `Label` | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `bsh.args` - String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. This overrides the script. The file name is stored in the script variable `FileName` | | Script | Yes (unless script file is provided) | The BeanShell script to run. The return value is ignored. | There's a [sample script](../demos/BeanShellAssertion.bsh) you can try. Before invoking the script, some variables are set up in the BeanShell interpreter. These are strings unless otherwise noted: - `log` - the [Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) Object. (e.g.) `log.warn("Message"[,Throwable])` - `SampleResult`, `prev` - the [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html) Object; read-write - `Response` - the response Object; read-write - `Failure` - boolean; read-write; used to set the Assertion status - `FailureMessage` - String; read-write; used to set the Assertion message - `ResponseData` - the response body (byte []) - `ResponseCode` - e.g. `200` - `ResponseMessage` - e.g. `OK` - `ResponseHeaders` - contains the HTTP headers - `RequestHeaders` - contains the HTTP headers sent to the server - `SampleLabel` - `SamplerData` - data that was sent to the server - `ctx` - [JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html) - `vars` - [JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html) - e.g. ``` vars.get("VAR1"); vars.put("VAR2","value"); vars.putObject("OBJ1",new Object()); ``` - `props` - JMeterProperties (class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. ``` props.get("START.HMS"); props.put("PROP1","1234"); ``` The following methods of the Response object may be useful: - `setStopThread(boolean)` - `setStopTest(boolean)` - `String getSampleLabel()` - `setSampleLabel(String)` ## MD5Hex Assertion ![MD5Hex Assertion](/images/screenshots/assertion/MD5HexAssertion.png) The MD5Hex Assertion allows the user to check the MD5 hash of the response data. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | MD5 sum | Yes | 32 hex digits representing the MD5 hash (case not significant) | ## HTML Assertion ![HTML Assertion](/images/screenshots/assertion/HTMLAssertion.png) The HTML Assertion allows the user to check the HTML syntax of the response data using JTidy. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | doctype | Yes | `omit`, `auto`, `strict` or `loose` | | Format | Yes | `HTML`, `XHTML` or `XML` | | Errors only | Yes | Only take note of errors? | | Error threshold | Yes | Number of errors allowed before classing the response as failed | | Warning threshold | Yes | Number of warnings allowed before classing the response as failed | | Filename | No | Name of file to which report is written | ## XPath Assertion ![XPath Assertion](/images/screenshots/xpath_assertion.png) The XPath Assertion tests a document for well formedness, has the option of validating against a DTD, or putting the document through JTidy and testing for an XPath. If that XPath exists, the Assertion is true. Using "`/`" will match any well-formed document, and is the default XPath Expression. The assertion also supports boolean expressions, such as "`count(//*error)=2`". See [http://www.w3.org/TR/xpath](http://www.w3.org/TR/xpath) for more information on XPath. Some sample expressions: - `//title[text()='Text to match']` - matches `<title>Text to match</title>` anywhere in the response - `/title[text()='Text to match']` - matches `<title>Text to match</title>` at root level in the response | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Use Tidy (tolerant parser) | Yes | Use Tidy, i.e. be tolerant of XML/HTML errors | | Quiet | If Tidy is selected | Sets the Tidy Quiet flag | | Report Errors | If Tidy is selected | If a Tidy error occurs, then set the Assertion accordingly | | Show warnings | If Tidy is selected | Sets the Tidy showWarnings option | | Use Namespaces | If Tidy is not selected | Should namespaces be honoured? (see note below on NAMESPACES) | | Validate XML | If Tidy is not selected | Check the document against its schema. | | Ignore Whitespace | If Tidy is not selected | Ignore Element Whitespace. | | Fetch External DTDs | If Tidy is not selected | If selected, external DTDs are fetched. | | XPath Assertion | Yes | XPath to match in the document. | | Invert assertion(will fail if above conditions met) | No | True if a XPath expression is not matched or returns false | :::note The non-tolerant parser can be quite slow, as it may need to download the DTD etc. ::: :::note **NAMESPACES** As a work-round for namespace limitations of the Xalan XPath parser (implementation on which JMeter is based) you need to: - provide a Properties file (if for example your file is named `namespaces.properties`) which contains mappings for the namespace prefixes: ``` prefix1=http\://foo.apache.org prefix2=http\://toto.apache.org … ``` - reference this file in `user.properties` file using the property: ``` xpath.namespace.config=namespaces.properties ``` ::: ## XPath2 Assertion ![XPath2 Assertion](/images/screenshots/xpath_assertion.png) The XPath2 Assertion tests a document for well formedness. Using "`/`" will match any well-formed document, and is the default XPath2 Expression. The assertion also supports boolean expressions, such as "`count(//*error)=2`". Some sample expressions: - `//title[text()='Text to match']` - matches `<title>Text to match</title>` anywhere in the response - `/title[text()='Text to match']` - matches `<title>Text to match</title>` at root level in the response | Name | Required | Description | |------|----------|-------------| | Namespaces aliases list | No | List of namespaces aliases you want to use to parse the document, one line per declaration. You must specify them as follow: `prefix=namespace`. This implementation makes it easier to use namespaces than with the old XPathExtractor version. | | XPath2 Assertion | Yes | XPath to match in the document. | | Invert assertion | No | Will fail if xpath expression returns true or matches, succeed otherwise | | Namespace aliases list | No | List of namespace aliases prefix=full namespace (one per line) | ## XML Schema Assertion ![XML Schema Assertion](/images/screenshots/assertion/XMLSchemaAssertion.png) The XML Schema Assertion allows the user to validate a response against an XML Schema. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | File Name | Yes | Specify XML Schema File Name | ## JSR223 Assertion The JSR223 Assertion allows JSR223 script code to be used to check the status of the previous sample. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Language | Yes | The JSR223 language to be used | | Parameters | No | Parameters to pass to the script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `args` - String array containing parameters, split on white-space | | Script file | No | A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property | | Script compilation caching | No | Unique String across Test Plan that JMeter will use to cache result of Script compilation if language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, BeanShell and JavaScript are not) :::note See note in JSR223 Sampler Java System property if you're using Groovy without checking this option ::: | | Script | Yes (unless script file is provided) | The script to run. | The following variables are set up for use by the script: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `Label` - the String Label - `Filename` - the script file name (if any) - `Parameters` - the parameters (as a String) - `args` - the parameters as a String array (split on whitespace) - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); vars.getObject("OBJ2"); ``` - `props` - (JMeterProperties - class [`java.util.Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)) - e.g. ``` props.get("START.HMS"); props.put("PROP1","1234"); ``` - `SampleResult`, `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous SampleResult (if any) - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html)) - gives access to the current sampler - `OUT` - `System.out` - e.g. `OUT.println("message")` - `AssertionResult` - ([AssertionResult](https://jmeter.apache.org/api/org/apache/jmeter/assertions/AssertionResult.html)) - the assertion result The script can check various aspects of the [SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html). If an error is detected, the script should use `AssertionResult.setFailureMessage("message")` and `AssertionResult.setFailure(true)`. For further details of all the methods available on each of the above variables, please check the Javadoc ## Compare Assertion ![Compare Assertion](/images/screenshots/assertion/compare.png) :::note Compare Assertion **must not be used** during load test as it consumes a lot of resources (memory and CPU). Use it only for either functional testing or during Test Plan debugging and Validation. ::: The Compare Assertion can be used to compare sample results within its scope. Either the contents or the elapsed time can be compared, and the contents can be filtered before comparison. The assertion comparisons can be seen in the [Comparison Assertion Visualizer](/user-manual/component-reference/#Comparison_Assertion_Visualizer). | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Compare Content | Yes | Whether or not to compare the content (response data) | | Compare Time | Yes | If the value is ≥0, then check if the response time difference is no greater than the value. I.e. if the value is `0`, then the response times must be exactly equal. | | Comparison Filters | No | Filters can be used to remove strings from the content comparison. For example, if the page has a time-stamp, it might be matched with: "`Time: \d\d:\d\d:\d\d`" and replaced with a dummy fixed time "`Time: HH:MM:SS`". | ## SMIME Assertion ![SMIME Assertion](/images/screenshots/assertion/smime.png) The SMIME Assertion can be used to evaluate the sample results from the Mail Reader Sampler. This assertion verifies if the body of a mime message is signed or not. The signature can also be verified against a specific signer certificate. As this is a functionality that is not necessarily needed by most users, additional jars need to be downloaded and added to `JMETER_HOME/lib`: - `bcmail-xxx.jar` (BouncyCastle SMIME/CMS) - `bcprov-xxx.jar` (BouncyCastle Provider) These need to be [downloaded from BouncyCastle.](http://www.bouncycastle.org/latest_releases.html) If using the [Mail Reader Sampler](/user-manual/component-reference/#Mail_Reader_Sampler), please ensure that you select "`Store the message using MIME (raw)`" otherwise the Assertion won't be able to process the message correctly. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Verify Signature | Yes | If selected, the assertion will verify if it is a valid signature according to the parameters defined in the `Signer Certificate` box. | | Message not signed | Yes | Whether or not to expect a signature in the message | | Signer Certificate | Yes | "`No Check`" means that it will not perform signature verification. "`Check values`" is used to verify the signature against the inputs provided. And "`Certificate file`" will perform the verification against a specific certificate file. | | Message Position | Yes | The Mail sampler can retrieve multiple messages in a single sample. Use this field to specify which message will be checked. Messages are numbered from `0`, so `0` means the first message. Negative numbers count from the LAST message; `-1` means LAST, `-2` means penultimate etc. | ## JSON Assertion ![JSON Assertion](/images/screenshots/assertion/json_assertion.png) This component allows you to perform validations of JSON documents. First, it will parse the JSON and fail if the data is not JSON. Second, it will search for specified path, using syntax from [Jayway JsonPath 1.2.0](https://github.com/json-path/JsonPath). If the path is not found, it will fail. Third, if JSON path was found in the document, and validation against expected value was requested, it will perform validation. For the `null` value there is special checkbox in the GUI. Note that if the path will return array object, it will be iterated and if expected value is found, the assertion will succeed. To validate empty array use `[]` string. Also, if patch will return dictionary object, it will be converted to string before comparison. :::note When using [indefinite JSON Paths](https://github.com/json-path/JsonPath#what-is-returned-when) you must assert the value due to the existing JSON library implementation, otherwise the assertion could always return successful. Since JMeter version 5.5 the assertion will fail, if an indefinite path is given, an empty list is extracted and no assertion value is set. ::: | Name | Required | Description | |------|----------|-------------| | Assert JSON Path exists | Yes | Path to JSON element for assert. | | Additionally assert value | No | Select checkbox if you want make assert with some value | | Match as regular expression | No | Select checkbox if you want use regular expression | | Expected Value | No | Value for assert or regular expression for match | | Expect null | No | Select checkbox if you expect null | | Invert assertion (will fail if above conditions met) | No | Invert assertion (will fail if above conditions met) | ## JSON JMESPath Assertion ![JSON JMESPath Assertion](/images/screenshots/assertion/jmespath_assertion.png) This component allows you to perform assertion on JSON documents content using [JMESPath](http://jmespath.org/). First, it will parse the JSON and fail if the data is not JSON. Second, it will search for specified path, using JMESPath syntax. If the path is not found, it will fail. Third, if JMES path was found in the document, and validation against expected value was requested, it will perform this additional check. If you want to check for nullity, use the `Expect null` checkbox. Note that the path cannot be null as the expression JMESPath will not be compiled and an error will occur. Even if you expect an empty or null response, you must put a valid JMESPath expression. | Name | Required | Description | |------|----------|-------------| | Assert JMESPath exists | Yes | Check that JMESPath to JSON element exists | | Additionally assert value | No | Select checkbox if you check the extracted JMESPath against an expected one | | Match as regular expression | No | Select checkbox if you want to use a regular expression for matching | | Expected Value | No | Value to use for exact matching or regular expression if `Match as regular expression` is checked | | Expect null | No | Select checkbox if you expect the value to be null | | Invert assertion (will fail if above conditions met) | No | Invert assertion (will fail if above conditions met) | [^](#) ## 18.6 Timers :::note Since version 3.1, a new feature (in Beta mode as of JMeter 3.1 and subject to changes) has been implemented which provides the following feature. You can apply a multiplication factor on the sleep delays computed by Random timer by setting property `timer.factor=float number` where float number is a decimal positive number. JMeter will multiply this factor by the computed sleep delay. This feature can be used by: - [Gaussian Random Timer](/user-manual/component-reference/#Gaussian_Random_Timer) - [Poisson Random Timer](/user-manual/component-reference/#Poisson_Random_Timer) - [Uniform Random Timer](/user-manual/component-reference/#Uniform_Random_Timer) ::: :::note Note that timers are processed **before** each sampler in the scope in which they are found; if there are several timers in the same scope, **all** the timers will be processed before each sampler. Timers are only processed in conjunction with a sampler. A timer which is not in the same scope as a sampler will not be processed at all. To apply a timer to a single sampler, add the timer as a child element of the sampler. The timer will be applied before the sampler is executed. To apply a timer after a sampler, either add it to the next sampler, or add it as the child of a [Flow Control Action](/user-manual/component-reference/#Flow_Control_Action) Sampler. ::: ## Constant Timer ![Constant Timer](/images/screenshots/timers/constant_timer.png) If you want to have each thread pause for the same amount of time between requests, use this timer. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree. | | Thread Delay | Yes | Number of milliseconds to pause. | ## Gaussian Random Timer ![Gaussian Random Timer](/images/screenshots/timers/gauss_random_timer.png) This timer pauses each thread request for a random amount of time, with most of the time intervals occurring near a particular value. The total delay is the sum of the Gaussian distributed value (with mean `0.0` and standard deviation `1.0`) times the deviation value you specify, and the offset value. Another way to explain it, in Gaussian Random Timer, the variation around constant offset has a Gaussian curve distribution. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree | | Deviation | Yes | Deviation in milliseconds. | | Constant Delay Offset | Yes | Number of milliseconds to pause in addition to the random delay. | ## Uniform Random Timer ![Uniform Random Timer](/images/screenshots/timers/uniform_random_timer.png) This timer pauses each thread request for a random amount of time, with each time interval having the same probability of occurring. The total delay is the sum of the random value and the offset value. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree. | | Random Delay Maximum | Yes | Maximum random number of milliseconds to pause. | | Constant Delay Offset | Yes | Number of milliseconds to pause in addition to the random delay. | ## Constant Throughput Timer ![Constant Throughput Timer](/images/screenshots/timers/constant_throughput_timer.png) This timer introduces variable pauses, calculated to keep the total throughput (in terms of samples per minute) as close as possible to a given figure. Of course the throughput will be lower if the server is not capable of handling it, or if other timers or time-consuming test elements prevent it. N.B. although the Timer is called the Constant Throughput timer, the throughput value does not need to be constant. It can be defined in terms of a variable or function call, and the value can be changed during a test. The value can be changed in various ways: - using a counter variable - using a `__jexl3`, `__groovy` function to provide a changing value - using the remote BeanShell server to change a JMeter property See [Best Practices](/user-manual/best-practices/) for further details. :::note Note that the throughput value should not be changed too often during a test - it will take a while for the new value to take effect. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree. | | Target Throughput | Yes | Throughput we want the timer to try to generate. | | Calculate Throughput based on | Yes | - `this thread only` - each thread will try to maintain the target throughput. The overall throughput will be proportional to the number of active threads. - `all active threads in current thread group` - the target throughput is divided amongst all the active threads in the group. Each thread will delay as needed, based on when it last ran. - `all active threads` - the target throughput is divided amongst all the active threads in all Thread Groups. Each thread will delay as needed, based on when it last ran. In this case, each other Thread Group will need a Constant Throughput timer with the same settings. - `all active threads in current thread group (shared)` - as above, but each thread is delayed based on when any thread in the group last ran. - `all active threads (shared)` - as above; each thread is delayed based on when any thread last ran. | ## Precise Throughput Timer ![Precise Throughput Timer](/images/screenshots/timers/precise_throughput_timer.png) This timer introduces variable pauses, calculated to keep the total throughput (e.g. in terms of samples per minute) as close as possible to a given figure. The timer does not generate threads, so the resulting throughput will be lower if the server is not capable of handling it, or if other timers add too big delays, or if there's not enough threads, or time-consuming test elements prevent it. :::note Note: in many cases, Open Model Thread Group would be a better choice for generating the desired load profile ::: :::note Note: if you alter timer configuration on the fly, then it might take time to adapt to the new settings. For instance, if the timer was initially configured for 1 request per hour, then it assigns incoming threads with 3600+sec pauses. Then, if the load configuration is altered to 1 per second, then the threads are not interrupted from their delays, and the threads keep waiting. ::: Although the Timer is called Precise Throughput Timer, it does not aim to produce precisely the same number of samples over one-second intervals during the test. The timer works best for rates under 36000 requests/hour, however your mileage might vary (see monitoring section below if your goals are vastly different). ##### Best location of a Precise Throughput Timer in a Test Plan As you might know, the timers are inherited by all the siblings and their child elements. That is why one of the best places for `Precise Throughput Timer` is under the first element in a test loop. For instance, you might add a dummy sampler at the beginning, and place the timer under that dummy sampler ##### Produced schedule `Precise Throughput Timer` models [Poisson arrivals](https://en.wikipedia.org/wiki/Poisson_point_process) schedule. That schedule often happens in a real-life, so it makes sense to use that for load testing. For instance, it naturally might generate samples that are close together thus it might reveal concurrency issues. Even if you manage to generate Poisson arrivals with [Poisson Random Timer](/user-manual/component-reference/#Poisson_Random_Timer), it would be susceptible to the issues listed below. For instance, true Poisson arrivals might have indefinitely long pause, and that is not practical for load testing. For instance, "regular" Poisson arrivals with 1 per second rate might end up with 50 samples over 60 second long test. [Constant Throughput Timer](/user-manual/component-reference/#Constant_Throughput_Timer) converges to the specified rate, however it tends to produce samples at even intervals. ##### Ramp-up and startup spike You might used "ramp-up" or similar approaches to avoid a spike at the test start. For instance, if you configure [Thread Group](/user-manual/component-reference/#Thread_Group) to have 100 threads, and set `Ramp-up Period` to `0` (or to a small number), then all the threads would start at the same time, and it would produce an unwanted spike of the load. On top of that, if you set `Ramp-up Period` too high, it might result in "_too few_" threads being available at the very beginning to achieve the required load. `Precise Throughput Timer` schedules executions in a random way, so it can be used to generate constant load, and it is recommended to set both `Ramp-up Period` and `Delay` to `0`. ##### Multiple thread groups starting at the same time A variation of `Ramp-up` issue might appear when [Test Plan](/user-manual/component-reference/#Test_Plan) includes multiple [Thread Group](/user-manual/component-reference/#Thread_Group)s. To mitigate that issue one typically adds "random" delay to each [Thread Group](/user-manual/component-reference/#Thread_Group) so threads start at different times. `Precise Throughput Timer` avoids that issue since it schedules executions in a random way. You do not need to add extra random delays to mitigate startup spike ##### Number of iterations per hour One of the basic requirements is to issue N samples per M minutes. Let it be 60 iterations per hour. Business customers would not understand if you report load test results with 57 executions "just because the random was random". In order to generate 60 iterations per hour, you need to configure as follows (other parameters could be left with their default values) - `Target throughput (samples)`: 60 - `Throughput period (seconds)`: 3600 - `Test duration (seconds)`: 3600 The first two options set the throughput. Even though 60/3600, 30/1800, and 120/7200 represent exactly the same load level, pick the one that represents business requirements better. For instance, if the requirement is to test for "60 sample per hour", then set 60/3600. If the requirement is to test "1 sample per minute", then set 1/60. `Test duration (seconds)` is there so the timer ensures exact number of samples for a given test duration. `Precise Throughput Timer` creates a schedule for the samples at the test startup. For instance, if you wish to perform 5 minutes test with 60 per hour throughput, you would set `Test duration (seconds)` to 300. This enables to configure throughput in a business-friendly way. Note: `Test duration (seconds)` does **not** limit test duration. It is just a hint for the timer. ##### Number of threads and think times One of the common pitfalls is to adjust number of threads and think times in order to end up with the desired throughput. Even though it might work, that approach results in lots of time spent on the test runs. It might require to adjust threads and delays again when new application version arrives. `Precise Throughput Timer` enables to set throughput goal and go for it no matter how well application performs. In order to do that, `Precise Throughput Timer` creates a schedule at the test startup, then it uses that schedule to release threads. The main driver for the think times and number of threads should be business requirements, not the desire to match throughput somehow. For instance, if you application is used by support engineers in a call center. Suppose there are 2 engineers in the call center, and the target throughput is 1 per minute. Suppose it takes 4 minutes for the engineer to read and review the web page. For that case you should set 2 threads in the group, use 4 minutes for think time delays, and specify 1 per minute in `Precise Throughput Timer`. Of course it would result in something around 2samples/4minutes=0.5 per minute and the result of such a test means "you need more support engineers in a call center" or "you need to reduce the time it takes an engineer to fulfill a task". ##### Testing low rates and repeatable tests Testing at low rates (e.g. 60 per hour) requires to know the desired test profile. For instance, if you need to inject load at even intervals (e.g. 60 seconds in between) then you'd better use [Constant Throughput Timer](/user-manual/component-reference/#Constant_Throughput_Timer). However, if you need to have randomized schedule (e.g. to model real users that execute reports), then `Precise Throughput Timer` is your friend. When comparing outcomes of multiple load tests, it is useful to be able to repeat exactly the same test profile. For instance, if action X (e.g. "Profit Report") is invoked after 5 minutes of the test start, then it would be nice to replicate that pattern for subsequent test executions. Replicating the same load pattern simplifies analysis of the test results (e.g. CPU% chart). `Random seed (change from 0 to random)` enables to control the seed value that is used by `Precise Throughput Timer`. By default it is initialized with `0` and that means random seed is used for each test execution. If you need to have repeatable load pattern, then change `Random seed` so some random value. The general advice is to use non-zero seed, and "0 by default" is an implementation limit. Note: when using multiple thread groups with same throughput rates and same non-zero seed it might result in unwanted firing the samples at the same time. ##### Testing high rates and/or long test durations `Precise Throughput Timer` generates the schedule and keeps it in memory. In most cases it should not be a problem, however, remember that you might want to keep the schedule shorter than 1'000'000 samples. It takes ~200ms to generate a schedule for 1'000'000 samples, and the schedule consumes 8 megabytes in the heap. Schedule for 10 million entries takes 1-2 second to build and it consumes 80 megabytes in the heap. For instance, if you want to perform 2-week long test with 5'000 per hour rate, then you probably want to have exactly 5'000 samples for each hour. You can set `Test duration (seconds)` property of the timer of the timer to 1 hour. Then the timer would create a schedule of 5'000 samples for an hour, and when the schedule is exhausted, the timer would generate a schedule for the next hour. At the same time, you can set `Test duration (seconds)` to 2 weeks, and the timer would generate a schedule with `168'000 samples = 2 weeks * 5'000 samples/hour = 2*7*24*500`. The schedule would take ~30ms to generate, and it would consume a little more than 1 megabyte. ##### Bursty load There might be a case when all the samples should come in pairs, triples, etc. Certain cases might be solved via [Synchronizing Timer](/user-manual/component-reference/#Synchronizing_Timer), however `Precise Throughput Timer` has native way to issue requests in packs. This behavior is disabled by default, and it is controlled with "Batched departures" settings - `Number of threads in the batch (threads)`. Specifies the number of samples in a batch. Note the overall number of samples will still be in line with `Target Throughput` - `Delay between threads in the batch (ms)`. For instance, if set to 42, and the batch size is 3, then threads will depart at x, x+42ms, x+84ms ##### Variable load rate Even though property values (e.g. throughput) can be defined via expressions, it is recommended to keep the value more or less the same through the test, as it takes time to recompute the new schedule to adapt new values. ##### Monitoring As next schedule is generated, `Precise Throughput Timer` logs a message to `jmeter.log`: `2018-01-04 17:34:03,635 INFO o.a.j.t.ConstantPoissonProcessGenerator: Generated 21 timings (... 20 required, rate 1.0, duration 20, exact lim 20000, i21) in 0 ms. First 15 events will be fired at: 1.1869653574244292 (+1.1869653574244292), 1.4691340403043207 (+0.2821686828798915), 3.638151706179226 (+2.169017665874905), 3.836357090410566 (+0.19820538423134026), 4.709330071408575 (+0.8729729809980085), 5.61330076999953 (+0.903970698590955), ...` This shows that schedule generation took 0ms, and it shows absolute timestamps in seconds. In the case above, the rate was set to be 1 per second, and the actual timestamps became 1.2 sec, 1.5 sec, 3.6 sec, 3.8 sec, 4.7 sec, and so on. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree | | Target throughput (in samples per 'throughput period') | Yes | Maximum number of samples you want to obtain per "throughput period", including all threads in group, from all affected samplers. | | Throughput period (seconds) | Yes | Throughput period. For example, if "throughput" is set to 42 and "throughput period" to 21 sec, then you'll get 2 samples per second. | | Test duration (seconds) | Yes | This is used to ensure you'll get throughput*duration samples during "test duration" timeframe. | | Number of threads in the batch (threads) | Yes | If the value exceeds 1, then multiple threads depart from the timer simultaneously. Average throughput still meets "throughput" value. | | Delay between threads in the batch (ms) | Yes | For instance, if set to 42, and the batch size is 3, then threads will depart at x, x+42ms, x+84ms. | | Random seed (change from 0 to random) | Yes | Note: different timers should better have different seed values. Constant seed ensures timer generates the same delays each test start. The value of "0" means the timer is truly random (non-repeatable from one execution to another).. | ## Synchronizing Timer ![Synchronizing Timer](/images/screenshots/timers/sync_timer.png) The purpose of the SyncTimer is to block threads until X number of threads have been blocked, and then they are all released at once. A SyncTimer can thus create large instant loads at various points of the test plan. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree. | | Number of Simultaneous Users to Group by | Yes | Number of threads to release at once. Setting it to `0` is equivalent to setting it to Number of threads in Thread Group. | | Timeout in milliseconds | No | If set to `0`, Timer will wait for the number of threads to reach the value in "`Number of Simultaneous Users to Group`". If superior to `0`, then timer will wait at max "`Timeout in milliseconds`" for the number of Threads. If after the timeout interval the number of users waiting is not reached, timer will stop waiting. Defaults to `0` | :::note If timeout in milliseconds is set to `0` and number of threads never reaches "`Number of Simultaneous Users to Group by`" then Test will pause infinitely. Only a forced stop will stop it. Setting Timeout in milliseconds is an option to consider in this case. ::: :::note Synchronizing timer blocks only within one JVM, so if using Distributed testing ensure you never set "`Number of Simultaneous Users to Group by`" to a value superior to the number of users of its containing Thread group considering 1 injector only. ::: ## BeanShell Timer ![BeanShell Timer](/images/screenshots/timers/beanshell_timer.png) The BeanShell Timer can be used to generate a delay. **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 Timer](/user-manual/component-reference/#JSR223_Timer)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: The test element supports the `ThreadListener` and `TestListener` methods. These should be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. The name is stored in the script variable `Label` | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `bsh.args` - String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. The file name is stored in the script variable `FileName` The return value is used as the number of milliseconds to wait. | | Script | Yes (unless script file is provided) | The BeanShell script. The return value is used as the number of milliseconds to wait. | Before invoking the script, some variables are set up in the BeanShell interpreter: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous `SampleResult` (if any) For details of all the methods available on each of the above variables, please check the Javadoc If the property `beanshell.timer.init` is defined, this is used to load an initialisation file, which can be used to define methods etc. for use in the BeanShell script. ## JSR223 Timer The JSR223 Timer can be used to generate a delay using a JSR223 scripting language, | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | ScriptLanguage | Yes | The scripting language to be used. | | Parameters | No | Parameters to pass to the script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `args` - String array containing parameters, split on white-space | | Script file | No | A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property The return value is converted to a long integer and used as the number of milliseconds to wait. | | Script compilation caching | No | Unique String across Test Plan that JMeter will use to cache result of Script compilation if language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not) :::note See note in JSR223 Sampler Java System property if you're using Groovy without checking this option ::: | | Script | Yes (unless script file is provided) | The script. The return value is used as the number of milliseconds to wait. | Before invoking the script, some variables are set up in the script interpreter: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html)) - the current Sampler - `Label` - the name of the Timer - `FileName` - the file name (if any) - `OUT` - System.out For details of all the methods available on each of the above variables, please check the Javadoc ## Poisson Random Timer ![Poisson Random Timer](/images/screenshots/timers/poisson_random_timer.png) This timer pauses each thread request for a random amount of time, with most of the time intervals occurring near a particular value. The total delay is the sum of the Poisson distributed value, and the offset value. Note: if you want to model Poisson arrivals, consider using [Precise Throughput Timer](/user-manual/component-reference/#Precise_Throughput_Timer) instead. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree | | Lambda | Yes | Lambda value in milliseconds. | | Constant Delay Offset | Yes | Number of milliseconds to pause in addition to the random delay. | [^](#) ## 18.7 Pre Processors Preprocessors are used to modify the Samplers in their scope. ## HTML Link Parser ![HTML Link Parser](/images/screenshots/html_link_parser.png) This modifier parses HTML response from the server and extracts links and forms. A URL test sample that passes through this modifier will be examined to see if it "matches" any of the links or forms extracted from the immediately previous response. It would then replace the values in the URL test sample with appropriate values from the matching link or form. Perl-type regular expressions are used to find matches. :::note Matches are performed using `protocol`, `host`, `path` and `parameter names`. The target sampler cannot contain parameters that are not in the response links. ::: :::note If using distributed testing, ensure you switch mode (see `jmeter.properties`) so that it's not a stripping one, see [Bug 56376](https://bz.apache.org/bugzilla/show_bug.cgi?id=56376) ::: #### Spidering Example Consider a simple example: let's say you wanted JMeter to "spider" through your site, hitting link after link parsed from the HTML returned from your server (this is not actually the most useful thing to do, but it serves as a good example). You would create a [Simple Controller](/user-manual/component-reference/#Simple_Controller), and add the "HTML Link Parser" to it. Then, create an HTTP Request, and set the domain to "`.*`", and the path likewise. This will cause your test sample to match with any link found on the returned pages. If you wanted to restrict the spidering to a particular domain, then change the domain value to the one you want. Then, only links to that domain will be followed. #### Poll Example A more useful example: given a web polling application, you might have a page with several poll options as radio buttons for the user to select. Let's say the values of the poll options are very dynamic - maybe user generated. If you wanted JMeter to test the poll, you could either create test samples with hardcoded values chosen, or you could let the HTML Link Parser parse the form, and insert a random poll option into your URL test sample. To do this, follow the above example, except, when configuring your Web Test controller's URL options, be sure to choose "`POST`" as the method. Put in hard-coded values for the `domain`, `path`, and any additional form parameters. Then, for the actual radio button parameter, put in the name (let's say it's called "`poll_choice`"), and then "`.*`" for the value of that parameter. When the modifier examines this URL test sample, it will find that it "matches" the poll form (and it shouldn't match any other form, given that you've specified all the other aspects of the URL test sample), and it will replace your form parameters with the matching parameters from the form. Since the regular expression "`.*`" will match with anything, the modifier will probably have a list of radio buttons to choose from. It will choose at random, and replace the value in your URL test sample. Each time through the test, a new random value will be chosen. ![Figure 18 - Online Poll Example](/images/screenshots/modification.png) _Figure 18 - Online Poll Example_ :::note One important thing to remember is that you must create a test sample immediately prior that will return an HTML page with the links and forms that are relevant to your dynamic test sample. ::: ## HTTP URL Re-writing Modifier ![HTTP URL Re-writing Modifier](/images/screenshots/url_rewriter.png) This modifier works similarly to the HTML Link Parser, except it has a specific purpose for which it is easier to use than the HTML Link Parser, and more efficient. For web applications that use URL Re-writing to store session ids instead of cookies, this element can be attached at the ThreadGroup level, much like the [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager). Simply give it the name of the session id parameter, and it will find it on the page and add the argument to every request of that ThreadGroup. Alternatively, this modifier can be attached to select requests and it will modify only them. Clever users will even determine that this modifier can be used to grab values that elude the [HTML Link Parser](/user-manual/component-reference/#HTML_Link_Parser). | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name given to this element in the test tree. | | Session Argument Name | Yes | The name of the parameter to grab from previous response. This modifier will find the parameter anywhere it exists on the page, and grab the value assigned to it, whether it's in an HREF or a form. | | Path Extension | No | Some web apps rewrite URLs by appending a semi-colon plus the session id parameter. Check this box if that is so. | | Do not use equals in path extension | No | Some web apps rewrite URLs without using an "`=`" sign between the parameter name and value (such as Intershop Enfinity). | | Do not use questionmark in path extension | No | Prevents the query string to end up in the path extension (such as Intershop Enfinity). | | Cache Session Id | Yes | Should the value of the session Id be saved for later use when the session Id is not present? | | URL Encode | No | URL Encode value when writing parameter | :::note If using distributed testing, ensure you switch mode (see `jmeter.properties`) so that it's not a stripping one, see [Bug 56376](https://bz.apache.org/bugzilla/show_bug.cgi?id=56376). ::: ## User Parameters ![User Parameters](/images/screenshots/user_params.png) Allows the user to specify values for User Variables specific to individual threads. User Variables can also be specified in the Test Plan but not specific to individual threads. This panel allows you to specify a series of values for any User Variable. For each thread, the variable will be assigned one of the values from the series in sequence. If there are more threads than values, the values get re-used. For example, this can be used to assign a distinct user id to be used by each thread. User variables can be referenced in any field of any JMeter Component. The variable is specified by clicking the `Add Variable` button in the bottom of the panel and filling in the Variable name in the '`Name:`' column. To add a new value to the series, click the '`Add User`' button and fill in the desired value in the newly added column. Values can be accessed in any test component in the same thread group, using the [function syntax](/user-manual/functions/): `\${variable}`. See also the [CSV Data Set Config](/user-manual/component-reference/#CSV_Data_Set_Config) element, which is more suitable for large numbers of parameters | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Update Once Per Iteration | Yes | A flag to indicate whether the User Parameters element should update its variables only once per iteration. if you embed functions into the UP, then you may need greater control over how often the values of the variables are updated. Keep this box checked to ensure the values are updated each time through the UP's parent controller. Uncheck the box, and the UP will update the parameters for every sample request made within its [scope](/user-manual/test-plan/#scoping_rules). | ## BeanShell PreProcessor ![BeanShell PreProcessor](/images/screenshots/beanshell_preprocessor.png) The BeanShell PreProcessor allows arbitrary code to be applied before taking a sample. **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 PreProcessor](/user-manual/component-reference/#JSR223_PreProcessor)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: The test element supports the `ThreadListener` and `TestListener` methods. These should be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. The name is stored in the script variable `Label` | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `bsh.args` - String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. The file name is stored in the script variable `FileName` | | Script | Yes (unless script file is provided) | The BeanShell script. The return value is ignored. | Before invoking the script, some variables are set up in the BeanShell interpreter: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous SampleResult (if any) - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html))- gives access to the current sampler For details of all the methods available on each of the above variables, please check the Javadoc If the property `beanshell.preprocessor.init` is defined, this is used to load an initialisation file, which can be used to define methods etc. for use in the BeanShell script. ## JSR223 PreProcessor The JSR223 PreProcessor allows JSR223 script code to be applied before taking a sample. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Language | Yes | The JSR223 language to be used | | Parameters | No | Parameters to pass to the script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `args` - String array containing parameters, split on white-space | | Script file | No | A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property | | Script compilation caching | No | Unique String across Test Plan that JMeter will use to cache result of Script compilation if language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not) :::note See note in JSR223 Sampler Java System property if you're using Groovy without checking this option ::: | | Script | Yes (unless script file is provided) | The script to run. | The following JSR223 variables are set up for use by the script: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `Label` - the String Label - `FileName` - the script file name (if any) - `Parameters` - the parameters (as a String) - `args` - the parameters as a String array (split on whitespace) - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); vars.getObject("OBJ2"); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html))- gives access to the current sampler - `OUT` - System.out - e.g. `OUT.println("message")` For details of all the methods available on each of the above variables, please check the Javadoc ## JDBC PreProcessor The JDBC PreProcessor enables you to run some SQL statement just before a sample runs. This can be useful if your JDBC Sample requires some data to be in DataBase and you cannot compute this in a setup Thread group. For details, see [JDBC Request](/user-manual/component-reference/#JDBC_Request). See the following Test plan: In the linked test plan, "`Create Price Cut-Off`" JDBC PreProcessor calls a stored procedure to create a Price Cut-Off in Database, this one will be used by "`Calculate Price cut off`". ![Create Price Cut-Off Preprocessor](/images/screenshots/jdbc-pre-processor.png) _Create Price Cut-Off Preprocessor_ ## RegEx User Parameters ![RegEx User Parameters](/images/screenshots/regex_user_params.png) Allows to specify dynamic values for HTTP parameters extracted from another HTTP Request using regular expressions. RegEx User Parameters are specific to individual threads. This component allows you to specify reference name of a regular expression that extracts names and values of HTTP request parameters. Regular expression group numbers must be specified for parameter's name and also for parameter's value. Replacement will only occur for parameters in the Sampler that uses this RegEx User Parameters which name matches | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Regular Expression Reference Name | Yes | Name of a reference to a regular expression | | Parameter names regexp group number | Yes | Group number of regular expression used to extract parameter names | | Parameter values regex group number | Yes | Group number of regular expression used to extract parameter values | #### Regexp Example Suppose we have a request which returns a form with 3 input parameters and we want to extract the value of 2 of them to inject them in next request 1. Create Post Processor Regular Expression for first HTTP Request - `refName` - set name of a regular expression Expression (`listParams`) - `regular expression` - expression that will extract input names and input values attributes Ex: `input name="([^"]+?)" value="([^"]+?)"` - `template` - would be empty - `match nr` - `-1` (in order to iterate through all the possible matches) 2. Create Pre Processor RegEx User Parameters for second HTTP Request - `refName` - set the same reference name of a regular expression, would be `listParams` in our example - `parameter names group number` - group number of regular expression for parameter names, would be `1` in our example - `parameter values group number` - group number of regular expression for parameter values, would be `2` in our example See also the [Regular Expression Extractor](/user-manual/component-reference/#Regular_Expression_Extractor) element, which is used to extract parameters names and values ## Sample Timeout ![Sample Timeout](/images/screenshots/sample_timeout.png) This Pre-Processor schedules a timer task to interrupt a sample if it takes too long to complete. The timeout is ignored if it is zero or negative. For this to work, the sampler must implement Interruptible. The following samplers are known to do so: AJP, BeanShell, FTP, HTTP, Soap, AccessLog, MailReader, JMS Subscriber, TCPSampler, TestAction, JavaSampler The test element is intended for use where individual timeouts such as Connection Timeout or Response Timeout are insufficient, or where the Sampler does not support timeouts. The timeout should be set sufficiently long so that it is not triggered in normal tests, but short enough that it interrupts samples that are stuck. [By default, JMeter uses a Callable to interrupt the sampler. This executes in the same thread as the timer, so if the interrupt takes a long while, it may delay the processing of subsequent timeouts. This is not expected to be a problem, but if necessary the property `InterruptTimer.useRunnable` can be set to `true` to use a separate Runnable thread instead of the Callable.] | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this timer that is shown in the tree. | | Sample Timeout | Yes | If the sample takes longer to complete, it will be interrupted. | [^](#) ## 18.8 Post-Processors As the name suggests, Post-Processors are applied after samplers. Note that they are applied to **all** the samplers in the same scope, so to ensure that a post-processor is applied only to a particular sampler, add it as a child of the sampler. :::note Note: Unless documented otherwise, Post-Processors are not applied to sub-samples (child samples) - only to the parent sample. In the case of JSR223 and BeanShell post-processors, the script can retrieve sub-samples using the method `prev.getSubResults()` which returns an array of SampleResults. The array will be empty if there are none. ::: Post-Processors are run before Assertions, so they do not have access to any Assertion Results, nor will the sample status reflect the results of any Assertions. If you require access to Assertion Results, try using a Listener instead. Also note that the variable `JMeterThread.last_sample_ok` is set to "`true`" or "`false`" after all Assertions have been run. ## Regular Expression Extractor ![Regular Expression Extractor](/images/screenshots/regex_extractor.png) Allows the user to extract values from a server response using a Perl-type regular expression. As a post-processor, this element will execute after each Sample request in its scope, applying the regular expression, extracting the requested values, generate the template string, and store the result into the given variable name. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - extraction is to be applied to the contents of the named variable Matching is applied to all qualifying samples in turn. For example if there is a main sample and 3 sub-samples, each of which contains a single match for the regex, (i.e. 4 matches in total). For match number = `3`, Sub-samples only, the extractor will match the 3rd sub-sample. For match number = `3`, Main sample and sub-samples, the extractor will match the 2nd sub-sample (1st match is main sample). For match number = `0` or negative, all qualifying samples will be processed. For match number > `0`, matching will stop as soon as enough matches have been found. | | Field to check | Yes | The following fields can be checked: - `Body` - the body of the response, e.g. the content of a web-page (excluding headers) - `Body (unescaped)` - the body of the response, with all Html escape codes replaced. Note that Html escapes are processed without regard to context, so some incorrect substitutions may be made. :::note Note that this option highly impacts performances, so use it only when absolutely necessary and be aware of its impacts ::: - `Body as a Document` - the extract text from various type of documents via Apache Tika (see [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Document view section). :::note Note that the Body as a Document option can impact performances, so ensure it is OK for your test ::: - `Request Headers` - may not be present for non-HTTP samples - `Response Headers` - may not be present for non-HTTP samples - `URL` - `Response Code` - e.g. `200` - `Response Message` - e.g. `OK` Headers can be useful for HTTP samples; it may not be present for other sample types. | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. Also note that each group is stored as `[refname]_g#`, where `[refname]` is the string you entered as the reference name, and `#` is the group number, where group `0` is the entire match, group `1` is the match from the first set of parentheses, etc. | | Regular Expression | Yes | The regular expression used to parse the response data. This must contain at least one set of parentheses "`()`" to capture a portion of the string, unless using the group `$0$`. Do not enclose the expression in `/ /` - unless of course you want to match these characters as well. | | Template | Yes | The template used to create a string from the matches found. This is an arbitrary string with special elements to refer to groups within the regular expression. The syntax to refer to a group is: '`$1$`' to refer to group `1`, '`$2$`' to refer to group `2`, etc. `$0$` refers to whatever the entire expression matches. | | Match No. (0 for Random) | Yes | Indicates which match to use. The regular expression may match multiple times. - Use a value of zero to indicate JMeter should choose a match at random. - A positive number N means to select the nth match. - Negative numbers are used in conjunction with the [ForEach Controller](/user-manual/component-reference/#ForEach_Controller) - see below. | | Default Value | No, but recommended | If the regular expression does not match, then the reference variable will be set to the default value. This is particularly useful for debugging tests. If no default is provided, then it is difficult to tell whether the regular expression did not match, or the RE element was not processed or maybe the wrong variable is being used. However, if you have several test elements that set the same variable, you may wish to leave the variable unchanged if the expression does not match. In this case, remove the default value once debugging is complete. | | Use empty default value | No | If the checkbox is checked and `Default Value` is empty, then JMeter will set the variable to empty string instead of not setting it. Thus when you will for example use `\${var}` (if `Reference Name` is var) in your Test Plan, if the extracted value is not found then `\${var}` will be equal to empty string instead of containing `\${var}` which may be useful if extracted value is optional. | If the match number is set to a non-negative number, and a match occurs, the variables are set as follows: - `refName` - the value of the template - `refName_g_n_`, where `n`=`0`,`1`,`2` - the groups for the match - `refName_g` - the number of groups in the Regex (excluding `0`) If no match occurs, then the `refName` variable is set to the default (unless this is absent). Also, the following variables are removed: - `refName_g0` - `refName_g1` - `refName_g` If the match number is set to a negative number, then all the possible matches in the sampler data are processed. The variables are set as follows: - `refName_matchNr` - the number of matches found; could be `0` - `refName__n_`, where `n` = `1`, `2`, `3` etc. - the strings as generated by the template - `refName__n__g_m_`, where `m`=`0`, `1`, `2` - the groups for match `n` - `refName` - always set to the default value - `refName_g_n_` - not set Note that the `refName` variable is always set to the default value in this case, and the associated group variables are not set. See also [Response Assertion](/user-manual/component-reference/#Response_Assertion) for some examples of how to specify modifiers, and [for further information on JMeter regular expressions.](/user-manual/regular-expressions/) ## CSS Selector Extractor _(formerly CSS/JQuery Extractor)_ ![CSS Selector Extractor](/images/screenshots/css_extractor_attr.png) Allows the user to extract values from a server HTML response using a CSS Selector syntax. As a post-processor, this element will execute after each Sample request in its scope, applying the CSS/JQuery expression, extracting the requested nodes, extracting the node as text or attribute value and store the result into the given variable name. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - extraction is to be applied to the contents of the named variable Matching is applied to all qualifying samples in turn. For example if there is a main sample and 3 sub-samples, each of which contains a single match for the regex, (i.e. 4 matches in total). For match number = `3`, Sub-samples only, the extractor will match the 3rd sub-sample. For match number = `3`, Main sample and sub-samples, the extractor will match the 2nd sub-sample (1st match is main sample). For match number = `0` or negative, all qualifying samples will be processed. For match number > `0`, matching will stop as soon as enough matches have been found. | | CSS Selector Implementation | False | 2 Implementations for CSS/JQuery based syntax are supported: - [JSoup](http://jsoup.org/) - [Jodd-Lagarto (CSSelly)](http://jodd.org/doc/lagarto/index.html) If selector is set to empty, default implementation(JSoup) will be used. | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. | | CSS/JQuery expression | Yes | The CSS/JQuery selector used to select nodes from the response data. Selector, selectors combination and pseudo-selectors are supported, examples: - `E[foo]` - an `E` element with a "`foo`" attribute - `ancestor child` - child elements that descend from ancestor, e.g. `.body p` finds `p` elements anywhere under a block with class "`body`" - `:lt(n)` - find elements whose sibling index (i.e. its position in the DOM tree relative to its parent) is less than `n`; e.g. `td:lt(3)` - `:contains(text)` - find elements that contain the given `text`. The search is case-insensitive; e.g. `p:contains(jsoup)` - … For more details on syntax, see: - [JSoup](http://jsoup.org/cookbook/extracting-data/selector-syntax) - [Jodd-Lagarto (CSSelly)](http://jodd.org/doc/csselly/) | | Attribute | false | Name of attribute (as per HTML syntax) to extract from nodes that matched the selector. If empty, then the combined text of this element and all its children will be returned. This is the equivalent [Element#attr(name)](http://jsoup.org/apidocs/org/jsoup/nodes/Node.html#attr%28java.lang.String%29) function for JSoup if an attribute is set. ![CSS Extractor with attribute value set](/images/screenshots/css_extractor_attr.png) _CSS Extractor with attribute value set_ If empty this is the equivalent of [Element#text()](http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#text%28%29) function for JSoup if not value is set for attribute. ![CSS Extractor with no attribute set](/images/screenshots/css_extractor_noattr.png) _CSS Extractor with no attribute set_ | | Match No. (0 for Random) | Yes | Indicates which match to use. The CSS/JQuery selector may match multiple times. - Use a value of zero to indicate JMeter should choose a match at random. - A positive number `N` means to select the nth match. - Negative numbers are used in conjunction with the [ForEach Controller](/user-manual/component-reference/#ForEach_Controller) - see below. | | Default Value | No, but recommended | If the expression does not match, then the reference variable will be set to the default value. This is particularly useful for debugging tests. If no default is provided, then it is difficult to tell whether the expression did not match, or the CSS/JQuery element was not processed or maybe the wrong variable is being used. However, if you have several test elements that set the same variable, you may wish to leave the variable unchanged if the expression does not match. In this case, remove the default value once debugging is complete. | | Use empty default value | No | If the checkbox is checked and `Default Value` is empty, then JMeter will set the variable to empty string instead of not setting it. Thus when you will for example use `\${var}` (if `Reference Name` is var) in your Test Plan, if the extracted value is not found then `\${var}` will be equal to empty string instead of containing `\${var}` which may be useful if extracted value is optional. | If the match number is set to a non-negative number, and a match occurs, the variables are set as follows: - `refName` - the value of the template If no match occurs, then the `refName` variable is set to the default (unless this is absent). If the match number is set to a negative number, then all the possible matches in the sampler data are processed. The variables are set as follows: - `refName_matchNr` - the number of matches found; could be `0` - `refName_n`, where `n` = `1`, `2`, `3`, etc. - the strings as generated by the template - `refName` - always set to the default value Note that the `refName` variable is always set to the default value in this case. ## XPath2 Extractor ![XPath2 Extractor](/images/screenshots/xpath2_extractor.png) This test element allows the user to extract value(s) from structured response - XML or (X)HTML - using XPath2 query language. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - extraction is to be applied to the contents of the named variable XPath matching is applied to all qualifying samples in turn, and all the matching results will be returned. | | Return entire XPath fragment instead of text content | Yes | If selected, the fragment will be returned rather than the text content. For example `//title` would return "`<title>Apache JMeter</title>`" rather than "`Apache JMeter`". In this case, `//title/text()` would return "`Apache JMeter`". | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. | | XPath Query | Yes | Element query in XPath 2.0 language. Can return more than one match. | | Match No. (0 for Random) | No | If the XPath Path query leads to many results, you can choose which one(s) to extract as Variables: - `0`: means random (default value) - `-1` means extract all results, they will be named as `_<variable name>__N` (where `N` goes from 1 to Number of results) - `X`: means extract the Xth result. If this Xth is greater than number of matches, then nothing is returned. Default value will be used | | Default Value | yes | Default value returned when no match found. It is also returned if the node has no value and the fragment option is not selected. | | Namespaces aliases list | No | List of namespaces aliases you want to use to parse the document, one line per declaration. You must specify them as follow: `prefix=namespace`. This implementation makes it easier to use namespaces than with the old XPathExtractor version. | To allow for use in a [ForEach Controller](/user-manual/component-reference/#ForEach_Controller), it works exactly the same as the above XPath Extractor XPath2 Extractor provides some interestings tools such as an improved syntax and much more functions than in its first version. Here are some exemples: **`abs(/book/page[2])`** : extracts 2nd absolute value of the page from a book **`avg(/librarie/book/page)`** : extracts the average number of page from all the books in the libraries **`compare(/book[1]/page[2],/book[2]/page[2])`** : return Integer value equal 0 to if the 2nd page of the first book is equal to the 2nd page of the 2nd book, else return -1. To see more information about these functions, please check [xPath2 functions](http://saxon.sourceforge.net/saxon7.9.1/functions.html) ## XPath Extractor ![XPath Extractor](/images/screenshots/xpath_extractor.png) This test element allows the user to extract value(s) from structured response - XML or (X)HTML - using XPath query language. :::note Since JMeter 5.0, you should use [XPath2 Extractor](/user-manual/component-reference/#XPath2_Extractor) as it provides better and easier namespace management, better performances and support for XPath 2.0 ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - extraction is to be applied to the contents of the named variable XPath matching is applied to all qualifying samples in turn, and all the matching results will be returned. | | Use Tidy (tolerant parser) | Yes | If checked use Tidy to parse HTML response into XHTML. - "`Use Tidy`" should be checked on for HTML response. Such response is converted to valid XHTML (XML compatible HTML) using Tidy - "`Use Tidy`" should be unchecked for both XHTML or XML response (for example RSS) :::note For HTML, CSS Selector Extractor is the correct and performing solution. Don't use XPath for HTML extractions. ::: | | Quiet | If Tidy is selected | Sets the Tidy Quiet flag | | Report Errors | If Tidy is selected | If a Tidy error occurs, then set the Assertion accordingly | | Show warnings | If Tidy is selected | Sets the Tidy showWarnings option | | Use Namespaces | If Tidy is not selected | If checked, then the XML parser will use namespace resolution.(see note below on NAMESPACES) Note that currently only namespaces declared on the root element will be recognised. See below for user-definition of additional workspace names. | | Validate XML | If Tidy is not selected | Check the document against its schema. | | Ignore Whitespace | If Tidy is not selected | Ignore Element Whitespace. | | Fetch External DTDs | If Tidy is not selected | If selected, external DTDs are fetched. | | Return entire XPath fragment instead of text content | Yes | If selected, the fragment will be returned rather than the text content. For example `//title` would return "`<title>Apache JMeter</title>`" rather than "`Apache JMeter`". In this case, `//title/text()` would return "`Apache JMeter`". | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. | | XPath Query | Yes | Element query in XPath language. Can return more than one match. | | Match No. (0 for Random) | No | If the XPath Path query leads to many results, you can choose which one(s) to extract as Variables: - `0`: means random - `-1` means extract all results (default value), they will be named as `_<variable name>__N` (where `N` goes from 1 to Number of results) - `X`: means extract the Xth result. If this Xth is greater than number of matches, then nothing is returned. Default value will be used | | Default Value | No | Default value returned when no match found. It is also returned if the node has no value and the fragment option is not selected. | To allow for use in a [ForEach Controller](/user-manual/component-reference/#ForEach_Controller), the following variables are set on return: - `refName` - set to first (or only) match; if no match, then set to default - `refName_matchNr` - set to number of matches (may be `0`) - `refName_n` - `n`=`1`, `2`, `3`, etc. Set to the 1st, 2nd 3rd match etc. :::note Note: The next `refName_n` variable is set to `null` - e.g. if there are 2 matches, then `refName_3` is set to `null`, and if there are no matches, then `refName_1` is set to `null`. ::: XPath is query language targeted primarily for XSLT transformations. However it is useful as generic query language for structured data too. See [XPath Reference](http://www.topxml.com/xsl/xpathref.asp) or [XPath specification](http://www.w3.org/TR/xpath) for more information. Here are few examples: **`/html/head/title`** : extracts title element from HTML response **`/book/page[2]`** : extracts 2nd page from a book **`/book/page`** : extracts all pages from a book **`//form[@name='countryForm']//select[@name='country']/option[text()='Czech Republic'])/@value`** : extracts value attribute of option element that match text '`Czech Republic`' inside of select element with name attribute '`country`' inside of form with name attribute '`countryForm`' :::note When "`Use Tidy`" is checked on - resulting XML document may slightly differ from original HTML response: - All elements and attribute names are converted to lowercase - Tidy attempts to correct improperly nested elements. For example - original (incorrect) `ul/font/li` becomes correct `ul/li/font` See [Tidy homepage](http://jtidy.sf.net) for more information. ::: :::note **NAMESPACES** As a work-round for namespace limitations of the Xalan XPath parser (implementation on which JMeter is based) you need to: - provide a Properties file (if for example your file is named `namespaces.properties`) which contains mappings for the namespace prefixes: ``` prefix1=http\://foo.apache.org prefix2=http\://toto.apache.org … ``` - reference this file in `user.properties` file using the property: ``` xpath.namespace.config=namespaces.properties ``` ::: Another option is to use the following code: ``` //mynamespace:tagname ``` by: ``` //*[local-name()='tagname' and namespace-uri()='uri-for-namespace'] ``` where "`uri-for-namespace`" is the uri for the "`mynamespace`" namespace.(not applicable if Tidy is selected) ## JSON JMESPath Extractor ![JSON JMESPath Extractor](/images/screenshots/extractor/jmespath_extractor.png) This test element allows the user to extract value(s) from JSON response using JMESPath query language. :::note In the XPATH Extractor we support to extract multiple xpaths at the same time, but in JMES Extractor only one JMES Expression can be entered at a time. ::: | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - extraction is to be applied to the contents of the named variable | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. | | JMESPath expressions | Yes | Element query in JMESPath query language. Can return the matched result. | | Match No. (0 for Random) | No | If the JMESPath query leads to many results, you can choose which one(s) to extract as Variables: - `0`: means random - `-1` means extract all results (default value), they will be named as `_<variable name>__N` (where `N` goes from 1 to Number of results) - `X`: means extract the Xth result. If this Xth is greater than number of matches, then nothing is returned. Default value will be used | | Default Value | No | Default value returned when no match found. It is also returned if the node has no value and the fragment option is not selected. | JMESPath is a query language for JSON. It is described in an ABNF grammar with a complete specification. This ensures that the language syntax is precisely defined. See [JMESPath Reference](http://jmespath.org/) for more information. Here are also some examples [JMESPath Example](http://jmespath.org/tutorial.html). ## Result Status Action Handler ![Result Status Action Handler](/images/screenshots/resultstatusactionhandler.png) This test element allows the user to stop the thread or the whole test if the relevant sampler failed. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Action to be taken after a Sampler error | No | Determines what happens if a sampler error occurs, either because the sample itself failed or an assertion failed. The possible choices are: - `Continue` - ignore the error and continue with the test - `Start next thread loop` - does not execute samplers following the sampler in error for the current iteration and restarts the loop on next iteration - `Stop Thread` - current thread exits - `Stop Test` - the entire test is stopped at the end of any current samples. - `Stop Test Now` - the entire test is stopped abruptly. Any current samplers are interrupted if possible. | ## BeanShell PostProcessor ![BeanShell PostProcessor](/images/screenshots/beanshell_postprocessor.png) The BeanShell PreProcessor allows arbitrary code to be applied after taking a sample. BeanShell Post-Processor no longer ignores samples with zero-length result data **For full details on using BeanShell, please see the [BeanShell website.](http://www.beanshell.org/)** :::note Migration to [JSR223 PostProcessor](/user-manual/component-reference/#JSR223_PostProcessor)+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library. ::: The test element supports the `ThreadListener` and `TestListener` methods. These should be defined in the initialisation file. See the file `BeanShellListeners.bshrc` for example definitions. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. The name is stored in the script variable `Label` | | Reset bsh.Interpreter before each call | Yes | If this option is selected, then the interpreter will be recreated for each sample. This may be necessary for some long running scripts. For further information, see [Best Practices - BeanShell scripting](/user-manual/best-practices/#bsh_scripting). | | Parameters | No | Parameters to pass to the BeanShell script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `bsh.args` - String array containing parameters, split on white-space | | Script file | No | A file containing the BeanShell script to run. The file name is stored in the script variable `FileName` | | Script | Yes (unless script file is provided) | The BeanShell script. The return value is ignored. | The following BeanShell variables are set up for use by the script: - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous SampleResult - `data` - (byte [])- gives access to the current sample data For details of all the methods available on each of the above variables, please check the Javadoc If the property `beanshell.postprocessor.init` is defined, this is used to load an initialisation file, which can be used to define methods etc. for use in the BeanShell script. ## JSR223 PostProcessor The JSR223 PostProcessor allows JSR223 script code to be applied after taking a sample. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Language | Yes | The JSR223 language to be used | | Parameters | No | Parameters to pass to the script. The parameters are stored in the following variables: - `Parameters` - string containing the parameters as a single variable - `args` - String array containing parameters, split on white-space | | Script file | No | A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "`user.dir`" System property | | Script compilation caching | No | Unique String across Test Plan that JMeter will use to cache result of Script compilation if language used supports `[Compilable](https://docs.oracle.com/javase/8/docs/api/javax/script/Compilable.html)` interface (Groovy is one of these, java, beanshell and javascript are not) :::note See note in JSR223 Sampler Java System property if you're using Groovy without checking this option ::: | | Script | Yes (unless script file is provided) | The script to run. | Before invoking the script, some variables are set up. Note that these are JSR223 variables - i.e. they can be used directly in the script. - `log` - ([Logger](https://www.slf4j.org/api/org/slf4j/Logger.html)) - can be used to write to the log file - `Label` - the String Label - `FileName` - the script file name (if any) - `Parameters` - the parameters (as a String) - `args` - the parameters as a String array (split on whitespace) - `ctx` - ([JMeterContext](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html)) - gives access to the context - `vars` - ([JMeterVariables](https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html)) - gives read/write access to variables: ``` vars.get(key); vars.put(key,val); vars.putObject("OBJ1",new Object()); vars.getObject("OBJ2"); ``` - `props` - (JMeterProperties - class java.util.Properties) - e.g. `props.get("START.HMS");` `props.put("PROP1","1234");` - `prev` - ([SampleResult](https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html)) - gives access to the previous SampleResult (if any) - `sampler` - ([Sampler](https://jmeter.apache.org/api/org/apache/jmeter/samplers/Sampler.html))- gives access to the current sampler - `OUT` - System.out - e.g. `OUT.println("message")` For details of all the methods available on each of the above variables, please check the Javadoc ## JDBC PostProcessor The JDBC PostProcessor enables you to run some SQL statement just after a sample has run. This can be useful if your JDBC Sample changes some data and you want to reset state to what it was before the JDBC sample run. In the linked test plan, "`JDBC PostProcessor`" JDBC PostProcessor calls a stored procedure to delete from Database the Price Cut-Off that was created by PreProcessor. ![JDBC PostProcessor](/images/screenshots/jdbc-post-processor.png) _JDBC PostProcessor_ ## JSON Extractor The JSON PostProcessor enables you extract data from JSON responses using JSON-PATH syntax. This post processor is very similar to Regular expression extractor. It must be placed as a child of HTTP Sampler or any other sampler that has responses. It will allow you to extract in a very easy way text content, see [JSON Path syntax](https://github.com/json-path/JsonPath). | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. **`Main sample only`** : only applies to the main sample **`Sub-samples only`** : only applies to the sub-samples **`Main sample and sub-samples`** : applies to both. **`JMeter Variable Name to use`** : extraction is to be applied to the contents of the named variable | | Names of created variables | Yes | Semicolon separated names of variables that will contain the results of JSON-PATH expressions (must match number of JSON-PATH expressions) | | JSON Path Expressions | Yes | Semicolon separated JSON-PATH expressions (must match number of variables) | | Default Values | No | Semicolon separated default values if JSON-PATH expressions do not return any result(must match number of variables) | | Match Numbers | No | For each JSON Path Expression, if the JSON Path query leads to many results, you can choose which one(s) to extract as Variables: - `0`: means random (Default Value) - `-1` means extract all results, they will be named as `_<variable name>__N` (where `N` goes from 1 to Number of results) - `X`: means extract the _X_th result. If this _X_th is greater than number of matches, then nothing is returned. Default value will be used The numbers have to be given as a Semicolon separated list. The number of elements in that list have to match the number of given JSON Path Expressions. If left empty, the value `0` will be used as default for every expression. | | Compute concatenation var | No | If many results are found, plugin will concatenate them using ‘`,`’ separator and store it in a var named `_<variable name>__ALL` | ![JSON PostProcessor](/images/screenshots/json-post-processor.png) _JSON PostProcessor_ ## Boundary Extractor ![Boundary Extractor](/images/screenshots/extractor/boundary_extractor.png) Allows the user to extract values from a server response using left and right boundaries. As a post-processor, this element will execute after each Sample request in its scope, testing the boundaries, extracting the requested values, generate the template string, and store the result into the given variable name. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Apply to: | Yes | This is for use with samplers that can generate sub-samples, e.g. HTTP Sampler with embedded resources, Mail Reader or samples generated by the Transaction Controller. - `Main sample only` - only applies to the main sample - `Sub-samples only` - only applies to the sub-samples - `Main sample and sub-samples` - applies to both. - `JMeter Variable Name to use` - assertion is to be applied to the contents of the named variable Matching is applied to all qualifying samples in turn. For example if there is a main sample and 3 sub-samples, each of which contains a single match test, (i.e. 4 matches in total). For match number = `3`, Sub-samples only, the extractor will match the 3rd sub-sample. For match number = `3`, Main sample and sub-samples, the extractor will match the 2nd sub-sample (1st match is main sample). For match number = `0` or negative, all qualifying samples will be processed. For match number > `0`, matching will stop as soon as enough matches have been found. | | Field to check | Yes | The following fields can be checked: - `Body` - the body of the response, e.g. the content of a web-page (excluding headers) - `Body (unescaped)` - the body of the response, with all Html escape codes replaced. Note that Html escapes are processed without regard to context, so some incorrect substitutions may be made. :::note Note that this option highly impacts performances, so use it only when absolutely necessary and be aware of its impacts ::: - `Body as a Document` - the extract text from various type of documents via Apache Tika (see [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Document view section). :::note Note that the Body as a Document option can impact performances, so ensure it is OK for your test ::: - `Request Headers` - may not be present for non-HTTP samples - `Response Headers` - may not be present for non-HTTP samples - `URL` - `Response Code` - e.g. `200` - `Response Message` - e.g. `OK` Headers can be useful for HTTP samples; it may not be present for other sample types. | | Name of created variable | Yes | The name of the JMeter variable in which to store the result. Also note that each group is stored as `[refname]_g#`, where `[refname]` is the string you entered as the reference name, and `#` is the group number, where group `0` is the entire match, group `1` is the match from the first set of parentheses, etc. | | Left Boundary | No | Left boundary of value to find | | Right Boundary | No | Right boundary of value to find | | Match No. (0 for Random) | Yes | Indicates which match to use. The boundaries may match multiple times. - Use a value of zero to indicate JMeter should choose a match at random. - A positive number N means to select the nth match. - Negative numbers are used in conjunction with the [ForEach Controller](/user-manual/component-reference/#ForEach_Controller) - see below. | | Default Value | No, but recommended | If the boundaries do not match, then the reference variable will be set to the default value. This is particularly useful for debugging tests. If no default is provided, then it is difficult to tell whether the boundaries did not match, or maybe the wrong variable is being used. However, if you have several test elements that set the same variable, you may wish to leave the variable unchanged if the expression does not match. In this case, remove the default value once debugging is complete. | If the match number is set to a non-negative number, and a match occurs, the variables are set as follows: - `refName` - the value of the extraction If no match occurs, then the `refName` variable is set to the default (unless this is absent). If the match number is set to a negative number, then all the possible matches in the sampler data are processed. The variables are set as follows: - `refName_matchNr` - the number of matches found; could be `0` - `refName__n_`, where `n` = `1`, `2`, `3` etc. - the strings as generated by the template - `refName__n__g_m_`, where `m`=`0`, `1`, `2` - the groups for match `n` - `refName` - always set to the default value Note that the `refName` variable is always set to the default value in this case, and the associated group variables are not set. :::note If both left and right boundary are null, the whole data selected in scope is returned ::: ## 18.9 Miscellaneous Features ## Test Plan ![Test Plan](/images/screenshots/testplan.png) The Test Plan is where the overall settings for a test are specified. Static variables can be defined for values that are repeated throughout a test, such as server names. For example the variable `SERVER` could be defined as `www.example.com`, and the rest of the test plan could refer to it as `\${SERVER}`. This simplifies changing the name later. If the same variable name is reused on one of more [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) Configuration elements, the value is set to the last definition in the test plan (reading from top to bottom). Such variables should be used for items that may change between test runs, but which remain the same during a test run. :::note Note that the Test Plan cannot refer to variables it defines. ::: If you need to construct other variables from the Test Plan variables, use a [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) test element. Selecting Functional Testing instructs JMeter to save the additional sample information - Response Data and Sampler Data - to all result files. This increases the resources needed to run a test, and may adversely impact JMeter performance. If more data is required for a particular sampler only, then add a Listener to it, and configure the fields as required. :::note The option does not affect CSV result files, which cannot currently store such information. ::: Also, an option exists here to instruct JMeter to run the [Thread Group](/user-manual/component-reference/#Thread_Group) serially rather than in parallel. Run tearDown Thread Groups after shutdown of main threads: if selected, the tearDown groups (if any) will be run after graceful shutdown of the main threads. The tearDown threads won't be run if the test is forcibly stopped. Test plan now provides an easy way to add classpath setting to a specific test plan. The feature is additive, meaning that you can add jar files or directories, but removing an entry requires restarting JMeter. :::note Note that this cannot be used to add JMeter GUI plugins, because they are processed earlier. ::: However it can be useful for utility jars such as JDBC drivers. The jars are only added to the search path for the JMeter loader, not for the system class loader. JMeter properties also provides an entry for loading additional classpaths. In `jmeter.properties`, edit "`user.classpath`" or "`plugin_dependency_paths`" to include additional libraries. See [JMeter's Classpath](/getting-started/get-started/#classpath) and [Configuring JMeter](/getting-started/get-started/#configuring_jmeter) for details. ## Open Model Thread Group ![Open Model Thread Group](/images/screenshots/open_model_thread_group.png) :::note This thread group is experimental, and it might change in the future releases. Please provide your feedback on what works and what could be improved. ::: Open Model Thread Group defines a pool of users that will execute a particular test case against the server. The users are generated according to the schedule. The load profile consists of a sequence of constant, increasing or decreasing load. The basic configuration is `rate(1/sec) random_arrivals(2 min) rate(3/sec)` which means the load will increase linearly from one request per second to three requests per second during a period of two-minutes. If you omit rate at the end, then it will be set to the same value as that from the start. For example, `rate(1/sec) random_arrivals(2 min)` is exactly the same as `rate(1/sec) random_arrivals(2 min) rate(1/sec)`. That is why `rate(1/sec) random_arrivals(2 min) random_arrivals(3 min) rate(4/sec)` is exactly the same as `rate(1/sec) random_arrivals(2 min) rate(1/sec) random_arrivals(3 min) rate(4/sec)`, so the load is one request per second during the first two minutes, after which it increases linearly from one request per second to four requests per second during three minutes. Here are examples for using the schedule: **`rate(10/sec) random_arrivals(1 min) rate(10/sec)`** : constant load rate of ten requests per second during one minute **`rate(0) random_arrivals(1 min) rate(10/sec)`** : linearly increase the load from zero requests per second to ten requests per second during one minute **`rate(0) random_arrivals(1 min) rate(10/sec) random_arrivals(1 min) rate(10/sec) random_arrivals(1 min) rate(0)`** : linearly increase the load from zero requests per second to ten requests per second during one minute, then hold the load during one minute, then linearly decrease the load from ten requests per second to zero during one minute **`rate(10) random_arrivals(1 min) rate(10/sec) random_arrivals(1 min) rate(10/sec) random_arrivals(1 min) rate(0)`** : linearly increase the load from zero requests per second to ten requests per second during one minute, then hold the load during one minute, then linearly decrease the load from ten requests per second to zero requests per second during one minute **`rate(10) random_arrivals(1 min) pause(2 sec) random_arrivals(1 min)`** : run with constant load of ten requests per second during one minute, then make two second pause, then resume the load of ten requests per second for one minute The following commands are available: **`rate(<number>/sec)`** : configures target load rate. The following time units are supported: `ms`, `sec`, `min`, `hour`, `day`. You can omit time unit in case the rate is 0: `rate(0)` **`random_arrivals(<number> sec)`** : configures random arrivals schedule with the given duration. The starting load rate is configured before `random_arrivals`, and the finish load rate is configured after `random_arrivals`. For example, 10 minute test from five requests per second at the beginning to fifteen request per second at the end could be configured as `rate(5/sec) random_arrivals(10 min) rate(15/sec)`. The implicit rate at the beginning of the test is `0`. If the finish rate is not provided (or if several `random_arrivals` steps go one after another), then the load is constant. For instance, `rate(3/sec) random_arrivals(1 min) random_arrivals(2 min) rate(6/sec)` configures constant rate of three requests per second for the first minute, and then the load increases from three requests per second to six requests per second during the next two minutes. The time units are the same as in `rate`. **`even_arrivals(<number> sec)`** : configures even arrivals (TODO: not implemented yet). For instance, if the desired load is one request per second, then `random_arrivals` would lauch samples with exactly one second intervals. **`pause(<number> sec)`** : configures a pause for the given duration. The rate is restored after the pause, so `rate(2/sec) random_arrivals(5 sec) pause(5 sec) random_arrivals(5 sec)` generates random arrivals with two requests per second rate, then a pause for five seconds (no new arrivals), then five more seconds with two requests per second rate. Note: `pause` duration is always honoured, even if all the scenarios are complete, and no new ones will be scheduled. For instance, if you use `rate(1/sec) random_arrivals(1 min) pause(1 hour)`, the thread group would always last for sixty-one minutes no matter how much time do individual scenarios take. **`/* Comments */`** : can be used to clarify the schedule or temporary disable some steps. Comments cannot be nested. **`// line comments`** : can be used to clarify the schedule or temporary disable some steps. Line comment lasts till the end of the line. The thread groups terminates threads as soon as the schedule ends. In other words, the threads are interrupted after all `arrivals` and `pause` intervals. If you want to let the threads complete safely, consider adding `pause(5 min)` at the end of the schedule. That will add five minutes for the threads to continue. There are no special functions for generating the load profile in a loop, however, the default JMeter templating functions can be helpful for generating the schedule. For example, the following pattern would generate a sequence of 10 steps where each step lasts 10 seconds: 10/sec, 20/sec, 30/sec, ... `\${__groovy((1..10).collect { "rate(" + it*10 + "/sec) random_arrivals(10 sec) pause(1 sec)" }.join(" "))}` You can get variables from properties as follows: `rate(\${__P(beginRate,40)}) random_arrivals(\${__P(testDuration, 10)} sec) rate(\${__P(endRate,40)})` Currently, the load profile is evaluated at the beginning of the test only, so if you use dynamic functions, then only the first result will be used. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this thread group that is shown in the tree | | Schedule | Yes | The expression that configures schedule. For example: `rate(5/sec) random_arrivals(1 min) pause(5 sec)` | | Random Seed (change from 0 to random) | No | Note: different thread groups should better have different seed values. Constant seed ensures thread group generates the same delays each test start. The value of "0" means the schedule is truly random (non-repeatable from one execution to another).. | ## Thread Group ![Thread Group](/images/screenshots/threadgroup.png) A Thread Group defines a pool of users that will execute a particular test case against your server. In the Thread Group GUI, you can control the number of users simulated (number of threads), the ramp up time (how long it takes to start all the threads), the number of times to perform the test, and optionally, a start and stop time for the test. See also [tearDown Thread Group](/user-manual/component-reference/#tearDown_Thread_Group) and [setUp Thread Group](/user-manual/component-reference/#setUp_Thread_Group). When using the scheduler, JMeter runs the thread group until either the number of loops is reached or the duration/end-time is reached - whichever occurs first. Note that the condition is only checked between samples; when the end condition is reached, that thread will stop. JMeter does not interrupt samplers which are waiting for a response, so the end time may be delayed arbitrarily. Since JMeter 3.0, you can run a selection of Thread Group by selecting them and right clicking. A popup menu will appear: ![Popup menu to start a selection of Thread Groups](/images/screenshots/threadgroup-popup-menu.png) _Popup menu to start a selection of Thread Groups_ Notice you have three options to run the selection of Thread Groups: **`Start`** : Start the selected thread groups only **`Start no pauses`** : Start the selected thread groups only but without running the timers **`Validate`** : Start the selected thread groups only using validation mode. Per default this runs the Thread Group in validation mode (see below) **Validation Mode:** This mode enables rapid validation of a Thread Group by running it with one thread, one iteration, no timers and no `Startup delay` set to `0`. Behaviour can be modified with some properties by setting in `user.properties`: **`testplan_validation.nb_threads_per_thread_group`** : Number of threads to use to validate a Thread Group, by default `1` **`testplan_validation.ignore_timers`** : Ignore timers when validating the thread group of plan, by default `1` **`testplan_validation.number_iterations`** : Number of iterations to use to validate a Thread Group **`testplan_validation.tpc_force_100_pct`** : Whether to force Throughput Controller in percentage mode to run as if percentage was 100 %. Defaults to `false` | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Action to be taken after a Sampler error | No | Determines what happens if a sampler error occurs, either because the sample itself failed or an assertion failed. The possible choices are: - `Continue` - ignore the error and continue with the test - `Start Next Thread Loop` - ignore the error, start next loop and continue with the test - `Stop Thread` - current thread exits - `Stop Test` - the entire test is stopped at the end of any current samples. - `Stop Test Now` - the entire test is stopped abruptly. Any current samplers are interrupted if possible. | | Number of Threads | Yes | Number of users to simulate. | | Ramp-up Period | Yes | How long JMeter should take to get all the threads started. If there are 10 threads and a ramp-up time of 100 seconds, then each thread will begin 10 seconds after the previous thread started, for a total time of 100 seconds to get the test fully up to speed. :::note The first thread will always start directly, so if you configured **one** thread, the ramp-up time is effectively **zero**. For the same reason, the tenth thread in the above example will actually be started after 90 seconds and not 100 seconds. ::: | | Same user on each iteration | Yes | If selected, cookie and cache data from the first sampler response are used in subsequent requests (requires a global Cookie and Cache Manager respectively). If not selected, cookie and cache data from the first sampler response are not used in subsequent requests. :::note If not selected, a new connection will be opened between iterations which will result in increased response times and consume more resources (memory and cpu). ::: | | Loop Count | Yes, unless Infinite is selected | Number of times to perform the test case. Alternatively, "`infinite`" can be selected causing the test to run until manually stopped or end of the thread lifetime is reached. | | Same user on each iteration | Yes | If selected, cookie and cache data from the first sampler response are used in subsequent requests (requires a global Cookie and Cache Manager respectively). If not selected, cookie and cache data from the first sampler response are not used in subsequent requests. :::note If not selected, a new connection will be opened between iterations which will result in increased response times and consume more resources (memory and cpu). ::: | | Delay Thread creation until needed | Yes | If selected, threads are created only when the appropriate proportion of the ramp-up time has elapsed. This is most appropriate for tests with a ramp-up time that is significantly longer than the time to execute a single thread. I.e. where earlier threads finish before later ones start. If not selected, all threads are created when the test starts (they then pause for the appropriate proportion of the ramp-up time). This is the original default, and is appropriate for tests where threads are active throughout most of the test. | | Specify Thread lifetime | Yes | If selected, confines Thread operation time to the given bounds | | Duration (seconds) | No | If the scheduler checkbox is selected, one can choose a relative end time. JMeter will use this to calculate the End Time. | | Startup delay (seconds) | No | If the scheduler checkbox is selected, one can choose a relative startup delay. JMeter will use this to calculate the Start Time. | ## WorkBench ## SSL Manager The SSL Manager is a way to select a client certificate so that you can test applications that use Public Key Infrastructure (PKI). It is only needed if you have not set up the appropriate System properties. :::note If you want to test client certificate authentication, see [Keystore Configuration](/user-manual/component-reference/#Keystore_Configuration) ::: **Choosing a Client Certificate** You may either use a Java Key Store (JKS) format key store, or a Public Key Certificate Standard #12 (PKCS12) file for your client certificates. There is a feature of the JSSE libraries that require you to have at least a six character password on your key (at least for the keytool utility that comes with your JDK). To select the client certificate, choose **Options → SSL Manager** from the menu bar. You will be presented with a file finder that looks for PKCS12 files by default. Your PKCS12 file must have the extension '`.p12`' for SSL Manager to recognize it as a PKCS12 file. Any other file will be treated like an average JKS key store. If JSSE is correctly installed, you will be prompted for the password. The text box does not hide the characters you type at this point -- so make sure no one is looking over your shoulder. The current implementation assumes that the password for the keystore is also the password for the private key of the client you want to authenticate as. Or you can set the appropriate System properties - see the `system.properties` file. The next time you run your test, the SSL Manager will examine your key store to see if it has at least one key available to it. If there is only one key, SSL Manager will select it for you. If there is more than one key, it currently selects the first key. There is currently no way to select other entries in the keystore, so the desired key must be the first. **Things to Look Out For** You must have your Certificate Authority (CA) certificate installed properly if it is not signed by one of the five CA certificates that ships with your JDK. One method to install it is to import your CA certificate into a JKS file, and name the JKS file "`jssecacerts`". Place the file in your JRE's `lib/security` folder. This file will be read before the "`cacerts`" file in the same directory. Keep in mind that as long as the "`jssecacerts`" file exists, the certificates installed in "`cacerts`" will not be used. This may cause problems for you. If you don't mind importing your CA certificate into the "`cacerts`" file, then you can authenticate against all of the CA certificates installed. ## HTTP(S) Test Script Recorder _(formerly HTTP Proxy Server)_ ![HTTP(S) Test Script Recorder](/images/screenshots/proxy_control.png) The HTTP(S) Test Script Recorder allows JMeter to intercept and record your actions while you browse your web application with your normal browser. JMeter will create test sample objects and store them directly into your test plan as you go (so you can view samples interactively while you make them). Ensure you read this [wiki page](https://cwiki.apache.org/confluence/display/JMETER/TestRecording210) to setup correctly JMeter. To use the recorder, _add_ the HTTP(S) Test Script Recorder element. Right-click on the Test Plan element to get the Add menu: (**Add → Non-Test Elements → HTTP(S) Test Script Recorder** ). The recorder is implemented as an HTTP(S) proxy server. You need to set up your browser use the proxy for all HTTP and HTTPS requests. :::note Do not use JMeter as the proxy for any other request types - FTP, etc. - as JMeter cannot handle them. ::: Ideally use private browsing mode when recording the session. This should ensure that the browser starts with no stored cookies, and prevents certain changes from being saved. For example, Firefox does not allow certificate overrides to be saved permanently. ##### HTTPS recording and certificates HTTPS connections use certificates to authenticate the connection between the browser and the web server. When connecting via HTTPS, the server presents the certificate to the browser. To authenticate the certificate, the browser checks that the server certificate is signed by a Certificate Authority (CA) that is linked to one of its in-built root CAs. :::note Browsers also check that the certificate is for the correct host or domain, and that it is valid and not expired. ::: If any of the browser checks fail, it will prompt the user who can then decide whether to allow the connection to proceed. JMeter needs to use its own certificate to enable it to intercept the HTTPS connection from the browser. Effectively JMeter has to pretend to be the target server. JMeter will generate its own certificate(s). These are generated with a validity period defined by the property `proxy.cert.validity`, default 7 days, and random passwords. If JMeter detects that it is running under Java 8 or later, it will generate certificates for each target server as necessary (dynamic mode) unless the following property is defined: `proxy.cert.dynamic_keys=false`. When using dynamic mode, the certificate will be for the correct host name, and will be signed by a JMeter-generated CA certificate. By default, this CA certificate won't be trusted by the browser, however it can be installed as a trusted certificate. Once this is done, the generated server certificates will be accepted by the browser. This has the advantage that even embedded HTTPS resources can be intercepted, and there is no need to override the browser checks for each new server. :::note Browsers don't prompt for embedded resources. So with earlier versions, embedded resources would only be downloaded for servers that were already 'known' to the browser ::: Unless a keystore is provided (and you define the property `proxy.cert.alias`), JMeter needs to use the keytool application to create the keystore entries. JMeter includes code to check that keytool is available by looking in various standard places. If JMeter is unable to find the keytool application, it will report an error. If necessary, the system property `keytool.directory` can be used to tell JMeter where to find keytool. This should be defined in the file `system.properties`. The JMeter certificates are generated (if necessary) when the `Start` button is pressed. :::note Certificate generation can take some while, during which time the GUI will be unresponsive. ::: The cursor is changed to an hour-glass whilst this is happening. When certificate generation is complete, the GUI will display a pop-up dialogue containing the details of the certificate for the root CA. This certificate needs to be installed by the browser in order for it to accept the host certificates generated by JMeter; see [below](#install_cert) for details. If necessary, you can force JMeter to regenerate the keystore (and the exported certificates - `ApacheJMeterTemporaryRootCA[.usr|.crt]`) by deleting the keystore file `proxyserver.jks` from the JMeter directory. This certificate is not one of the certificates that browsers normally trust, and will not be for the correct host. As a consequence: - The browser should display a dialogue asking if you want to accept the certificate or not. For example: ``` 1) The server's name "`www.example.com`" does not match the certificate's name "`_ JMeter Root CA for recording (INSTALL ONLY IF IT IS YOURS)`". Somebody may be trying to eavesdrop on you. 2) The certificate for "`_ JMeter Root CA for recording (INSTALL ONLY IF IT IS YOURS)`" is signed by the unknown Certificate Authority "`_ JMeter Root CA for recording (INSTALL ONLY IF IT IS YOURS)`". It is not possible to verify that this is a valid certificate. ``` You will need to accept the certificate in order to allow the JMeter Proxy to intercept the SSL traffic in order to record it. However, do not accept this certificate permanently; it should only be accepted temporarily. Browsers only prompt this dialogue for the certificate of the main URL, not for the resources loaded in the page, such as images, CSS or JavaScript files hosted on a secured external CDN. If you have such resources (gmail has for example), you'll have to first browse manually to these other domains in order to accept JMeter's certificate for them. Check in `jmeter.log` for secure domains that you need to register certificate for. - If the browser has already registered a validated certificate for this domain, the browser will detect JMeter as a security breach and will refuse to load the page. If so, you have to remove the trusted certificate from your browser's keystore. Versions of JMeter from 2.10 onwards still support this method, and will continue to do so if you define the following property: `proxy.cert.alias` The following properties can be used to change the certificate that is used: - `proxy.cert.directory` - the directory in which to find the certificate (default = JMeter `bin/`) - `proxy.cert.file` - name of the keystore file (default "`proxyserver.jks`") - `proxy.cert.keystorepass` - keystore password (default "`password`") [Ignored if using JMeter certificate] - `proxy.cert.keypassword` - certificate key password (default "`password`") [Ignored if using JMeter certificate] - `proxy.cert.type` - the certificate type (default "`JKS`") [Ignored if using JMeter certificate] - `proxy.cert.factory` - the factory (default "`SunX509`") [Ignored if using JMeter certificate] - `proxy.cert.alias` - the alias for the key to be used. If this is defined, JMeter does not attempt to generate its own certificate(s). - `proxy.ssl.protocol` - the protocol to be used (default "`SSLv3`") :::note If your browser currently uses a proxy (e.g. a company intranet may route all external requests via a proxy), then you need to [tell JMeter to use that proxy](/getting-started/get-started/#proxy_server) before starting JMeter, using the [command-line options](/getting-started/get-started/#options) `-H` and `-P`. This setting will also be needed when running the generated test plan. ::: ##### Installing the JMeter CA certificate for HTTPS recording As mentioned above, when run under Java 8, JMeter can generate certificates for each server. For this to work smoothly, the root CA signing certificate used by JMeter needs to be trusted by the browser. The first time that the recorder is started, it will generate the certificates if necessary. The root CA certificate is exported into a file with the name `ApacheJMeterTemporaryRootCA` in the current launch directory. When the certificates have been set up, JMeter will show a dialog with the current certificate details. At this point, the certificate can be imported into the browser, as per the instructions below. Note that once the root CA certificate has been installed as a trusted CA, the browser will trust any certificates signed by it. Until such time as the certificate expires or the certificate is removed from the browser, it will not warn the user that the certificate is being relied upon. So anyone that can get hold of the keystore and password can use the certificate to generate certificates which will be accepted by any browsers that trust the JMeter root CA certificate. For this reason, the password for the keystore and private keys are randomly generated and a short validity period used. The passwords are stored in the local preferences area. Please ensure that only trusted users have access to the host with the keystore. :::note The popup that displays once you start the Recorder is an informational popup: ![Recorder Install Certificate Popup](/images/screenshots/recorder_popup_info.png) _Recorder Install Certificate Popup_ Just click ok and proceed further. ::: ###### Installing the certificate in Firefox Choose the following options: - `Tools / Options` - `Advanced / Certificates` - `View Certificates` - `Authorities` - `Import …` - Browse to the JMeter launch directory, and click on the file `ApacheJMeterTemporaryRootCA.crt`, press `Open` - Click `View` and check that the certificate details agree with the ones displayed by the JMeter Test Script Recorder - If OK, select "`Trust this CA to identify web sites`", and press `OK` - Close dialogs by pressing `OK` as necessary ###### Installing the certificate in Chrome or Internet Explorer Both Chrome and Internet Explorer use the same trust store for certificates. - Browse to the JMeter launch directory, and click on the file `ApacheJMeterTemporaryRootCA.crt`, and open it - Click on the "`Details`" tab and check that the certificate details agree with the ones displayed by the JMeter Test Script Recorder - If OK, go back to the "`General`" tab, and click on "`Install Certificate …`" and follow the Wizard prompts ###### Installing the certificate in Opera - `Tools / Preferences / Advanced / Security` - `Manage Certificates …` - Select "`Intermediate`" tab, click "`Import …`" - Browse to the JMeter launch directory, and click on the file `ApacheJMeterTemporaryRootCA.usr`, and open it - | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | Port | Yes | The port that the HTTP(S) Test Script Recorder listens to. `8888` is the default, but you can change it. | | HTTPS Domains | No | List of domain (or host) names for HTTPS. Use this to pre-generate certificates for all servers you wish to record. For example, `*.example.com,*.subdomain.example.com` Note that wildcard domains only apply to one level, i.e. `abc.subdomain.example.com` matches `*.subdomain.example.com` but not `*.example.com` | | Target Controller | Yes | The controller where the proxy will store the generated samples. By default, it will look for a Recording Controller and store them there wherever it is. | | Grouping | Yes | Whether to group samplers for requests from a single "click" (requests received without significant time separation), and how to represent that grouping in the recording: - `Do not group samplers` - store all recorded samplers sequentially, without any grouping. - `Add separators between groups` - add a controller named "`--------------`" to create a visual separation between the groups. Otherwise the samplers are all stored sequentially. - `Put each group in a new controller` - create a new [Simple Controller](/user-manual/component-reference/#Simple_Controller) for each group, and store all samplers for that group in it. - `Store 1st sampler of each group only` - only the first request in each group will be recorded. The "`Follow Redirects`" and "`Retrieve All Embedded Resources …`" flags will be turned on in those samplers. - `Put each group in a new transaction controller` - create a new [Transaction Controller](/user-manual/component-reference/#Transaction_Controller) for each group, and store all samplers for that group in it. The property `proxy.pause` determines the minimum gap that JMeter needs between requests to treat them as separate "clicks". The default is `5000` (milliseconds) i.e. 5 seconds. If you are using grouping, please ensure that you leave the required gap between clicks. | | Capture HTTP Headers | Yes | Should headers be added to the plan? If specified, a Header Manager will be added to each HTTP Sampler. The Proxy server always removes Cookie and Authorization headers from the generated Header Managers. By default it also removes `If-Modified-Since` and `If-None-Match` headers. These are used to determine if the browser cache items are up to date; when recording one normally wants to download all the content. To change which additional headers are removed, define the JMeter property `proxy.headers.remove` as a comma-separated list of headers. | | Add Assertions | Yes | Add a blank assertion to each sampler? | | Regex Matching | Yes | Use Regex Matching when replacing variables? If checked replacement will use word boundaries, i.e. it will only replace word matching values of variable, not part of a word. A word boundary follows Perl5 definition and is equivalent to `\b`. More information below in the paragraph about "`User Defined Variable replacement`". | | Prefix/Transaction name | No | Add a prefix to sampler name during recording (Prefix mode). Or replace sampler name by user chosen name (Transaction name) | | Naming scheme | No | Select the naming scheme for sampler names during recording. Default is `Transaction name` | | Naming format | No | If `Use format string` is selected as naming scheme, a freestyle format can be given. Placeholders for the transaction name, scheme, host, port, path and counter can be given by `#{name}`, `#{scheme}`, `#{host}`, `#{port}`, `#{path}`, `#{url}` and `#{counter}`. A simple format could be "`#{name}-#{counter}`", which would be equivalent to the numbered default naming scheme. For more complex formatting Java formatting for MessageFormat can be used, as in "`#{counter,number,000}: #{name}-#{path}`", which would print the counter filled with up to three zeroes. Note that scheme is called `protocol` in the sampler GUI and host is called `domain`. Default is an empty string. | | Counter start value | No | Can be used to reset the counter to a given value. Note, that the next sample will first increment and then use the value. If the first sampler should start with `1`, reset the counter to `0`. | | Create new transaction after request (ms) | No | Inactivity time between two requests needed to consider them in two separate groups. | | Type | Yes | Which type of sampler to generate (the HTTPClient default or Java) | | Redirect Automatically | Yes | Set Redirect Automatically in the generated samplers? | | Follow Redirects | Yes | Set Follow Redirects in the generated samplers? :::note Note: see "Recording and redirects" section below for important information. ::: | | Use Keep-Alive | Yes | Set Use Keep-Alive in the generated samplers? | | Retrieve all Embedded Resources | Yes | Set Retrieve all Embedded Resources in the generated samplers? | | Content Type filter | No | Filter the requests based on the `content-type` - e.g. "`text/html [;charset=utf-8 ]`". The fields are regular expressions which are checked to see if they are contained in the `content-type`. [Does not have to match the entire field]. The include filter is checked first, then the exclude filter. Samples which are filtered out will not be stored. :::note Note: this filtering is applied to the content type of the response ::: | | Patterns to Include | No | Regular expressions that are matched against the full URL that is sampled. Allows filtering of requests that are recorded. All requests pass through, but only those that meet the requirements of the `Include`/`Exclude` fields are _recorded_. If both `Include` and `Exclude` are left empty, then everything is recorded (which can result in dozens of samples recorded for each page, as images, stylesheets, etc. are recorded). :::note If there is at least one entry in the `Include` field, then only requests that match one or more `Include` patterns are recorded ::: . | | Patterns to Exclude | No | Regular expressions that are matched against the URL that is sampled. :::note Any requests that match one or more `Exclude` pattern are _not_ recorded ::: . | | Notify Child Listeners of filtered samplers | No | Notify Child Listeners of filtered samplers :::note Any response that match one or more `Exclude` pattern is _not_ delivered to Child Listeners (View Results Tree) ::: . | | Start Button | N/A | Start the proxy server. JMeter writes the following message to the console once the proxy server has started up and is ready to take requests: "`Proxy up and running!`". | | Stop Button | N/A | Stop the proxy server. | | Restart Button | N/A | Stops and restarts the proxy server. This is useful when you change/add/delete an include/exclude filter expression. | ##### Recording and redirects During recording, the browser will follow a redirect response and generate an additional request. The Proxy will record both the original request and the redirected request (subject to whatever exclusions are configured). The generated samples have "`Follow Redirects`" selected by default, because that is generally better. :::note Redirects may depend on the original request, so repeating the originally recorded sample may not always work. ::: Now if JMeter is set to follow the redirect during replay, it will issue the original request, and then replay the redirect request that was recorded. To avoid this duplicate replay, JMeter tries to detect when a sample is the result of a previous redirect. If the current response is a redirect, JMeter will save the redirect URL. When the next request is received, it is compared with the saved redirect URL and if there is a match, JMeter will disable the generated sample. It also adds comments to the redirect chain. This assumes that all the requests in a redirect chain will follow each other without any intervening requests. To disable the redirect detection, set the property `proxy.redirect.disabling=false` ##### Includes and Excludes The **include and exclude patterns** are treated as regular expressions (using Jakarta ORO). They will be matched against the host name, port (actual or implied), path and query (if any) of each browser request. If the URL you are browsing is "`http://localhost/jmeter/index.html?username=xxxx`", then the regular expression will be tested against the string: "`localhost:80/jmeter/index.html?username=xxxx`". Thus, if you want to include all `.html` files, your regular expression might look like: "`.*\.html(\?.*)?`" - or "`.*\.html` if you know that there is no query string or you only want html pages without query strings. If there are any include patterns, then the URL **must match at least one** of the patterns , otherwise it will not be recorded. If there are any exclude patterns, then the URL **must not match any** of the patterns , otherwise it will not be recorded. Using a combination of includes and excludes, you should be able to record what you are interested in and skip what you are not. :::note N.B. the string that is matched by the regular expression must be the same as the **whole** host+path string. Thus "`\.html`" will **not** match `localhost:80/index.html` ::: ##### Capturing binary POST data JMeter is able to capture binary POST data. To configure which `content-types` are treated as binary, update the JMeter property `proxy.binary.types`. The default settings are as follows: ```properties # These content-types will be handled by saving the request in a file: proxy.binary.types=application/x-amf,application/x-java-serialized-object # The files will be saved in this directory: proxy.binary.directory=user.dir # The files will be created with this file filesuffix: proxy.binary.filesuffix=.binary ``` ##### Adding timers It is also possible to have the proxy add timers to the recorded script. To do this, create a timer directly within the HTTP(S) Test Script Recorder component. The proxy will place a copy of this timer into each sample it records, or into the first sample of each group if you're using grouping. This copy will then be scanned for occurrences of variable `\${T}` in its properties, and any such occurrences will be replaced by the time gap from the previous sampler recorded (in milliseconds). When you are ready to begin, hit "`start`". :::note You will need to edit the proxy settings of your browser to point at the appropriate server and port, where the server is the machine JMeter is running on, and the port # is from the Proxy Control Panel shown above. ::: ##### Where Do Samples Get Recorded? JMeter places the recorded samples in the Target Controller you choose. If you choose the default option "`Use Recording Controller`", they will be stored in the first Recording Controller found in the test object tree (so be sure to add a Recording Controller before you start recording). If the Proxy does not seem to record any samples, this could be because the browser is not actually using the proxy. To check if this is the case, try stopping the proxy. If the browser still downloads pages, then it was not sending requests via the proxy. Double-check the browser options. If you are trying to record from a server running on the same host, then check that the browser is not set to "`Bypass proxy server for local addresses`" (this example is from IE7, but there will be similar options for other browsers). If JMeter does not record browser URLs such as `http://localhost/` or `http://127.0.0.1/`, try using the non-loopback hostname or IP address, e.g. `http://myhost/` or `http://192.168.0.2/`. ##### Handling of HTTP Request Defaults If the HTTP(S) Test Script Recorder finds enabled [HTTP Request Defaults](/user-manual/component-reference/#HTTP_Request_Defaults) directly within the controller where samples are being stored, or directly within any of its parent controllers, the recorded samples will have empty fields for the default values you specified. You may further control this behaviour by placing an HTTP Request Defaults element directly within the HTTP(S) Test Script Recorder, whose non-blank values will override those in the other HTTP Request Defaults. See [Best Practices with the HTTP(S) Test Script Recorder](/user-manual/best-practices/#proxy_server) for more info. ##### User Defined Variable replacement Similarly, if the HTTP(S) Test Script Recorder finds [User Defined Variables](/user-manual/component-reference/#User_Defined_Variables) (UDV) directly within the controller where samples are being stored, or directly within any of its parent controllers, the recorded samples will have any occurrences of the values of those variables replaced by the corresponding variable. Again, you can place User Defined Variables directly within the HTTP(S) Test Script Recorder to override the values to be replaced. See [Best Practices with the Test Script Recorder](/user-manual/best-practices/#proxy_server) for more info. :::note Please note that matching is case-sensitive. ::: Replacement by Variables: by default, the Proxy server looks for all occurrences of UDV values. If you define the variable `WEB` with the value `www`, for example, the string `www` will be replaced by `\${WEB}` wherever it is found. To avoid this happening everywhere, set the "`Regex Matching`" check-box. This tells the proxy server to treat values as Regexes (using the perl5 compatible regex matchers provided by ORO). If "`Regex Matching`" is selected every variable will be compiled into a perl compatible regex enclosed in `\b(` and `)\b`. That way each match will start and end at a word boundary. :::note Note that the boundary characters are not part of the matching group, e.g. `n.*` to match `name` out of `You can call me 'name'`. ::: If you don't want your regex to be enclosed with those boundary matchers, you have to enclose your regex within parens, e.g `('.*?')` to match `'name'` out of `You can call me 'name'`. :::note The variables will be checked in random order. So ensure, that the potential matches don't overlap. Overlapping matchers would be `.*` (which matches anything) and `www` (which matches `www` only). Non-overlapping matchers would be `a+` (matches a sequence of `a`'s) and `b+` (matches a sequence of `b`'s). ::: If you want to match a whole string only, enclose it in `(^` and `$)`, e.g. `(^thus$)`. The parens are necessary, since the normally added boundary characters will prevent `^` and `$` to match. If you want to match `/images` at the start of a string only, use the value `(^/images)`. Jakarta ORO also supports zero-width look-ahead, so one can match `/images/…` but retain the trailing `/` in the output by using `(^/images(?=/))`. :::note Note that the current version of Jakarta ORO does not support look-behind - i.e. `(?<=…)` or `(?<!…)`. ::: Look out for overlapping matchers. For example the value `.*` as a regex in a variable named `regex` will partly match a previous replaced variable, which will result in something like `\${{regex}`, which is most probably not the desired result. If there are any problems interpreting any variables as patterns, these are reported in `jmeter.log`, so be sure to check this if UDVs are not working as expected. When you are done recording your test samples, stop the proxy server (hit the "`stop`" button). Remember to reset your browser's proxy settings. Now, you may want to sort and re-order the test script, add timers, listeners, a cookie manager, etc. ##### How can I record the server's responses too? Just place a [View Results Tree](/user-manual/component-reference/#View_Results_Tree) listener as a child of the HTTP(S) Test Script Recorder and the responses will be displayed. You can also add a [Save Responses to a file](/user-manual/component-reference/#Save_Responses_to_a_file) Post-Processor which will save the responses to files. ##### Associating requests with responses If you define the property `proxy.number.requests=true` JMeter will add a number to each sampler and each response. Note that there may be more responses than samplers if excludes or includes have been used. Responses that have been excluded will have labels enclosed in `[` and `],` for example `[23 /favicon.ico]` ##### Cookie Manager If the server you are testing against uses cookies, remember to add an [HTTP Cookie Manager](/user-manual/component-reference/#HTTP_Cookie_Manager) to the test plan when you have finished recording it. During recording, the browser handles any cookies, but JMeter needs a Cookie Manager to do the cookie handling during a test run. The JMeter Proxy server passes on all cookies sent by the browser during recording, but does not save them to the test plan because they are likely to change between runs. ##### Authorization Manager The HTTP(S) Test Script Recorder grabs "`Authentication`" header, tries to compute the Auth Policy. If Authorization Manager was added to target controller manually, HTTP(S) Test Script Recorder will find it and add authorization (matching ones will be removed). Otherwise Authorization Manager will be added to target controller with authorization object. You may have to fix automatically computed values after recording. ##### Uploading files Some browsers (e.g. Firefox and Opera) don't include the full name of a file when uploading files. This can cause the JMeter proxy server to fail. One solution is to ensure that any files to be uploaded are in the JMeter working directory, either by copying the files there or by starting JMeter in the directory containing the files. ##### Recording HTTP Based Non Textual Protocols not natively available in JMeter You may have to record an HTTP protocol that is not handled by default by JMeter (Custom Binary Protocol, Adobe Flex, Microsoft Silverlight, … ). Although JMeter does not provide a native proxy implementation to record these protocols, you have the ability to record these protocols by implementing a custom `SamplerCreator`. This Sampler Creator will translate the binary format into a `HTTPSamplerBase` subclass that can be added to the JMeter Test Case. For more details see "Extending JMeter". ## HTTP Mirror Server ![HTTP Mirror Server](/images/screenshots/mirrorserver.png) The HTTP Mirror Server is a very simple HTTP server - it simply mirrors the data sent to it. This is useful for checking the content of HTTP requests. It uses default port `8081`. | Name | Required | Description | |------|----------|-------------| | Port | Yes | Port on which Mirror server listens, defaults to `8081`. | | Max Number of threads | No | If set to a value > `0`, number of threads serving requests will be limited to the configured number, if set to a value ≤ `0` a new thread will be created to serve each incoming request. Defaults to `0` | | Max Queue size | No | Size of queue used for holding tasks before they are executed by Thread Pool, when Thread pool is exceeded, incoming requests will be held in this queue and discarded when this queue is full. This parameter is only used if Max Number of Threads is greater than `0`. Defaults to `25` | :::note Note that you can get more control over the responses by adding an HTTP Header Manager with the following name/value pairs: ::: | Name | Required | Description | |------|----------|-------------| | X-Sleep | No | Time to sleep in ms before sending response | | X-SetCookie | No | Cookies to be set on response | | X-ResponseStatus | No | Response status, see [HTTP Status responses](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), example 200 OK, 500 Internal Server Error, …. | | X-ResponseLength | No | Size of response, this trims the response to the requested size if that is less than the total size | | X-SetHeaders | No | Pipe separated list of headers, example: `headerA: valueA|headerB: valueB` would set `headerA` to `valueA` and `headerB` to `valueB`. | You can also use the following query parameters: | Name | Required | Description | |------|----------|-------------| | redirect | No | Generates a 302 (Temporary Redirect) with the provided location, e.g. `?redirect=/path` | | status | No | Overrides the default status return, e.g. `?status=404 Not Found` | | v | No | Verbose flag, writes some details to standard output, e.g. first line and redirect location if specified | ## Property Display ![Property Display](/images/screenshots/property_display.png) The Property Display shows the values of System or JMeter properties. Values can be changed by entering new text in the Value column. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | ## Debug Sampler ![Debug Sampler](/images/screenshots/debug_sampler.png) The Debug Sampler generates a sample containing the values of all JMeter variables and/or properties. The values can be seen in the [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Listener Response Data pane. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | JMeter Properties | Yes | Include JMeter properties? | | JMeter Variables | Yes | Include JMeter variables? | | System Properties | Yes | Include System properties? | ## Debug PostProcessor ![Debug PostProcessor](/images/screenshots/debug_postprocessor.png) The Debug PostProcessor creates a subSample with the details of the previous Sampler properties, JMeter variables, properties and/or System Properties. The values can be seen in the [View Results Tree](/user-manual/component-reference/#View_Results_Tree) Listener Response Data pane. | Name | Required | Description | |------|----------|-------------| | Name | No | Descriptive name for this element that is shown in the tree. | | JMeter Properties | Yes | Whether to show JMeter properties (default `false`). | | JMeter Variables | Yes | Whether to show JMeter variables (default `false`). | | Sampler Properties | Yes | Whether to show Sampler properties (default `true`). | | System Properties | Yes | Whether to show System properties (default `false`). | ## Test Fragment ![Test Fragment](/images/screenshots/test_fragment.png) The Test Fragment is used in conjunction with the [Include Controller](/user-manual/component-reference/#Include_Controller) and [Module Controller](/user-manual/component-reference/#Module_Controller). | Name | Required | Description | |------|----------|-------------| | Name | Yes | Descriptive name for this element that is shown in the tree. | :::note When using Test Fragment with [Module Controller](/user-manual/component-reference/#Module_Controller), ensure you disable the Test Fragment to avoid the execution of Test Fragment itself. This is done by default since JMeter 2.13. ::: ## setUp Thread Group ![setUp Thread Group](/images/screenshots/setup_thread_group.png) A special type of ThreadGroup that can be utilized to perform Pre-Test Actions. The behavior of these threads is exactly like a normal [Thread Group](/user-manual/component-reference/#Thread_Group) element. The difference is that these type of threads execute before the test proceeds to the executing of regular Thread Groups. ## tearDown Thread Group ![tearDown Thread Group](/images/screenshots/teardown_thread_group.png) A special type of ThreadGroup that can be utilized to perform Post-Test Actions. The behavior of these threads is exactly like a normal [Thread Group](/user-manual/component-reference/#Thread_Group) element. The difference is that these type of threads execute after the test has finished executing its regular Thread Groups. :::note Note that by default it won't run if Test is gracefully shutdown, if you want to make it run in this case, ensure you check option "`Run tearDown Thread Groups after shutdown of main threads`" on Test Plan element. If Test Plan is stopped, tearDown will not run even if option is checked. ::: ![Figure 1 - Run tearDown Thread Groups after shutdown of main threads](/images/screenshots/tear_down_on_shutdown.png) _Figure 1 - Run tearDown Thread Groups after shutdown of main threads_ [^](#) {/* SYNCED-BODY:END */} {/* CUSTOM-FOOTER:START */} Use the Component Reference alongside the [Building a Test Plan](/user-manual/build-test-plan/) guide to configure elements. - [Functions and Variables](/user-manual/functions/) - parameterize component fields with dynamic values - [Properties Reference](/user-manual/properties-reference/) - JMeter properties that affect component behavior - [Listeners](/user-manual/listeners/) - detailed configuration for result viewers and reporters - [Best Practices](/user-manual/best-practices/) - which components to use and which to avoid in load tests {/* CUSTOM-FOOTER:END */} --- Title: Extending JMeter URL: https://docs.jmeter.ai/extending/extending-jmeter/ --- {/* SYNCED-BODY:START */} ## Extending JMeter ### Extending JMeter : There are several ways to extend JMeter and add functionality. JMeter is designed to make this task easier. - [A good overview of the process of extending JMeter](/JMeter Extension Scenario/) - [Creating your own Timer](#timer) - [Creating your own SampleListener (such as a visualizer, or reporter)](#listener) - [Creating your own Config Element](#config) - [Creating your own logic SamplerController](#logical) - [Creating your own test sample SamplerController](#testsample) - [Creating your own Sampler](#sampler) - [Making your custom elements play nice as a JMeter UI component](#uicomponent) - [Making your custom elements saveable and loadable from within JMeter](#saveable) --- #### Creating your own Timer The timer interface: ``` public long delay(); ``` Not too complicated. Your delay method must, each time it is called, return a long representing the number of milliseconds to delay. The constant timer returns the same number every time it's called. A random timer returns a different number each time. --- #### Creating your own SampleListener The SampleListener interface: ``` public void sampleOccurred(SampleEvent e); public void sampleStarted(SampleEvent e); public void sampleStopped(SampleEvent e); ``` sampleOccurred is the method called when a sample is completed, and the data has been collected. The SampleEvent object should contain all the information gathered from the sample. If your sample listener is primarily concerned with collecting the data from a test run, you can implement this method - the other two are for other purposes and can be ignored (though the methods have to be there for your class to compile). sampleStarted and sampleStopped are used to indicate the state of the sampling thread. This is useful for visualizers that show the user the state of all running threads (ie, they are running and waiting for response, or they're stopped and waiting to begin again). --- #### Creating your own Config Element The ConfigElement interface: ``` public void addConfigElement(ConfigElement config); public boolean expectsModification(); public Object clone(); ``` The ConfigElement interface is sparse. All ConfigElements are expected to implement a public **clone()** method. The reason for this is that config elements will be cloned for each different sampling thread, and most will be cloned for each sample. If your config element expects to be modified in the process of a test run, and you want those modifications to carry over from sample to sample (as in a cookie manager - you want to save all cookies that gets set throughout the test), then return true for the **expectsModification()** method. Your config element will not be cloned for each sample. If your config elements are more static in nature, return false. If in doubt, return false. **addConfigElement()** is required so that config elements can be layered. For instance, let's say a user creates a URL entry that contains default values - they might use this to specify a server. Then, all their test samples configure individual test cases, but leave out the server field. This information is combined via the **addConfigElement()** method. Your custom config elements should do the right thing when this method is called. Normally, this involves ignoring such calls unless the passed in ConfigElement is of the same type as yours, and then only merging in values that are not already set in the object receiving the call (ie you probably don't want to overwrite any values). You may have noticed there's no specification on how to get the config information **out** of a ConfigElement. This raises the question, who is going to use it? At the end of the line, there will be a Sampler that will need the information held in your config element. The sampler that uses your config element needs to know more about the class than the rest of JMeter - that information is not part of this interface. If at all possible, extend **AbstractConfigElement** when creating your own. By doing so, and by following some simple rules, you will get cloning and saving to XML of your config element for free (as in, you don't have to do anything!). **AbstractConfigElement** stores all its values in a Map, and provides getProperty and putProperty methods. Your config element can provide **getXXX()** and **setXXX()** methods, but these should delegate to **getProperty()** and **setProperty()**, probably using static Strings as keys in the Map. You can store any type of object, provided the objects are cloneable and Saveable (Strings, Integer, Long, Double, Float are all good in this regard). One caveat - if your config element has been restored from file, all the values held in the Map will be String objects (except for elements that implement Saveable on their own), and you may have to do casting and parsing. Example: an Integer will have to be converted from a String to an int, so your getXXX() method should check for this possibility to avoid exceptions. --- #### Creating your own logic SamplerController The SamplerController interface looks as follows: ``` Entry nextEntry(); Collection getListeners(); void addSamplerController(SamplerController controller); void addConfigElement(ConfigElement config); Object clone(); ``` Again, **clone()** is a method that must be implemented to all SamplerControllers to avoid contamination between sampling threads. The **nextEntry()** method is the essential job of a SamplerController - to deliver Entry objects to be sampled. An Entry object encapsulates all the information needed by a Sampler to do its job. The **nextEntry()** method should work like an iterator and continuously return new Entry objects. There are two boundary conditions that need to be handled. If the Controller has no more Entries to give, for the rest of the test, it should return **null**. Therefore, if your Controller has sub-controllers it is receiving Entries from, it should remove them from its list of controllers to get Entries from. The other condition is when your controller reaches the end of its list of Entries, and it needs to start over from the beginning. The parent Controller needs to know this so that it can move on to its next controller in its list. Therefore, at the end of each iteration, your SamplerController needs to return a CycleEntry object instead of a normal Entry. Conversely, this means that if your Controller receives a CycleEntry object, it should move on to the next Controller in its list. A logic controller does not generate Entries on its own, but simply regulates the flow of Entries from its sub-controllers. A logic controller might provide looping logic, or it might modify the Entries that pass through it, or whatever. GenericController provides an implementation that does absolutely nothing but pass Entries on from its sub-controllers. This class is useful both for reference purposes and to extend, since it provides a lot of methods you're likely to find useful **getListeners()** is an odd member of this Class. It's there to serve those who want their controller to receive sample data. This would be useful for a controller that modified Entry objects based on previous sample results (like an HTML spider that dynamically reacted to previously sampled webpages for links and forms). The responsibility of the controller implementer is to collect all potential listeners from the sub-controller list, and add themselves if desired. Most SamplerControllers that extend GenericController don't have to do anything. **addSamplerController(SamplerController controller)** is the method used to add sub controllers to your SamplerController. **addConfigElement(ConfigElement config)** Your SamplerController should also be capable of holding configuration elements and adding them to Entries as they pass through your controller. Again, see GenericController for reference. Essentially, all Entry objects that get returned by **nextEntry()** are handed all the ConfigElements of the controller. --- #### Creating your own test sample SamplerController A SamplerController that generates Entry objects is just like a logic controller except that it creates its own Entry objects instead of gathering them from sub-controllers (although, to be fully correct, your test sample SamplerController should handle both possibilities). Your test sample SamplerController can also benefit from extending GenericController. By doing so, most of your cloning and saving needs are handled (but probably not entirely). See HttpTestSample as reference. --- #### Creating your own Sampler The Sampler interface: ``` public SampleResult sample(Entry e) ``` Your Sampler has two responsibilities. Of lesser importance, it should do whatever it is you want to do, given an Entry object that hopefully contains information about what is to be sampled. Of greater importance, your sampler should return a **SampleResult** object that holds information about the sampling. Information such as how long the sample took, the text response from the sample (if appropriate), and a string that describes the location of what was sampled. The SampleResult interface is essentially a Map with public static Strings as keys. --- #### Making your custom elements play nice as a JMeter UI component In order to take part in the JMeter UI, your component needs to implement the JMeterComponentModel interface: ``` Class getGuiClass(); public String getName(); public void setName(String name); public Collection getAddList(); public String getClassLabel(); public void uncompile(); ``` Most of this stuff is easy, boring, and tedious. **getName()**, **setName()** is a simple String property that is the name of the object. **getClassLabel()** should return a String that describes the class. This string will be displayed to the user and so should be short but meaningful. **getGuiClass()** should return a Class object for the class that will be used as a GUI component. This class should be a subclass of java.awt.Container, and preferably a subclass of **javax.swing.JComponent**. **getAddList()** should return a list of either Strings or JMenus. These Strings represent the Classes that can be added to your SamplerController. Each String should correspond to the target class's **getClassLabel()** String. **MenuFactory** is a class that will return some preset menu lists (such as all available SamplerControllers, all available ConfigElements, etc). **uncompile()** is a cleanup method used between sampling runs. When the user hits "Start", JMeter "compiles" the objects in the tree. Child nodes are added to their parent objects recursively until there is one TestPlan object, which is then submitted for testing. Afterward, these elements have to un-added from their parent objects, or uncompiled. To uncompile your class, simply clear all your data structures that are holding sub-elements. For your SamplerController, this will be the list of sub-controllers and the list of ConfigElements. That's it, except for your GUI class. If your SamplerController has no configuration needs, just return org.apache.jmeter.gui.NamePanel, and the user will at least be able to change the name of your component. Otherwise, create a gui class that implements the **ModelSupported** interface: ``` void setModel(Object model); public void updateGui(); ``` **setModel()** is used to hand your JMeterModelComponent class to the GUI class when it is instantiated. It is your responsibility for providing the means by which the Gui class updates the values in the model class. For updating in the other direction, there is **updateGui()**, which the model class can call if necessary. Note, normally, this call is made for you automatically whenever the Gui is brought to the screen. If you are creating a Visualizer, then you may need to use **updateGui()**. For reference, refer to UrlConfigGui (in org.apache.jmeter.protocol.http.config.gui). If you have done all this correctly, there's just one more step. If you compile your classes into the ApacheJMeter.jar file, then you're done. Your classes will be automatically found and used. Otherwise, you will need to modify jmeter.properties. The _search_paths_ property should be modified to include the path where your classes are. This does not obviate the need for your classes to be in the JVM's CLASSPATH - it is an additional requirement. Otherwise, your classes will not be detected, and the Gui will not make them available to the user. --- #### Making your custom elements saveable and loadable from within JMeter The Saveable interface has just one method: ``` public Class getTagHandlerClass() ``` This method simply returns the Class object that represents the Class that handles the saving and loading of your component. To write this SaveHandler, make a class that extends **TagHandler** (from org.apache.jmeter.save.xml). Note, if your component extends AbstractConfigElement, it is already fully Saveable - provided you only have information stored in the Map from AbstractConfigElement. To write your own TagHandler, you will have to implement the following methods: ``` public abstract void setAtts(Attributes atts) throws Exception public String getPrimaryTagName() public void save(Saveable objectToSave,Writer out) throws IOException ``` **getPrimaryTagName()** should return the String that is the XML tagname that your class handles. When you save your object, it should all be contained within an XML tag of the same name. This will ensure that when JMeter's parser hits that tag, your class will be called upon to handle the data. **setAtts(Attributes atts)** is called when the parser first hits your tag. If this primary tag has any attributes, this method represents your chance to save the information. **save(Saveable objectToSave,Writer out)** - when the user selects "Save", JMeter will call this method and hand the Saveable object to be saved (it will be the object that specified your TagHandler as the class responsible for saving it). This method should use the given Writer object to print all the XML necessary to save the current state of the objectToSave. There's more you have to do to handle creating a new Object when JMeter parses an XML file. However, there's no standard interface you need to implement, but rather, JMeter uses reflection to generate method calls into your class. When JMeter hits a tag that corresponds to your PrimaryTagName, an instance of your TagHandler will be created, and its **setAtts()** method will get called. Thereafter, methods are called depending on subsequent tags and character data. For every tag, JMeter calls **<tag-name>TagStart(Attributes atts)**, and for every end tag, JMeter calls **<tag-name>TagEnd()**. Additionally, JMeter will call a method that corresponds to all tags that are current. So, for instance, if JMeter runs into a tag name "foo", then **foo(Attributes atts)** will be called. If JMeter then parses character data, then **foo(String data)** will be called. If JMeter parses a tag within foo, called "nestedFoo", then JMeter will call **foo_nestedFoo(Attributes atts)** and **foo_nestedFoo(String data)**. And so on. An annotated example: ``` public class AbstractConfigElementHandler extends TagHandler { private AbstractConfigElement config; private String currentProperty; public AbstractConfigElementHandler() { } /** * Returns the AbstractConfigElement object parsed from the XML. This method * is required to fulfill the SaveHandler interface. It is used by the XML * routines to gather all the saved objects. */ public Object getModel() { return config; } /** * This is called when a tag is first encountered for this handler class to handle. * The attributes of the tag are passed, and the SaveHandler object is expected * to instantiate a new object. */ public void setAtts(Attributes atts) throws Exception { String className = atts.getValue("type"); config = (AbstractConfigElement)Class.forName(className).newInstance(); } /** * Called by reflection when a <property> tag is encountered. Again, the * attributes are passed. */ public void property(Attributes atts) { currentProperty = atts.getValue("name"); } /** * Called by reflection when text between the begin and end <property> * tag is encountered. */ public void property(String data) { if(data != null && data.trim().length() > 0) { config.putProperty(currentProperty,data); currentProperty = null; } } /** * Called by reflection when the <property> tag is ended. */ public void propertyTagEnd() { // Here's a tricky bit. See below for explanation. List children = xmlParent.takeChildObjects(this); if(children.size() == 1) { config.putProperty(currentProperty,((TagHandler)children.get(0)).getModel()); } } /** * Gets the tag name that will trigger the use of this object's TagHandler. */ public String getPrimaryTagName() { return "ConfigElement"; } /** * Tells the object to save itself to the given output stream. */ public void save(Saveable obj,Writer out) throws IOException { AbstractConfigElement saved = (AbstractConfigElement)obj; out.write("<ConfigElement type=\""); out.write(saved.getClass().getName()); out.write("\">\n"); Iterator iter = saved.getPropertyNames().iterator(); while (iter.hasNext()) { String key = (String)iter.next(); Object value = saved.getProperty(key); writeProperty(out,key,value); } out.write(</ConfigElement>"); } /** * Routine to write each property to xml. */ private void writeProperty(Writer out,String key,Object value) throws IOException { out.write("<property name=\""); out.write(key); out.write("\">\n"); JMeterHandler.writeObject(value,out); out.write("\n</property>\n"); } ``` In the **propertyTagEnd()** method, **takeChildObjects()** is called on the xmlParent instance variable. xmlParent is inherited from TagHandler - the DocumentHandler object that is running the show. xmlParent takes an XML file that represents a portion of the test configuration tree, and recreates a tree-like data structure. When it is done, it will convert its tree-like data structure into the test configuration tree structure. However, sometimes, a tree element has sub objects that you do not want represented in the tree - rather, they are part of your object. But, they may be complicated enough to warrant their own SaveHandler class, and thus, the xmlParent picks them up as part of its tree. When the tag is done, and you know that there are child objects you want to grab, you can call the **takeChildObjects()** method and get a List object containing them all. This will remove them from the tree, and you can add them to your object that you're creating. UrlConfig is good example. It extends AbstractConfigElement, so it uses exactly the code above to save and reload itself from XML. However, one of the pieces of data that UrlConfig stores is an Arguments object. Arguments is too complicated to save to file as a simple string, so it has its own Handler object (ArgumentsHandler). In the above code, when the call to **JMeterHandler.writeObject(value,out)** is made, the writeObject method detects whether the object implements Saveable, and if so, calls the object's SaveHandler class to deal with it. This means, however, that when reading that XML file, the Argument object will show up as a separate entity in the data tree, whereas it originally was just part of the data of the UrlConfig object. In order to preserve that relationship, it's necessary for the AbstractConfigElementHandler to check after each property tag is done for child objects in the tree, and take them for its own use. Study the other SaveHandler objects and the TagHandler class to learn more about how saving is accomplished. Once you understand the design, writing your own SaveHandler is very easy. {/* SYNCED-BODY:END */} --- Title: Developer's guide: Dashboard generator URL: https://docs.jmeter.ai/extending/devguide-dashboard/ --- {/* SYNCED-BODY:START */} ## Dashboard generator This document describes the architecture and operation of the dashboard generation engine. ### 1 Overview #### 1.1 Architecture The dashboard generation engine is a modular feature based on samples operation processes. The processes can be represented by the following diagram: ![Figure 1 - Dashboard generation overview](/images/screenshots/dashboard.png) _Figure 1 - Dashboard generation overview_ In this view, you can see: - A source from where samples are produced (e.g. CSV file). - A chain of items, named consumers, that operate on the samples that go through the chain (e.g. Filtering, sorting, calculation, …). - An execution context, named sample context, where the results of consumers calculations are stored. - A set of items, named exporters, that use the content of the sample context to generate a final result to the user (e.g. HTML page generation). #### 1.2 Operation Before producing samples, the source is associated with a sample context that will be used to store the consumers results. Then a chain of consumers is built using JMeter properties (prefixed by `jmeter.reportgenerator` ) in order to enable the user to customize it. When the source emits a sample, it sends it to the first consumer of the chain. The consumer can have different behaviors: - It can process the sample and send it to the next consumers. - It cannot process the sample, so it stores it and continues to receive other samples. When it can process the stored samples, it does so and sends the whole to the next consumers (e.g. sorting). - It can choose to discard the sample (e.g. filtering). When the source stops producing samples, consumers can publish a result in the sample context. The latter is send to the set of exporters in order to create results used by final user. ### 2 Consumers chain details ![Figure 2 - Consumers chain](/images/screenshots/chain.png) _Figure 2 - Consumers chain_ The chain begins with a normalizer consumer in charge of standardizing the timestamp of each sample because JMeter allows different timestamp formats (See `jmeter.save.saveservice.timestamp_format` ). Then two consumers have to define the start time and end time of the load tests. At the same level a filter consumer keeps or discards samples depending on the `jmeter.reportgenerator.sample_filter` property. Another filter is plugged after to discard controller samples. Depending on the property `jmeter.reportgenerator.graph.<graph_id>.exclude_controllers` , the graph consumer matching the `graph_id` identifier will be set at position `A` or `B` . ### 3 Template processing #### 3.1 Overview The default exporter of the generator use the template engine [freemarker](http://freemarker.org/) to produce html pages. Template files are located in the template directory defined by the JMeter property "`jmeter.reportgenerator.template_dir`" and have the extension "`.fmkr`". The graph references in the template files use the syntax : `\${<graph_id>.<value>}` where : **`graph_id`** : is the identifier of the graph matching the JMeter properties definition **`value`** : is the name of the value where data are stored. Each graph produces the following values : **`maxX`:** : The maximum abscissa of the graph (double). **`maxY`:** : The maximum ordinate of the graph (double). **`minX`:** : The minimum abscissa of the graph (double). **`minY`:** : The maximum ordinate of the graph (double). **`title`:** : The title of the graph (string). **`values`:** : A JSON object representing the data of the graph series (string). #### 3.2 Customization You can customize the dashboard generation by modifying the files in the template directory. If you want to add a graph to the dashboard, you have to [declare it among the JMeter properties](#configure_graph) and use its references in the template files. If you want to remove a graph from the dashboard, you must remove all its references in the template files and clear JMeter properties. ### 4 Limitations and Outlooks - Till now, there is only one sample source implementation which is strongly coupled with the CSV file format, we should allow other kinds of source by using a sample source interface. - To add customized graph, users must extend the `AbstractGraphConsumer` or use one of the implementations provided in the package `org.apache.jmeter.report.processor.graph.impl` . This could be enhanced by making concrete the base class and give public access to additional properties (like selectors). But first we have to resolve the issue of shared properties (e.g. over time graphs must dispatch the same granularity property to the keys selector and time rate aggregator). - The chain building is dispatched between the `org.apache.jmeter.report.dashboard.ReportGenerator.generate` method and the implementation of the consumers. So the code in charge of the building is split and furthermore some consumers can be redundant and harm the performance of report generation, not load testing. E.g. Each `LatencyVSRequestGraphConsumer` and `ResponseTimeVSRequestGraphConsumer` instances use an embedded consumer that could be shared depending on `granularity` and `exclude_controllers` properties. So we should enable the consumers to define the chain they require and provide a single chain builder that processes these chain requirements to instantiate needed consumers on demand. I.e. for the same chain requirement declaration, the same consumer instances are used. Otherwise if the declaration differs, a new branch of consumers is created. - The graphs (DOM elements) in the generated HTML page should be dynamically build in order to match the graphs defined in JMeter properties. - Some improvements can be done on the generated html pages: - Using a single page, and hide graphs depending on the navigation menu selection. - Adding a loading animation when graphs are build or refreshed. - Let the user determine if a graph is zoomable using a JMeter property. - Using the `jquery.plot.setData()` method to handle series activation/deactivation rather than rebuild the graph. {/* SYNCED-BODY:END */} --- Title: JMeter Release Notes URL: https://docs.jmeter.ai/releases/ --- {/* GENERATED by scripts/generate-release-pages.mjs - do not edit by hand */} Pick a version to see everything it shipped: new features, improvements, bug fixes, and incompatible changes. Release notes are generated from the official Apache JMeter changelog. Need the latest bits? Head to [Download JMeter](/reference/download-jmeter/) or the [getting started guide](/getting-started/get-started/). ### [JMeter 6.0.0](/releases/6-0-0/) 23 improvements · 6 bug fixes · highlights included ### [JMeter 5.6.2](/releases/5-6-2/) 1 bug fixes ### [JMeter 5.6.1](/releases/5-6-1/) 2 improvements · 2 bug fixes · highlights included ### [JMeter 5.6](/releases/5-6/) 23 improvements · 15 bug fixes ### [JMeter 5.5](/releases/5-5/) 21 improvements · 32 bug fixes ### [JMeter 5.4.3](/releases/5-4-3/) documented changes ### [JMeter 5.4.2](/releases/5-4-2/) documented changes ### [JMeter 5.4.1](/releases/5-4-1/) 2 improvements · 19 bug fixes · 1 incompatible changes ### [JMeter 5.4](/releases/5-4/) 13 improvements · 24 bug fixes · 1 incompatible changes ### [JMeter 5.3](/releases/5-3/) 27 improvements · 19 bug fixes · 2 incompatible changes ### [JMeter 5.2.1](/releases/5-2-1/) 1 improvements · 3 bug fixes ### [JMeter 5.2](/releases/5-2/) 46 improvements · 26 bug fixes · 3 incompatible changes ### [JMeter 5.1.1](/releases/5-1-1/) 6 improvements · 10 bug fixes ### [JMeter 5.1](/releases/5-1/) 42 improvements · 39 bug fixes · 4 incompatible changes ### [JMeter 5.0](/releases/5-0/) 52 improvements · 43 bug fixes · 6 incompatible changes ### [JMeter 4.0](/releases/4-0/) 81 improvements · 26 bug fixes · 14 incompatible changes ### [JMeter 3.3](/releases/3-3/) 27 improvements · 36 bug fixes · 5 incompatible changes ### [JMeter 3.2](/releases/3-2/) 56 improvements · 41 bug fixes · 20 incompatible changes ### [JMeter 3.1](/releases/3-1/) 61 improvements · 36 bug fixes · 15 incompatible changes ### [JMeter 3.0](/releases/3-0/) 108 improvements · 59 bug fixes · 30 incompatible changes ### [JMeter 2.13](/releases/2-13/) 20 improvements · 16 bug fixes · 3 incompatible changes ### [JMeter 2.12](/releases/2-12/) 38 improvements · 45 bug fixes · 4 incompatible changes ### [JMeter 2.11](/releases/2-11/) 15 improvements · 9 bug fixes · 4 incompatible changes ### [JMeter 2.10](/releases/2-10/) 52 improvements · 61 bug fixes · 11 incompatible changes ### [JMeter 2.9](/releases/2-9/) documented changes ### [JMeter 2.8](/releases/2-8/) documented changes ### [JMeter 2.7](/releases/2-7/) documented changes ### [JMeter 2.6](/releases/2-6/) documented changes ### [JMeter 2.5.1](/releases/2-5-1/) documented changes ### [JMeter 2.5](/releases/2-5/) documented changes ### [JMeter 2.4](/releases/2-4/) documented changes ### [JMeter 2.3.4](/releases/2-3-4/) documented changes ### [JMeter 2.3.3](/releases/2-3-3/) documented changes ## Related - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) - [Download JMeter](/reference/download-jmeter/) --- Title: Changes URL: https://docs.jmeter.ai/user-manual/changes/ --- {/* SYNCED-BODY:START */} ## Changes {/* CUSTOM-INTRO:START */} :::note[Version-specific behavior] Use this page when behavior differs between JMeter releases, especially for components, properties, Java support, and distributed testing defaults. ::: {/* CUSTOM-INTRO:END */} :::note **This page details the changes made in the current version only.** Earlier changes are detailed in the [History of Previous Changes](/user-manual/changes-history/). ::: :::note JMeter 6.x requires Java 17 or later for execution (Java 21 is recommended). ::: ## Version 6.0.0 Summary - [Changes](#Changes) - [Bug fixes](#Bug fixes) ## Changes #### General - [PR#6220](https://github.com/apache/jmeter/pull/6220) Require Java 17 or later for running JMeter - [PR#6550](https://github.com/apache/jmeter/pull/6550) Require Kotlin 1.9 or later for running JMeter - [PR#6274](https://github.com/apache/jmeter/pull/6274) Change references to old MySQL driver to new class `com.mysql.cj.jdbc.Driver` - [Issue#6352](https://github.com/apache/jmeter/issues/6352) Calculate delays in Open Model Thread Group and Precise Throughput Timer relative to start of Thread Group instead of the start of the test. - [Issue#6357](https://github.com/apache/jmeter/issues/6357)[PR#6358](https://github.com/apache/jmeter/pull/6358) Ensure writable directories when copying template files while report generation. - [PR#6509](https://github.com/apache/jmeter/pull/6509)[PR#6675](https://github.com/apache/jmeter/pull/6675) Synchronize recent file menu across multiple JVMs. Contributed by Corneliu C (https://github.com/KingRabbid) - [PR#6596](https://github.com/apache/jmeter/pull/6596)Fallback to English locale when loading test plans that use string values for enum properties, so old sample plans load correctly even with non-English locales. #### HTTP Samplers and Test Script Recorder - [PR#5891](https://github.com/apache/jmeter/pull/5891)Skip Internet Explorer 6-9 conditional comment processing when fetching resource links - [Issue#5466](https://github.com/apache/jmeter/issues/5466)Allow enabling or disabling individual HTTP request arguments in the HTTP Sampler UI. Contributed by Pasquale Pochop (github.com/pochopsp) - [Issue#6250](https://github.com/apache/jmeter/issues/6250)Avoid adding "; charset=" automatically to `multipart/form-data` requests to align behavior with modern HTTP clients. - [Issue#6080](https://github.com/apache/jmeter/issues/6080)Preserve the original HTTP method when following 307 and 308 redirects according to the HTTP specification. Contributed by LeeJiWon (github.com/dlwldnjs1009) - [Issue#6267](https://github.com/apache/jmeter/issues/6267)[PR#6268](https://github.com/apache/jmeter/pull/6268)Add a space between key and value after `:` in View Results Tree > Sampler result tab for better readability. #### Timers, Assertions, Config, Pre- & Post-Processors - [Issue#6448](https://github.com/apache/jmeter/issues/6448)Support trailing empty default values in JSON Extractor so expressions like `\${VAR:-}` are handled correctly. Contributed by Raul Almeida (github.com/ratacolita) - [PR#6596](https://github.com/apache/jmeter/pull/6596)Add a schema for ConstantThroughputTimer and use it to ensure required properties are initialized properly. #### Non-functional changes - Update Apache Tika to 3.x from 1.x to use the latest parser engine. - Update Saxon-HE to 12.x from 11.x for XSLT and XQuery processing. - Update Groovy to 5.x for the Groovy-based scripting environment. - Update Bouncy Castle to 1.82 for cryptographic operations. - Update json-path to 2.10.0 for JSON query expressions. - Update Neo4j Java driver to 6.x for Bolt-based database tests. - Update Rhino JavaScript engine to 1.8.0 for JSR-223 JavaScript execution. #### UI - [PR#6333](https://github.com/apache/jmeter/pull/6333)Apply HiDPI mode automatically when setting up the GUI so JMeter looks sharp on high-resolution displays. Contributed by Gabriele Coletta (github.com/gdmg92) - [PR#6656](https://github.com/apache/jmeter/pull/6656)Replace the previous feather icon with the new oak leaf in the JMeter logo. ## Bug fixes #### General - [PR#6654](https://github.com/apache/jmeter/pull/6654)[Issue#6611](https://github.com/apache/jmeter/issues/6611)Support JDK 25 and above for result collectors with empty file names - Trim whitespace when parsing numeric JMeter properties so accidental spaces do not silently change configuration values. - [PR#6372](https://github.com/apache/jmeter/pull/6372)Fix KeyManager logging when using CLI mode so keystore passwords are not incorrectly reported as missing. Contributed by Patrick Uiterwijk (patrick at puiterwijk.org) - [Issue#5937](https://github.com/apache/jmeter/issues/5937)Remove deprecated Log4j package scanning and configure plugin metadata processing to improve startup time and avoid deprecation warnings. Contributed by Piotr P. Karwasz (github.com/piotrgithub) - [PR#6620](https://github.com/apache/jmeter/pull/6620)Fix report generation paths so dashboard output files are created in the correct location after internal refactoring. - [Bug 6456](https://bz.apache.org/bugzilla/show_bug.cgi?id=6456)Handle malformed percent-encoded URLs gracefully when recording HTTP traffic, logging a warning instead of failing the recording. ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Raul Almeida (github.com/ratacolita) - Pasquale Pochop (github.com/pochopsp) - Gabriele Coletta (github.com/gdmg92) - Patrick Uiterwijk (patrick at puiterwijk.org) - Piotr P. Karwasz (github.com/piotrgithub) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). JMeter now ships with a JSR-223 compatible JavaScript engine by default (Mozilla Rhino 1.8.0), so you do not need to download Rhino separately anymore. If you prefer to use Nashorn instead, you can still add it as a module. One way to download version 15.7 (or later) and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.7/nashorn-core-15.7.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.9.1/asm-9.9.1.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.9.1/asm-commons-9.9.1.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.9.1/asm-util-9.9.1.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.9.1/asm-tree-9.9.1.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.9.1/asm-analysis-9.9.1.jar popd export JVM_ARGS="--module-path $PWD/lib/modules" ./bin/jmeter ``` {/* SYNCED-BODY:END */} --- Title: History of Previous Changes URL: https://docs.jmeter.ai/user-manual/changes-history/ --- {/* SYNCED-BODY:START */} ## History of Previous Changes :::note **This page details the changes made in previous versions only.** Current changes are detailed in [Changes](/user-manual/changes/). ::: Changes sections are chronologically ordered from top (most recent) to bottom (least recent) ## Version 5.6.2 Summary - [Bug fixes](#Bug fixes) ## Bug fixes #### General - [PR#6042](https://github.com/apache/jmeter/pull/6042)[Issue#6041](https://github.com/apache/jmeter/issues/6041)Fix compatibility with Maven's pom.xml parser by adding explicit versions for `com.google.auto.service:auto-service-annotations` (regression since 5.6) ## Thanks We thank all contributors mentioned in bug and improvement sections above: We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - [Issue#6043](https://github.com/apache/jmeter/issues/6043) `Min` is always `0` in `Summary Report` (fixed in 5.6.3) - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.14.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-engine-1.7.14.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 (or later) and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.3/nashorn-core-15.3.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.5/asm-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.5/asm-util-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar popd export JVM_ARGS="--module-path $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.6.1 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ## Improvements #### HTTP Samplers and Test Script Recorder - [PR#6010](https://github.com/apache/jmeter/pull/6010)Use UTF-8 as a default encoding in HTTP sampler. It enables sending parameter names, and filenames with unicode characters - [PR#6010](https://github.com/apache/jmeter/pull/6010)Test Recorder will use UTF-8 encoding by default, so it will infer human-readable arguments rather than percent-encoded ones ## Non-functional changes - [PR#6000](https://github.com/apache/jmeter/pull/6000)Add release-drafter for populating GitHub releases info based on the merged PRs - [PR#5989](https://github.com/apache/jmeter/pull/5989)Use Gradle toolchains for JDK provisioning, enable building and testing with different JDKs, start testing with Java 21 - [PR#5991](https://github.com/apache/jmeter/pull/5991)Update jackson-core, jackson-databind, jackson-annotations to 2.15.2 (from 2.15.1) - [PR#5993](https://github.com/apache/jmeter/pull/5993)Update ph-commons to 10.2.5 (from 10.2.4) - [PR#6017](https://github.com/apache/jmeter/pull/6017)Update kotlin-stdlib to 1.8.22 (from 1.8.21) - [PR#6020](https://github.com/apache/jmeter/pull/6020)Update error_prone_annotations to 2.20.0 (from 2.19.1) - [PR#6023](https://github.com/apache/jmeter/pull/6023)Update checker-qual to 3.35.0 (from 3.34.0) #### Other Samplers - [PR#6028](https://github.com/apache/jmeter/pull/6028) Change default value for `sampleresult.default.encoding` to UTF-8 (it inherits default HTTP encoding which was modified in [PR#6010](https://github.com/apache/jmeter/pull/6010)) ## Bug fixes #### Thread Groups - [PR#6011](https://github.com/apache/jmeter/pull/6011)Regression since 5.6: ThreadGroups are running endlessly in non-gui mode: use default value for LoopController.continue_forever rather than initializing it in the constructor #### Other Samplers - [PR#6012](https://github.com/apache/jmeter/pull/6012) Java Request sampler cannot be enabled again after disabling in UI (regression since 5.6) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Alex Schwartz, [@alexsch01](https://github.com/alexsch01) We also thank bug reporters who helped us improve JMeter. - David Getzlaff, [@dgetzlaf](https://github.com/dgetzlaf) - LeeBaul, [@libaolu](https://github.com/libaolu) Apologies if we have omitted anyone else. ## Known problems and workarounds - `pom.xml` misses `<version>` tags for `auto-service-annotations`, so Maven can't infer transitive dependencies. The issue is resolved in 5.6.2 - [Issue#6043](https://github.com/apache/jmeter/issues/6043) `Min` is always `0` in `Summary Report` (fixed in 5.6.3) - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.14.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-engine-1.7.14.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 (or later) and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.3/nashorn-core-15.3.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.5/asm-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.5/asm-util-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar popd export JVM_ARGS="--module-path $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.6 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ## Improvements #### Thread Groups - [Issue#5682](https://github.com/apache/jmeter/issues/5682)[PR#717](https://github.com/apache/jmeter/pull/717) Open Model Thread Group: avoid skipping rows from CSV Data Set Config - Support custom thread group implementations in "Add think time" and "Save as test fragment" actions - Open Model Thread Group: interrupt pending HTTP requests and other `Interruptible` test elements on test stop #### HTTP Samplers and Test Script Recorder - [PR#5911](https://github.com/apache/jmeter/pull/5911) Use Caffeine for caching HTTP headers instead of commons-collections4 LRUMap - [PR#5947](https://github.com/apache/jmeter/pull/5947) Fetch resources referenced in `<link "rel"="preload"...>` elements - [PR#5869](https://github.com/apache/jmeter/pull/5869) Allow more templates to format sampler names in the recorder: `#{url}`, `#{method}`, `#{scheme}`, `#{host}`, `#{port}` #### Other samplers - [PR#5909](https://github.com/apache/jmeter/pull/5909) Use Caffeine for caching compiled scripts in JSR223 samplers instead of commons-collections4 LRUMap #### General - [PR#5792](https://github.com/apache/jmeter/pull/5792)Add KeyStroke for start_no_timers (Start no pauses: CRTL+SHIFT+n) - [PR#5899](https://github.com/apache/jmeter/pull/5899)Speed up CPU-bound tests by skipping `recoverRunningVersion` for elements that are shared between threads (the ones that implement `NoThreadClone`) - [PR#5914](https://github.com/apache/jmeter/pull/5914)Use `Locale.ROOT` instead of default locale for `toUpperCase`, and `toLowerCase` to avoid surprises with dotless I in `tr_TR` locale - [PR#5885](https://github.com/apache/jmeter/pull/5885)Use Java's `ServiceLoader` for loading plugins instead of classpath scanning. It enables faster startup - [PR#5788](https://github.com/apache/jmeter/pull/5788)`FunctionProperty` no longer caches the value. Previously it cached the values based on iteration number only which triggered wrong results on concurrent executions. The previous behavior can be temporary restored with `function.cache.per.iteration` property. - [PR#5920](https://github.com/apache/jmeter/pull/5920)Improve HTTP HeaderManager performance when it contains many headers: skip reinitialization on each iteration - [PR#5920](https://github.com/apache/jmeter/pull/5920)Use AtomicInteger and AtomicLong instead of synchronized primitives for JMeterContextService#numberOfThreads - [PR#5920](https://github.com/apache/jmeter/pull/5920)Cache bean properties in `TestBeanHelper` and avoid synchronization, so test plans with `TestBean`-based elements is faster - [PR#5920](https://github.com/apache/jmeter/pull/5920)Improve computation when many threads actively produce samplers by using `LongAdder` and similar concurrency classes to avoid synchronization in `Calculator` - [PR#5920](https://github.com/apache/jmeter/pull/5920)Reduce synchronization contention on `AbstractTestElement` that are shared between threads (the ones that implement `NoThreadClone`) - [PR#5934](https://github.com/apache/jmeter/pull/5934)Added caching for date formatters for `__time` function - [PR#710](https://github.com/apache/jmeter/pull/710)[Issue#5666](https://github.com/apache/jmeter/issues/5666)Added Shortcut key event for Reset search: `ctrl + alt + F`, `cmd + alt + F` - [PR#5959](https://github.com/apache/jmeter/pull/5959)`TestElement` has been migrated to Kotlin, so nullable types are annotated better - [PR#5944](https://github.com/apache/jmeter/pull/5944)Add PI for declaring `TestElement` schemas so element properties are easier to access in code (see `TestElementSchema`, `TestElement#getSchema()`, `TestElement#getProps()`) - [PR#5944](https://github.com/apache/jmeter/pull/5944)Enable usage of `\${...}` expressions for checkbox controls (see context menus for checkboxes, however, the individual components should be adapted individually) - [PR#678](https://github.com/apache/jmeter/pull/678)Experimental Kotlin and Java DSL for programmatic test plan generation (see [Creating a plan with Kotlin DSL](/usermanual/build-programmatic-test-plan/#treebuilder_kotlin_dsl)) ## Non-functional changes - [PR#725](https://github.com/apache/jmeter/pull/725)Add Chinese Simplified Translation for Open Model Thread Group - [PR#5710](https://github.com/apache/jmeter/pull/5710)Add GitHub Issue templates - [PR#5910](https://github.com/apache/jmeter/pull/5910)Use Caffeine for caching customizers in TestBeanGUI instead of commons-collections4 LRUMap - [PR#5713](https://github.com/apache/jmeter/pull/5713)[PR#5931](https://github.com/apache/jmeter/pull/5931)Update Spock to 2.3-groovy-3.0 (from 2.1-groovy-3.0) - [Issue#5718](https://github.com/apache/jmeter/issues/5718)Update Apache commons-text to 1.10.0 (from 1.9) - [PR#5731](https://github.com/apache/jmeter/pull/5731)Update docs for `changeCase` function. `UPPER` is the default - [PR#5924](https://github.com/apache/jmeter/pull/5924)Update Apache commons-io to 2.12.0 (from 2.11.0) - [PR#5921](https://github.com/apache/jmeter/pull/5921)Update Jackson Core to 2.15.1 (from 2.13.3) - [PR#5921](https://github.com/apache/jmeter/pull/5921)Update Jackson Databind to 2.15.1 (from 2.13.3) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update Tika Parser to 1.28.5 (from 1.28.3) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update JSoup to 1.16.1 (from 1.15.1) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update Apache commons-net to 3.9.0 (from 3.8.0) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update XStream to 1.4.20 (from 1.4.19) - [PR#5763](https://github.com/apache/jmeter/pull/5763)[PR#5814](https://github.com/apache/jmeter/pull/5814)Updated Gradle to 8.1.1 (from 7.2) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Added Apache Httpclient5 5.1.3 - [PR#5833](https://github.com/apache/jmeter/pull/5833)Update Apache Freemarker to 2.3.32 (from 2.3.31) - [PR#5830](https://github.com/apache/jmeter/pull/5830)Update Apache Groovy to 3.0.17 (from 3.0.11) - [PR#5862](https://github.com/apache/jmeter/pull/5862)Update Apache Httpclient to 4.5.14 (from 4.5.13) - [PR#5880](https://github.com/apache/jmeter/pull/5880)Update Apache Xalan to 2.7.3 (from 2.7.2) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Update Saxon-HE to 11.5 (from 11.5) - [PR#5840](https://github.com/apache/jmeter/pull/5840)[PR#5930](https://github.com/apache/jmeter/pull/5930)Update accessors-smart to 2.4.11 (from 2.4.8) - [PR#5837](https://github.com/apache/jmeter/pull/5837)Update asm to 9.5 (from 9.3) - [PR#5840](https://github.com/apache/jmeter/pull/5840)[PR#5930](https://github.com/apache/jmeter/pull/5930)Update json-smart to 2.4.11 (from 2.4.8) - [PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlin-stdlib to 1.8.21 (from 1.6.21) - [PR#5889](https://github.com/apache/jmeter/pull/5889)[PR#5918](https://github.com/apache/jmeter/pull/5918)[PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlinx-coroutines-core to 1.8.21 (from 1.6.21) - [PR#5889](https://github.com/apache/jmeter/pull/5889)[PR#5918](https://github.com/apache/jmeter/pull/5918)[PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlinx-coroutines-swing to 1.8.21 (from 1.6.21) - [PR#5907](https://github.com/apache/jmeter/pull/5907)Update lets-plot-batik to 3.2.0 (from 2.1.1) - [PR#5907](https://github.com/apache/jmeter/pull/5907)Update lets-plot-jvm to 4.3.0 (from 3.1.1) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-1.2-api to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-api to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-core to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-slf4j-impl to 2.20.0 (from 2.17.2) - [PR#5861](https://github.com/apache/jmeter/pull/5861)Update neo4j-java-driver to 4.4.11 (from 4.4.6) - [PR#5853](https://github.com/apache/jmeter/pull/5853)Update org.jetbrains:annotations to 24.0.1 (from 23.0.0) - [PR#5868](https://github.com/apache/jmeter/pull/5868)[PR#5886](https://github.com/apache/jmeter/pull/5886)Update ph-commons to 10.2.4 (from 10.1.6) - [PR#5861](https://github.com/apache/jmeter/pull/5861)Update reactive-streams to 1.0.4 (from 1.0.3) - [PR#5847](https://github.com/apache/jmeter/pull/5847)Update rsyntaxtextarea to 3.3.3 (from 3.2.0) - [PR#5839](https://github.com/apache/jmeter/pull/5839)Update svgSalamander to 1.1.4 (from 1.1.2.4) - [PR#5852](https://github.com/apache/jmeter/pull/5852)Update xmlgraphics-commons to 2.8 (from 2.7) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Update xmlresolver to 4.6.4 (from 4.2.0) - [PR#693](https://github.com/apache/jmeter/pull/693)Added randomized test GitHub Actions matrix for better coverage of locales and time zones - [PR#5960](https://github.com/apache/jmeter/pull/5960)Add OpenJDK JMH for creating microbenchmarks in JMeter code - [Issue#5961](https://github.com/apache/jmeter/issues/5961)Deprecate TestElement.threadName as it is not related to TestElement ## Bug fixes #### HTTP Samplers and Test Script Recorder - [PR#5901](https://github.com/apache/jmeter/pull/5901)Fix NumberFormatException when counter is empty or not a digit on Proxy Settings panel - [PR#5987](https://github.com/apache/jmeter/pull/5987)[Issue#4546](https://github.com/apache/jmeter/issues/4546)Encode unicode characters in filenames when sending files in HTTP Sampler #### Other Samplers - [PR#5736](https://github.com/apache/jmeter/pull/5736)[Issue#5733](https://github.com/apache/jmeter/issues/5733)Allow `SampleResult#setEndTime` be set in `JSR223Sampler` #### Listeners - [Issue#5740](https://github.com/apache/jmeter/issues/5740)[PR#5741](https://github.com/apache/jmeter/pull/5741)Fix Aggregated Graph component to cope with empty names of samplers - [Issue#5807](https://github.com/apache/jmeter/issues/5807)Fix an `ArrayIndexOutOfBoundsException` on HTTP parameters line on special case when key and value are empty, i.e.: "`k1=v1&=&k2=v2`" - [Issue#5654](https://github.com/apache/jmeter/issues/5654)[PR#5785](https://github.com/apache/jmeter/pull/5785) Fix `InfluxDBRawBackendListenerClient` missing data. Allow InfluxDB to insert multiple entries with the same `timestamp` but with different `threadName`. Contributed by Victor Peralta (vperaltac at github) #### Timers, Assertions, Config, Pre- & Post-Processors - [PR#5717](https://github.com/apache/jmeter/pull/5717)Add jsonpath string to JSON Path Assertion error message so the error is easier to understand - [PR#723](https://github.com/apache/jmeter/pull/723)Use correct number format on JSON Path Assertion. Contributed by andreaslind01 (andreaslind01 at gmail.com) #### Report / Dashboard - [Bug 66140](https://bz.apache.org/bugzilla/show_bug.cgi?id=66140)Guess the delimiter of the CSV source, when configured one seems wrong. This is in line with the behaviour of CSVSaveService. #### Documentation - [Issue#5694](https://github.com/apache/jmeter/issues/5694)Document changed formatter for [__time()](/user-manual/functions/#__time__). A warning will be logged, if the code `u` is found in the format string, as the meaning for that code has changed from _day-of-week_ to _year_. #### General - [Bug 66157](https://bz.apache.org/bugzilla/show_bug.cgi?id=66157)[PR#719](https://github.com/apache/jmeter/pull/719)Correct theme for darklaf on rsyntaxtextarea - [Issue#5872](https://github.com/apache/jmeter/issues/5872)[PR#5874](https://github.com/apache/jmeter/pull/5874)Trim name in Argument objects. - [PR#693](https://github.com/apache/jmeter/pull/693)Avoid wrong results when `Object.hashCode()` happen to collide. Use `IdentityHashMap` instead of `HashMap` when key is `TestElement` - Refresh UI when dragging JMeter window from one monitor to another, so rich syntax text areas are properly editable after window movement - [PR#5984](https://github.com/apache/jmeter/pull/5984)`AbstractTestElement#clone` might produce non-identical clones if element constructor adds a non-default property value ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Alex Schwartz, [@alexsch01](https://github.com/alexsch01) - Andreas Lind, [@andreaslind01](https://github.com/andreaslind01) - Arnout Engelen, [@raboof](https://github.com/raboof) - Clay Johnson, [@clayburn](https://github.com/clayburn) - David Getzlaff, [@dgetzlaf](https://github.com/dgetzlaf) - Kai Lehmann, [@lehmannk](https://github.com/lehmannk) - kaola89, [@kaola89](https://github.com/kaola89) - Matt Tansley, [@matthewt-assurity](https://github.com/matthewt-assurity) - Mohamed Ibrahim, [@rollno748](https://github.com/rollno748) - Ori Marko, [@orimarko](https://github.com/orimarko) - PJ Fanning, [@pjfanning](https://github.com/pjfanning) - Sandra Thieme, [@sandra-thieme](https://github.com/sandra-thieme) - Stefan Seide, [@sseide](https://github.com/sseide) - Victor Peralta, [@vperaltac](https://github.com/vperaltac) - Vincent DABURON, [@vdaburon](https://github.com/vdaburon) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - [Issue#6008](https://github.com/apache/jmeter/issues/6008) ThreadGroups are running endlessly in non-gui mode (fixed in 5.6.1, see [PR#6011](https://github.com/apache/jmeter/pull/6011)) - [Issue#6043](https://github.com/apache/jmeter/issues/6043) `Min` is always `0` in `Summary Report` (fixed in 5.6.3) - [PR#5987](https://github.com/apache/jmeter/pull/5987)HTTP sampler sends filenames with percent-encoded UTF-8, however it is not aligned with the browsers. The workaround is to refrain non-ASCII filenames - [Issue#6004](https://github.com/apache/jmeter/issues/6004)Java Request sampler cannot be enabled again after disabling in UI (fixed in 5.6.1, [PR#6012](https://github.com/apache/jmeter/pull/6012)) - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.14.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-engine-1.7.14.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 (or later) and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.3/nashorn-core-15.3.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.5/asm-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.5/asm-util-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar popd export JVM_ARGS="--module-path $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.5 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy JMeter now supports Java 17 JMeter 5.5 ships with log4j2 2.17.2 ### Open Model Thread Group New component: `[Open Model Thread Group](/./usermanual/component-reference/#Open_Model_Thread_Group)` allows creating load profiles with variable load. For example, if you need to gradually increase load from `0/sec` to `10/sec` during `minute` you could previously use `Thread Group + Timer` combinations. However, then you need to compute the expected number of threads, ensure they are created only when needed, and so on. With `Open Model Thread Group` you can configure the same load profile as `rate(0/sec) random_arrivals(1 minute) rate(10/sec)`. The thread group would spawn threads as needed to drive the configured load. The load profile can use properties, so you can launch the same script with slightly different load levels, however, the profile can't be updated while the test is running. The new thread group is experimental in JMeter 5.5, so please feel free to submit your feedback. ![Open Model Thread Group sample](/images/screenshots/open_model_thread_group.png) _Open Model Thread Group sample_ ### Preparing the deprecation of Oro Regex usage Another experimental feature in JMeter 5.5 is the ability to replace the Oro based Regex implementation by the built-in Java based one. To choose the Java based one, set the JMeter property `jmeter.regex.engine` to the value `java`. ### Core improvements Kotlin language is now used in some core classes and tests (e.g. Open Model Thread Group). JMeter is compiled with `apiTarget=1.5`, and it ships with `kotlin-stdlib` 1.6. [lets-plot-kotlin](https://github.com/JetBrains/lets-plot-kotlin) charting library is added, so it will be easier to refine and create new charts in UI in the future. ## Improvements #### Thread Groups - New component: `[Open Model Thread Group](/./usermanual/component-reference/#Open_Model_Thread_Group)` #### HTTP Samplers and Test Script Recorder - [Bug 65027](https://bz.apache.org/bugzilla/show_bug.cgi?id=65027)Detect mime-type for files automatically when adding files to HTTP Sampler - [Bug 65020](https://bz.apache.org/bugzilla/show_bug.cgi?id=65020)HTTP Sampler/Files upload tab - add missing buttons - [PR#650](https://github.com/apache/jmeter/pull/650)HTTP Sampler timestamp fix when exception is caught. Contributed by Konstantin Kalinin (konstantin at kkalinin.pro) - [Bug 65328](https://bz.apache.org/bugzilla/show_bug.cgi?id=65328)[PR#666](https://github.com/apache/jmeter/pull/666)HTTP 308 Permanent Redirect is not supported. Contributed by Baptiste Gaillard (baptiste.gaillard at gmail.com) #### Other samplers - [Bug 65149](https://bz.apache.org/bugzilla/show_bug.cgi?id=65149)[PR#644](https://github.com/apache/jmeter/pull/644)Encode the personal part of email addresses in SMTP Sampler - [PR#638](https://github.com/apache/jmeter/pull/638)Various additions to the Bolt Sampler. Added `transaction timeout`, `database` option required for Neo4j 4.x (with multi-database support) and `access mode` option, that allows running against a Neo4j Enterprise Causal Cluster. Contributed by David Pecollet (david.pecollet at gmail.com) #### Controllers - [PR#665](https://github.com/apache/jmeter/pull/665)Increase visible lines of code in `IfController` and `WhileController`. Based on an idea by David Getzlaff (david.getzlaff at t-systems.com>). #### Listeners - [Bug 64988](https://bz.apache.org/bugzilla/show_bug.cgi?id=64988)Sort properties and variables in a human expected order for DebugPostProcessor and DebugSampler - [Bug 63061](https://bz.apache.org/bugzilla/show_bug.cgi?id=63061)Sort View Results in Table in a human expected order - [PR#706](https://github.com/apache/jmeter/pull/706)Try to keep UI responsive when displaying large text results. Can be configured with the new property `view.results.tree.simple_view_limit` #### Timers, Assertions, Config, Pre- & Post-Processors - [PR#638](https://github.com/apache/jmeter/pull/638)Bolt Connection Configuration: added `ConnectionPoolMaxSize` parameter. Contributed by David Pecollet (david.pecollet at gmail.com) - [Bug 65515](https://bz.apache.org/bugzilla/show_bug.cgi?id=65515)Allow pooling of Prepared Statements in JDBC - [Bug 65299](https://bz.apache.org/bugzilla/show_bug.cgi?id=65299)JSONPathAssertion attributes are out of order/Compare JSON objects and not their string representations. #### Report / Dashboard - [Bug 65353](https://bz.apache.org/bugzilla/show_bug.cgi?id=65353)Make the estimator used for calculating percentiles on the dashboard configurable #### General - [Bug 61805](https://bz.apache.org/bugzilla/show_bug.cgi?id=61805)[PR#663](https://github.com/apache/jmeter/pull/663)Add simple HTTP request template. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 65611](https://bz.apache.org/bugzilla/show_bug.cgi?id=65611)[PR#673](https://github.com/apache/jmeter/pull/673)Add support for IPv6 addresses when specifying a remote worker node. Based on a patch by Peter Wong (peter.wong at csexperts.com) - Reduce memory consumption by the logging panel (disable undo events for it) - [Bug 63620](https://bz.apache.org/bugzilla/show_bug.cgi?id=63620)[PR#694](https://github.com/apache/jmeter/pull/694)Fix GUI freeze when viewing response body with long line breaks - [PR#699](https://github.com/apache/jmeter/pull/699)Add documentation for Graphite Backend Listener. Contributed by Ji Hun (jihunkimkw at gmail.com) - [Bug 57672](https://bz.apache.org/bugzilla/show_bug.cgi?id=57672)[PR#700](https://github.com/apache/jmeter/pull/700)Add a switch (`jmeter.regex.engine`) to replace Oro Regex implementation by the built-in Java one. ## Non-functional changes - Added Kotlin 1.6.21 for JMeter engine implementation (apiVersion=1.5). The set of JSR 223 languages is intact. - [Bug 65128](https://bz.apache.org/bugzilla/show_bug.cgi?id=65128)[PR#643](https://github.com/apache/jmeter/pull/643)Add missing documentation about `Same user on each iteration` for Thread Groups. Contributed by njkuzas. - [PR#648](https://github.com/apache/jmeter/pull/648)Updated xmlgraphics-commons to 2.6 (from 2.3). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [PR#655](https://github.com/apache/jmeter/pull/655)[PR#667](https://github.com/apache/jmeter/pull/667)[PR#675](https://github.com/apache/jmeter/pull/675)[PR#698](https://github.com/apache/jmeter/pull/698)Updated x-stream to 1.4.19 (from 1.4.15). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [PR#656](https://github.com/apache/jmeter/pull/656)[PR#668](https://github.com/apache/jmeter/pull/668)Updated json-smart to 2.4.8 (from 2.3), accessors-smart to 2.4.8 (from 1.2) and asm 9.3 (from 9.0). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [Bug 64831](https://bz.apache.org/bugzilla/show_bug.cgi?id=64831)Log truststore entries in debug level for logger `org.apache.jmeter.util.keystore.JmeterKeyStore` - [Bug 65232](https://bz.apache.org/bugzilla/show_bug.cgi?id=65232)Hide splash screen when an error is displayed because the test plan could not be parsed. - Updated Groovy to 3.0.11 (from 3.0.7). - Updated Darklaf to 2.7.3 (from 2.5.4). - Updated Apache ActiveMQ to 15.6.4 (from 15.6.0). - Updated Asm to 9.2 (from 9.1). - Updated Bouncycastle to 1.70 (from 1.67). - Updated Caffeine to 2.9.3 (from 2.8.8). - Updated Apache commons-dbcp2 to 2.9.0 (from 2.8.0). - Updated Apache commons-io to 2.11.0 (from 2.8.0). - Updated Apache commons-lang3 to 3.12.0 (from 3.11). - Updated Apache commons-net to 3.8.0 (from 3.7.2). - Updated Apache commons-pool2 to 2.11.1 (from 2.9.0). - Updated equalsverifier to 3.10 (from 3.4.2). - Updated Apache Freemarker to 2.3.31 (from 2.3.30). - Updated hsqldb to 2.5.2 (from 2.5.0). - Updated Apache HttpClient to 4.5.13 (from 4.5.12). - Updated Apache HttpCore to 4.4.15 (from 4.4.13). - Updated jacoco to 0.8.7 (from 0.8.5). - Updated json-path to 2.7.0 (from 2.4.0). - Updated jsoup to 1.15.1 (from 1.13.1). - Updated JUnit to 4.13.2 and 5.8.2 (from 4.13.1 and 5.7.0). - Updated Apache log4j2 to 2.17.2 (from 2.13.3). - Updated Miglayout to 5.3 (from 5.2). - Updated Neo4j Java driver to 4.4.6 (from 4.2.0). - Updated Objenesis to 3.2 (from 2.6). - Updated ktlint to 0.40.0 - Updated PH CSS and PH commons to 6.5.4 and 10.1.6 (from 6.2.3 and 9.5.1). - Updated RSyntaxTextArea to 3.2.0 (from 3.1.1). - Updated SLF4J to 1.7.36 (from 1.7.30). - Updated SvgSalamander to 1.1.2.4 (from 1.1.2.1). - [PR#698](https://github.com/apache/jmeter/pull/698)Updated Apache Tika to 1.28.3 (from 1.26). - Updated WireMock-JRE8 to 2.30.0 (from 2.24.1). - Updated com.github.vlsi.vlsi-release-plugins 1.76 (from 1.74). - Updated jackson to 2.13.3 (from 2.10.5) - Updated jmespath to 0.5.1 - Updated Saxon-HE to 11.2 (from 9.9.1-8) - Updated Apache xmlgraphics commons to 2.7 (from 2.6) - [PR#671](https://github.com/apache/jmeter/pull/671)Move example definition of property `jmeter.reportgenerator.statistic_window` to `user.properties`, as it is read from that place. Contributed by Rithvik Patibandla (rithvikp98 at gmail.com) - [Bug 65456](https://bz.apache.org/bugzilla/show_bug.cgi?id=65456)Updated commons-jexl 3 to 3.2.1 (from 3.1). Contributed by Ori Marko (orimarko at gmail.com>) - [PR#654](https://github.com/apache/jmeter/pull/654)Try do give better feedback while loading keystores - [PR#672](https://github.com/apache/jmeter/pull/672)Add more details to documentation for timeShift function. Contributed by Mariusz (mawasak at gmail.com) - Updated Gradle to 7.3 (from 7.2) - [PR#689](https://github.com/apache/jmeter/pull/689)Code clean up in StringFromFile. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#690](https://github.com/apache/jmeter/pull/690)Refactor a few unit tests. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#692>](https://github.com/apache/jmeter/pull/692>)Fix a few deprecation warnings for Gradle. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#697>](https://github.com/apache/jmeter/pull/697>)Junit 5 tests to use asserts from Junit 5 API. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [Bug 65983](https://bz.apache.org/bugzilla/show_bug.cgi?id=65983)[PR#707](https://github.com/apache/jmeter/pull/707)Use current screenshot for save-to-file listener in documentation. Based on patch by NaveenKumar Namachivayam (catch.nkn at gmail.com) - [PR#708](https://github.com/apache/jmeter/pull/708)Make errorprone happier. Based on patch by Wilson Kurniawan (wilson at visenze.com)> - Updated Rhino JavaScript to 1.7.14 (from 1.7.13) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 65310](https://bz.apache.org/bugzilla/show_bug.cgi?id=65310)Don't let users override `multipart/form-data` `content-type` header in HC4 sampler. - [Bug 65363](https://bz.apache.org/bugzilla/show_bug.cgi?id=65363)`NullPointerException` in `HTTPHC4Impl$ManagedCredentialsProvider.getAuthorizationForAuthScope` when `401` response from remote and `httpclient4.auth.preemptive=false` - [Bug 65692](https://bz.apache.org/bugzilla/show_bug.cgi?id=65692)HTTP(s) Test Script Recorder: Enable setting enabled cipher suite and enabled protocols on SSLContext/ Align SSL properties between Java and HC4 implementation - [Bug 65108](https://bz.apache.org/bugzilla/show_bug.cgi?id=65108)Support JMeter variables in [GraphQL HTTP Request](/./usermanual/component-reference/#HTTP_Request) - [Bug 65864](https://bz.apache.org/bugzilla/show_bug.cgi?id=65864)Catch `NullPointerException` from JSoup when recording a test plan #### Other Samplers - [Bug 65152](https://bz.apache.org/bugzilla/show_bug.cgi?id=65152)OS Process Sampler - Cannot `Add from Clipboard` Command parameters - [PR#638](https://github.com/apache/jmeter/pull/638)Bolt Sampler: fixed error displaying results when "Record Query Results" is enabled. Contributed by David Pecollet (david.pecollet at gmail.com) #### Controllers #### Listeners - [Bug 64962](https://bz.apache.org/bugzilla/show_bug.cgi?id=64962)Save CSV sub-results recursively from View Results Tree - [Bug 65784](https://bz.apache.org/bugzilla/show_bug.cgi?id=65784)No Graphs displayed in Aggregate Report/Response Time Graph - [Bug 65884](https://bz.apache.org/bugzilla/show_bug.cgi?id=65884)GUI doesn't display response for multipart request _manually_ encoded #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 65257](https://bz.apache.org/bugzilla/show_bug.cgi?id=65257)JMESPathExtractor writes error log entries if JMESPath filter returns empty result - [Bug 65259](https://bz.apache.org/bugzilla/show_bug.cgi?id=65259)JMESPathExtractor Attribute `Match No.` Required - [Bug 65269](https://bz.apache.org/bugzilla/show_bug.cgi?id=65269)JSON Extractor and JSON JMESPath Extractor ignore sub-samples - [Bug 65352](https://bz.apache.org/bugzilla/show_bug.cgi?id=65352)Warning logged when Boundary Extractor doesn't find any match - [Bug 65681](https://bz.apache.org/bugzilla/show_bug.cgi?id=65681)Use default values for `null` values when extracting with JSONPostProcessor - Allow setters in ConstantThroughputTimer to update the values during run time - [Bug 65782](https://bz.apache.org/bugzilla/show_bug.cgi?id=65782)Use correct message format for MessageFormat in HTMLAssertion - [Bug 65794](https://bz.apache.org/bugzilla/show_bug.cgi?id=65794)JSON Assertion always successful with indefinite paths #### Functions #### I18N #### Report / Dashboard #### Documentation - [PR#658](https://github.com/apache/jmeter/pull/658)Improve javadoc. Contributed by Ori Marko (orimarko at gmail.com) #### General - [Bug 64318](https://bz.apache.org/bugzilla/show_bug.cgi?id=64318)DNS Cache Manager - custom DNS resolver does not use system resolver by default - [PR#641](https://github.com/apache/jmeter/pull/641)[PR#698](https://github.com/apache/jmeter/pull/698)Updated xercesImpl to 2.12.2 (from 2.12.0). Based on patch by Stefan Seide (stefan at trilobyte-se.de). - [PR#645](https://github.com/apache/jmeter/pull/645)Add escaping for new lines in `AbstractInfluxdbMetricsSender`. Contributed by David Getzlaff (david.getzlaff at t-systems.com>) - [Bug 65198](https://bz.apache.org/bugzilla/show_bug.cgi?id=65198)Can't copy generated function from FunctionHelper - [PR#661](https://github.com/apache/jmeter/pull/661)Fix wording in doc. Contributed by BugKing (wangzhen at fit2cloud.com) - [PR#664](https://github.com/apache/jmeter/pull/664)Allow whitespace in path. Contributed by Till Neunast (github.com/tilln) - [Bug 65270](https://bz.apache.org/bugzilla/show_bug.cgi?id=65270)POST `application/x-www-form-urlencoded` cURL code generated from Postman is not imported correctly - Silence warnings of missing font Arial on startup under Linux - [Bug 65300](https://bz.apache.org/bugzilla/show_bug.cgi?id=65300)`IllegalAccessError` when opening file dialog with Java 16 - [Bug 65336](https://bz.apache.org/bugzilla/show_bug.cgi?id=65336)Blank labels when different elements had the same name - [Bug 65522](https://bz.apache.org/bugzilla/show_bug.cgi?id=65522)Restart doesn't work, when parameters contain spaces - [Bug 63914](https://bz.apache.org/bugzilla/show_bug.cgi?id=63914)Simplify `:src:dist:clean` configuration, ensure `/lib/junit/test.jar` is removed on clean - [PR#696](https://github.com/apache/jmeter/pull/696)Keep JSyntaxTextArea text value for use in headless mode. Contributed by Peter Paul Bakker (peter.paul.bakker at stokpop.nl) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Stefan Seide (stefan at trilobyte-se.de) - njzukas (github.com/njzukas) - David Getzlaff (david.getzlaff at t-systems.com>) - Konstantin Kalinin (konstantin at kkalinin.pro) - David Pecollet (david.pecollet at gmail.com) - Ori Marko (orimarko at gmail.com) - BugKing (wangzhen at fit2cloud.com) - Till Neunast (github.com/tilln) - Baptiste Gaillard (baptiste.gaillard at gmail.com) - Rithvik Patibandla (rithvikp98 at gmail.com) - Mariusz (mawasak at gmail.com) - peter.wong@csexperts.com - Woonsan Ko (woonsan.ko at bloomreach.com) - Chromico Rek (atech5122 at gmail.com) - Magnus Spångdal (magnus.spangdal as avanza.se) - Piotr Smietana (piotrsmietana1998 at gmail.com) - Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - Ji Hun (jihunkimkw at gmail.com) - Peter Paul Bakker (peter.paul.bakker at stokpop.nl) - NaveenKumar Namachivayam (catch.nkn at gmail.com) - Wilson Kurniawan (wilson at visenze.com) We also thank bug reporters who helped us improve JMeter. - Nikola Aleksic (nalexic at gmail.com) - Vladimir Rosu (rosuvladimir at gmail.com) Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.14.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-engine-1.7.14.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 (or later) and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.3/nashorn-core-15.3.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.2/asm-commons-9.2.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.2/asm-util-9.2.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.2/asm-analysis-9.2.jar popd export JVM_ARGS="--module-path $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.4.3 Summary This version is a fix release against the vulnerability CVE-2021-45105: Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3) did not protect from uncontrolled recursion from self-referential lookups. This allows an attacker with control over Thread Context Map data to cause a denial of service when a crafted string is interpreted. - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) ## Non-functional changes - Updated Apache log4j2 to 2.17.0 (from 2.16.0). ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.13.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_13_Release/rhino-engine-1.7.13.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.0/nashorn-core-15.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.0/asm-commons-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.0/asm-util-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.0/asm-tree-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.0/asm-analysis-9.0.jar popd export JVM_ARGS="--modulepath $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.4.2 Summary This version is a fix release against the vulnerability CVE-2021-44228: Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and other JNDI related endpoints. - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) ## Non-functional changes - Updated Apache log4j2 to 2.16.0 (from 2.13.3). ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.13.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_13_Release/rhino-engine-1.7.13.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.0/nashorn-core-15.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.0/asm-commons-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.0/asm-util-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.0/asm-tree-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.0/asm-analysis-9.0.jar popd export JVM_ARGS="--modulepath $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.4.1 Summary - [Incompatible changes](#Incompatible changes) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## Incompatible changes - Restart after LAF change has been reinstated, it had been removed in JMeter 5.3 ## Improvements #### General - [Bug 65028](https://bz.apache.org/bugzilla/show_bug.cgi?id=65028)Add documentation for the property `client.rmi.localport` - [Bug 65012](https://bz.apache.org/bugzilla/show_bug.cgi?id=65012)Better handling of displaying long comments in the GUI ## Non-functional changes - Updated SaxonHE to 9.9.1-8 (from 9.9.1-7) - Updated asm to 9.0 (from 7.3.1) - Updated bouncycastle to 1.67 (from 1.66) - Updated caffeine to 2.8.8 (from 2.8.0) - Updated commons-codec to 1.15 (from 1.14) - Updated commons-io to 2.8.0 (from 2.7) - Updated commons-net to 3.7.2 (from 3.7) - Updated jackson to 2.10.5 (from 2.10.3) - Updated junit to 4.13.1 (from 4.13) - Updated ph-commons to 9.5.1 (from 9.4.1) - Updated ph-css to 6.2.3 (from 6.2.1) - Updated groovy to 3.0.7 (from 3.0.5) - Updated xstream to 1.4.15 (from 1.4.14) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64955](https://bz.apache.org/bugzilla/show_bug.cgi?id=64955)Keystore password not reset on reload - [Bug 65002](https://bz.apache.org/bugzilla/show_bug.cgi?id=65002)HTTP(S) Test Script recorder creates an invalid Basic authentication URL. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 65004](https://bz.apache.org/bugzilla/show_bug.cgi?id=65004)HTTP(S) Test Script recorder computes wrong HTTP Request breaking the application. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64543](https://bz.apache.org/bugzilla/show_bug.cgi?id=64543)On MacOSX, Darklaf- IntelliJ Theme throws NPE in javax.swing.ToolTipManager.initiateToolTip - [Bug 65024](https://bz.apache.org/bugzilla/show_bug.cgi?id=65024)Sending mime type with parameter throws IllegalArgumentException - [Bug 65029](https://bz.apache.org/bugzilla/show_bug.cgi?id=65029)Try harder to correctly guess the URL for applets, when download embedded URLs is enabled #### Other Samplers - [Bug 65034](https://bz.apache.org/bugzilla/show_bug.cgi?id=65034)Ignore `SocketTimeoutException` on `BinaryTCPClientImpl`, when no EOM Byte is set. Regression introduced by commit c190641e4f0474a34a366a72364b0a8dd25bfc81 which fixed [Bug 52104](https://bz.apache.org/bugzilla/show_bug.cgi?id=52104). That bug was bout handling the case of waiting for an EOM. #### Listeners - [Bug 64821](https://bz.apache.org/bugzilla/show_bug.cgi?id=64821)When importing XML formatted jtl files, sub samplers will get renamed - [Bug 65052](https://bz.apache.org/bugzilla/show_bug.cgi?id=65052)XPath2 Tester and JSON JMESPath Tester are missing in `view.results.tree.renderers_order` property #### Documentation - [Bug 64960](https://bz.apache.org/bugzilla/show_bug.cgi?id=64960)Change scheduler reference in Thread Group documentation. Contributed by Ori Marko - [Bug 65006](https://bz.apache.org/bugzilla/show_bug.cgi?id=65006)Illustration for completed HTTP Request Defaults element (Figure 4.4) contains misleading info #### General - [Bug 64957](https://bz.apache.org/bugzilla/show_bug.cgi?id=64957)When importing example test plan JMeter displays an NullPointerException - [Bug 64961](https://bz.apache.org/bugzilla/show_bug.cgi?id=64961)Darklaf: On Windows 7, NPE in BasicEditorPaneUI.cleanDisplayProperties with Darklaf Intellij - [Bug 64963](https://bz.apache.org/bugzilla/show_bug.cgi?id=64963)Blank comment tooltip is visible - [Bug 64969](https://bz.apache.org/bugzilla/show_bug.cgi?id=64969)RemoteJMeterEngineImpl#rexit doesn't unexport RemoteJMeterEngineImpl on exit. Contributed by luo_isaiah at qq.com - [Bug 64984](https://bz.apache.org/bugzilla/show_bug.cgi?id=64984)Darklaf LAF: Selecting a Test element does not work under certain screen resolutions on Windows. With the help of Jannis Weis - [Bug 65008](https://bz.apache.org/bugzilla/show_bug.cgi?id=65008)SampleResult.setIgnore() called from PostProcessor is not considered - [Bug 64993](https://bz.apache.org/bugzilla/show_bug.cgi?id=64993)Daklaf LAF: Menu navigation not working with keyboard shortcuts. With the help of Jannis Weis - [Bug 65013](https://bz.apache.org/bugzilla/show_bug.cgi?id=65013)POST multipart/form-data cURL code with quoted arguments is not imported correctly ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Ori Marko (orimarko at gmail.com) - 罗寅卓 (luo_isaiah at qq.com) - [Ubik Load Pack](https://ubikloadpack.com) - [Jannis Weis](https://github.com/weisJ/darklaf) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.13.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_13_Release/rhino-engine-1.7.13.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.0/nashorn-core-15.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.0/asm-commons-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.0/asm-util-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.0/asm-tree-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.0/asm-analysis-9.0.jar popd export JVM_ARGS="--modulepath $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.4 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ### UX improvements [Bug 62179](https://bz.apache.org/bugzilla/show_bug.cgi?id=62179)[Bug 64658](https://bz.apache.org/bugzilla/show_bug.cgi?id=64658)The splash screen is now application-modal rather than system-modal, so it does not block other applications when JMeter is starting up. ## Incompatible changes - Remove LogKit logger functionality from some classes. This was intended to completely remove `LoggingManager` class (it has been deprecated since JMeter 3.2), but as jmeter-plugins depended on it, `LoggingManager` and our `LogKit`-adapter will remain for this version (but is still deprecated). ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 53848](https://bz.apache.org/bugzilla/show_bug.cgi?id=53848)[Bug 63527](https://bz.apache.org/bugzilla/show_bug.cgi?id=63527)Implement a new setting to allow the exclusion of embedded URLs - [Bug 64696](https://bz.apache.org/bugzilla/show_bug.cgi?id=64696)[PR#571](https://github.com/apache/jmeter/pull/571)[PR#595](https://github.com/apache/jmeter/pull/595)Freestyle format for names in (Default)SamplerCreater. Based on a patch by Vincent Daburon (vdaburon at gmail.com) - [Bug 64752](https://bz.apache.org/bugzilla/show_bug.cgi?id=64752)Add GraphQL/HTTP Request Sampler. Contributed by woonsan. #### Other samplers - [Bug 64555](https://bz.apache.org/bugzilla/show_bug.cgi?id=64555)Set JMSType header field through JMSProperties. Contributed by Daniel van den Ouden #### Controllers #### Listeners - [PR#544](https://github.com/apache/jmeter/pull/544)Add BackendListener that sends "raw" results to InfluxDB. Contributed by Graham Russell (graham at ham1.co.uk) #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard - [Bug 64824](https://bz.apache.org/bugzilla/show_bug.cgi?id=64824)Dashboard/HTML Report: Rename `KO` to `FAIL` - [Bug 64936](https://bz.apache.org/bugzilla/show_bug.cgi?id=64936)Increase generate_report_ui.generation_timeout to 5 minutes to handle large performance test #### General - [Bug 64446](https://bz.apache.org/bugzilla/show_bug.cgi?id=64446)Better parse curl commands with backslash at line endings and support `PUT` method with data arguments - [PR#599](https://github.com/apache/jmeter/pull/599)Ensure all buttons added to the toolbar behave/look consistently. Contributed by Jannis Weis - [Bug 64581](https://bz.apache.org/bugzilla/show_bug.cgi?id=64581)Allow `SampleResult#setIgnore` to influence behaviour on Sampler Error - [Bug 64680](https://bz.apache.org/bugzilla/show_bug.cgi?id=64680)Fall back to `JMETER_HOME` on startup to detect JMeter's installation directory - [Bug 64787](https://bz.apache.org/bugzilla/show_bug.cgi?id=64787)[PR#630](https://github.com/apache/jmeter/pull/630)Add Korean translation. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 64776](https://bz.apache.org/bugzilla/show_bug.cgi?id=64776)Add the ability to install additional SecurityProvider. Contributed by Timo (ASF.Software.Timo at Leefers.eu) ## Non-functional changes - Build system upgraded from Gradle to 6.7 (from 6.6) - [PR#594](https://github.com/apache/jmeter/pull/594)Updated neo4j-java-driver to 4.2.0 (from 1.7.5) - [Bug 64454](https://bz.apache.org/bugzilla/show_bug.cgi?id=64454)More precise error message, when no datasource value can be found in JDBC sampler - [Bug 64440](https://bz.apache.org/bugzilla/show_bug.cgi?id=64440)Log exeptions reported via `JMeterUtils#reportToUser` even when in GUI mode - [PR#591](https://github.com/apache/jmeter/pull/591)Remove deprecated sudo flag from travis file. Deng Liming (liming.d.pro at gmail.com) - Updated Darklaf to 2.4.10 (from 2.1.1) - Updated Groovy to 3.0.5 (from 3.0.3) - [PR#596](https://github.com/apache/jmeter/pull/596)Use neutral words in documentation - [Bug 63809](https://bz.apache.org/bugzilla/show_bug.cgi?id=63809)[PR#557](https://github.com/apache/jmeter/pull/557)Updated commons-collections to 4.4 (from 3.2.2) while keeping the jars for the old commons-collections 3.x for compatibility - [PR#598](https://github.com/apache/jmeter/pull/598)Add another option for creating diffs to the building page. Contributed by jmetertea (github.com/jmetertea) - [PR#609](https://github.com/apache/jmeter/pull/609)Make use of newer API for darklaf installation. Jannis Weis - [PR#612](https://github.com/apache/jmeter/pull/612)Correct typos in `README.md`. Based on patches by Pooja Chandak (poojachandak002 at gmail.com) - [PR#613](https://github.com/apache/jmeter/pull/613)Add documentation for Darklaf properties. Jannis Weis - Update SpotBugs to 4.1.2 (from 4.1.1), upgrade spotbugs-gradle-plugin to 4.5.0 (from 2.0.0) - Update org.sonarqube Gradle plugin to 3.0 (from 2.7.1) - Update Apache ActiveMQ to 5.16.0 (from 5.15.11) - Update Bouncycastle to 1.66 (from 1.64) - Update Apache commons-io to 2.7 (from 2.6) - Update Apache commons-lang3 to 3.11 (from 3.10) - Update Apache commons-net to 3.7 (from 3.6) - Update Apache commons-pool2 to 2.9.0 (from 2.8.0) - Update Apache commons-text to 1.9 (from 1.8) - Update equalsverifier to 3.4.2 (from 3.1.13) - Update junit5 to 5.6.2 (from 5.6.0) - Update Apache log4j2 to 2.13.3 (from 2.13.1) - Update rsyntaxtextarea to 3.1.1 (from 3.1.0) - Update JUnit5 to 5.7.0 (from 5.6.2) - Update Rhino to 1.7.13 (from 1.7.12) - Update XStream to 1.4.14 (from 1.4.14.1) - Update Apache commons-dbcp2 to 2.8.0 (from 2.7.0) - [PR#635](https://github.com/apache/jmeter/pull/635)Correct some image ratios in the documentation. Patch provided by Vincent Daburon (vdaburon at gmail.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64479](https://bz.apache.org/bugzilla/show_bug.cgi?id=64479)Regression: HTTP(s) Script Recorder prevents proper shutdown in non-GUI mode - [Bug 64653](https://bz.apache.org/bugzilla/show_bug.cgi?id=64653)Exclude Javascript and JSON from parsing for charsets from forms by proxy #### Other Samplers #### Controllers - [Bug 64795](https://bz.apache.org/bugzilla/show_bug.cgi?id=64795)Generate summary report may not output a summary line in the configured interval (`summariser.interval`): Clarify documentation #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64638](https://bz.apache.org/bugzilla/show_bug.cgi?id=64638)JSON JMESPath Assertion / JSON Assertion: Opening GUI shows a horizontal scrollbar that keeps sliding - [Bug 64915](https://bz.apache.org/bugzilla/show_bug.cgi?id=64915)JMeter Cache Manager misbehaving when "Use Cache-Control/Expires header" is checked #### Functions #### I18N #### Report / Dashboard - [Bug 64547](https://bz.apache.org/bugzilla/show_bug.cgi?id=64547)Report/Dashboard: Ensure graphs Response codes per second is not broken by empty response code in SampleResult. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64617](https://bz.apache.org/bugzilla/show_bug.cgi?id=64617)HTML report: In graph Response Time Percentiles Over Time 90,95,99th percentile correspond in reality to 0.90, 0.95 and 0.99 percentiles - [Bug 64553](https://bz.apache.org/bugzilla/show_bug.cgi?id=64553)When using Transaction Controller, send Bytes and Received Bytes are displayed as 0 in the influxdb(BackendListener) - [Bug 64624](https://bz.apache.org/bugzilla/show_bug.cgi?id=64624)Use less aggressive escaping for JSON Strings in reports error messages #### Documentation - [PR#571](https://github.com/apache/jmeter/pull/571)Correct documented name of generated CA when using proxy script recorder. Part of a bigger PR. Vincent Daburon (vdaburon at gmail.com) - Change documentation of the special header functionality of the mirror server to reflect the implementation. #### General - [Bug 64448](https://bz.apache.org/bugzilla/show_bug.cgi?id=64448)User Defined Variable Duplication in Right Click Context Menu - [Bug 64499](https://bz.apache.org/bugzilla/show_bug.cgi?id=64499)Exiting JMeter when `jmeterengine.stopfail.system.exit=true` takes too much time if threads are not stopped - [Bug 64510](https://bz.apache.org/bugzilla/show_bug.cgi?id=64510)Darklaf- IntelliJ Theme throws NPE in DarkTreeUI on MacOS - [Bug 64594](https://bz.apache.org/bugzilla/show_bug.cgi?id=64594)Unable to enter variable values instead of numeric values in components using PowerTableModel (Impacts 3rd party plugins like Throughput Shaping Timer) - [Bug 64475](https://bz.apache.org/bugzilla/show_bug.cgi?id=64475)Menu Generate HTML Report: When report generation fails due to timeout, error message is not explicit. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64627](https://bz.apache.org/bugzilla/show_bug.cgi?id=64627)Programmatic manipulation of the control flow via API methods of JMeterContext is not working as it used to before 5.0. Contributed by Till Neunast - [Bug 64647](https://bz.apache.org/bugzilla/show_bug.cgi?id=64647)groovy-dateutil is missing in distribution - [Bug 64640](https://bz.apache.org/bugzilla/show_bug.cgi?id=64640)Darklaf: NPE at com.github.weisj.darklaf.ui.DarkPopupFactory.getPopupType(DarkPopupFactory.java:96) - [Bug 64641](https://bz.apache.org/bugzilla/show_bug.cgi?id=64641)Darklaf: NPE at com.github.weisj.darklaf.ui.tree.DarkTreeUI.isChildOfSelectionPath(DarkTreeUI.java:603) ~[darklaf-core-2.4.2-SNAPSHOT.jar:2.4.2-SNAPSHOT] - [Bug 64453](https://bz.apache.org/bugzilla/show_bug.cgi?id=64453)Darklaf: Save Test Plan as New Folder failure - [Bug 64625](https://bz.apache.org/bugzilla/show_bug.cgi?id=64625)Darklaf: trying to select a folder in Browse leads to an error popup and stacktrace - [Bug 64711](https://bz.apache.org/bugzilla/show_bug.cgi?id=64711)Textarea Colors are not good in dark modes. Contributed by Jannis Weis - [Bug 64935](https://bz.apache.org/bugzilla/show_bug.cgi?id=64935)A broken plugin class should not prevent JMeter from starting ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Michael Weidmann (https://github.com/michaelweidmann) - Deng Liming (liming.d.pro at gmail.com) - jmetertea (https://github.com/jmetertea) - [Ubik Load Pack](https://ubikloadpack.com) - [Jannis Weis](https://github.com/weisJ/darklaf) - [Daniel van den Ouden](https://github.com/topicus-pw-dvdouden) - Till Neunast (https://github.com/tilln) - Pooja Chandak (poojachandak002 at gmail.com) - Vincent Daburon (vdaburon at gmail.com) - Woonsan Ko (woonsan at apache.org) - Timo (ASF.Software.Timo at Leefers.eu) - Graham Russell (graham at ham1.co.uk) We also thank bug reporters who helped us improve JMeter. - Hiroyoshi Mitsumori (mitsumori at mis.dev) Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` - With Java 15 the JavaScript implementation [Nashorn has been removed](https://openjdk.java.net/jeps/372). To add back a JSR-223 compatible JavaScript engine you have two options: **Use Mozilla Rhino** : Copy [rhino-engine-1.7.13.jar](https://github.com/mozilla/rhino/releases/download/Rhino1_7_13_Release/rhino-engine-1.7.13.jar) into `$JMETER_HOME/lib/ext`. **Use OpenJDK Nashorn** : The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 and its dependencies and set the module path is outlined below: ``` mkdir lib/modules pushd lib/modules wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.0/nashorn-core-15.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.0/asm-commons-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.0/asm-util-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.0/asm-tree-9.0.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.0/asm-analysis-9.0.jar popd export JVM_ARGS="--modulepath $PWD/lib/modules" ./bin/jmeter ``` ## Version 5.3 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ### UX improvements Added [Darklaf](https://github.com/weisJ/darklaf) look and feel that improves several components. Tree indentation level is easier to follow: ![JMeter tree with Darklaf Darcula theme](/images/screenshots/changes/5.3/tree_theme_darcula.png) _JMeter tree with Darklaf Darcula theme_ ![JMeter tree with Darklaf IntelliJ theme](/images/screenshots/changes/5.3/tree_theme_intellij.png) _JMeter tree with Darklaf IntelliJ theme_ New look and feel themes. Light: IntellJ, Solarized Light, HighContrast Light. Dark: OneDark, Solarized Dark, HighContrast Dark. When an element in tree is disabled, all its descendants are shown in gray. For instance, `While Contoller` is disabled in the following tree, so its children are gray. It is purely a UI change, and the behavior is not altered. ![While controller is disabled, so its children are gray](/images/screenshots/changes/5.3/disabled_subtree.png) _While controller is disabled, so its children are gray_ Tree context menu is shown even in case the node selection is changed. Previously the popup did disappear and it was required to select a node first and only then launch popup. Look and feel can now be updated without a restart Use `CTRL + ALT + wheel` for zooming fonts. Previous shortcut was `CTRL + SHIFT + wheel`, however, it conflicted with horizontal scrolling. In-app zoom is more consistent (e.g. sometimes not all the labels or even panels were scaled). For instance: log viewer, JSR223 code editor were not previously scaled with zoom-in/out feature Tree context menu is shown for the full row, not for the label only Undo and redo support for editable fields. Keystrokes are `CTRL + Z` / `CTRL + SHIFT + Z`, or `CMD + Z`/ `CMD + SHIFT + Z` depending on the operating system. Undo is implemented on a field level basis (each fields has its own history), and the history is invalidated when tree selection changes. Mark the currently selected language in the options menu. Mark the currently selected log level in the options menu. Rework of many Test Element UI (JUnit Request, ForEach Controller, If Controller, Throughput Controller, WhileController, Counter Config, XPath2 Extractor, Function Helper Dialog, Search popup, JMS Elements) ## Incompatible changes - Default value of `httpclient4.time_to_live` has been modified from `2000` to `60000`, this means HTTP connections will live longer than before. This has impact on connection creation and SSL handshake, see [Bug 64289](https://bz.apache.org/bugzilla/show_bug.cgi?id=64289) - The update to Groovy 3 ([PR#590](https://github.com/apache/jmeter/pull/590)) might break some old Groovy code of your tests. Have a look at [the update notes for Groovy 3](https://groovy-lang.org/releasenotes/groovy-3.0.html) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 64160](https://bz.apache.org/bugzilla/show_bug.cgi?id=64160)Test HTTP/S Test Script Recorder: Name transaction controller/ simple controller using prefix without "`-XXXX`" suffix - [Bug 64289](https://bz.apache.org/bugzilla/show_bug.cgi?id=64289)Make `httpclient4.time_to_live` to `60000` to be closer to typical browser behavior #### Other samplers - [Bug 64288](https://bz.apache.org/bugzilla/show_bug.cgi?id=64288)JUnit Request: Improve UX - [Bug 64407](https://bz.apache.org/bugzilla/show_bug.cgi?id=64407)Improve JMS Publisher UX. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64408](https://bz.apache.org/bugzilla/show_bug.cgi?id=64408)Improve JMS Subscriber UX. Contributed by Ubik Load Pack (https://ubikloadpack.com) #### Controllers - [Bug 64277](https://bz.apache.org/bugzilla/show_bug.cgi?id=64277)ForEach Controller: Improve UX - [Bug 64280](https://bz.apache.org/bugzilla/show_bug.cgi?id=64280)If Controller: Improve UX - [Bug 64282](https://bz.apache.org/bugzilla/show_bug.cgi?id=64282)Throughput Controller: Improve UX - [Bug 64287](https://bz.apache.org/bugzilla/show_bug.cgi?id=64287)WhileController: Improve UX #### Listeners - [Bug 64150](https://bz.apache.org/bugzilla/show_bug.cgi?id=64150)View Results Tree: Allow editing of response data in testers - [Bug 63822](https://bz.apache.org/bugzilla/show_bug.cgi?id=63822)View Results Tree: Keep position of split pane while switching renderer mode #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64091](https://bz.apache.org/bugzilla/show_bug.cgi?id=64091)Precise Throughput Timer schedule generation is improved significantly (e.g. 2 seconds for 10M samples) - [Bug 64281](https://bz.apache.org/bugzilla/show_bug.cgi?id=64281)Counter Config: Improve UX - [Bug 64283](https://bz.apache.org/bugzilla/show_bug.cgi?id=64283)XPath2 Extractor: Improve UX #### Functions - [Bug 64070](https://bz.apache.org/bugzilla/show_bug.cgi?id=64070)`_timeshift` function does not work with offset formatters - [Bug 64275](https://bz.apache.org/bugzilla/show_bug.cgi?id=64275)Function Helper Dialog: Improve UX #### I18N - [Bug 64102](https://bz.apache.org/bugzilla/show_bug.cgi?id=64102)Add Chinese translation for Tools menu. Contributed by Liu XP (liu_xp2003 at sina.com) #### Report / Dashboard - [Bug 64380](https://bz.apache.org/bugzilla/show_bug.cgi?id=64380)Add a '`Median`' field to the dashboard and make the response time percentile fields support floating-point numbers. Contributed by Keith Mo(https://github.com/keithmork) - [Bug 64378](https://bz.apache.org/bugzilla/show_bug.cgi?id=64378)HTML report generation should not fail if a plugin has registered a graph and is not more present in classpath, issue a warning instead #### General - [Bug 63458](https://bz.apache.org/bugzilla/show_bug.cgi?id=63458)[PR#551](https://github.com/apache/jmeter/pull/551)Add new template "Functional Testing Test Plan [01]". Contributed by Sebastian Boga (sebastian.boga at endava.com) - [Bug 64119](https://bz.apache.org/bugzilla/show_bug.cgi?id=64119)Use first renderer from `view.results.tree.renderers_order` property as default in View Results Tree - [Bug 64148](https://bz.apache.org/bugzilla/show_bug.cgi?id=64148)Use gray icons for disabled elements in the tree, display subtree as gray - [Bug 64198](https://bz.apache.org/bugzilla/show_bug.cgi?id=64198)Allow spaces in `\${...}` expressions around functions. - [Bug 64276](https://bz.apache.org/bugzilla/show_bug.cgi?id=64276)Search popup: Improve UX - [PR#573](https://github.com/apache/jmeter/pull/573)Improve the startup time: skip test plan UI initialization - [PR#585](https://github.com/apache/jmeter/pull/585)Added JEXL3 as a syntax alias for JSyntaxTextArea. Contributed by drivera-armedia (https://github.com/drivera-armedia) - [PR#590](https://github.com/apache/jmeter/pull/590)Update Groovy to 3.0.3. ## Non-functional changes - Build system upgraded from Gradle to 6.3 (from 6.1), Java 14 can be used now for the build - [Bug 63963](https://bz.apache.org/bugzilla/show_bug.cgi?id=63963)[PR#546](https://github.com/apache/jmeter/pull/546)Updated jackson to 2.10.3 (from 2.9.10) - [Bug 64120](https://bz.apache.org/bugzilla/show_bug.cgi?id=64120)Updated jsoup to 1.13.1 (from 1.12.1) - [Bug 63809](https://bz.apache.org/bugzilla/show_bug.cgi?id=63809)Updated commons-dbcp2 to 2.7.0 (from 2.5.0) - Updated Apache ActiveMQ to 5.15.11 (from 5.15.8) - Updated bouncycastle to 1.64 (from 1.60) - Updated asm to 7.3.1 (from 7.1) - Updated Apache commons-codec to 1.14 (from 1.13) - Updated Apache commons-pool to 2.8.0 (from 2.7.0) - Updated equalsverifier to 3.1.9 (from 3.1.12) - Updated Apache Groovy to 2.4.18 (from 2.4.16) - Updated hsqldb to 2.5.0 (from 2.4.1) - Updated hamcrest to 2.2 (from 2.1) - Updated Apache httpclient and httpmime to 4.5.12 (from 4.5.10) - Updated Apache httpcore and httpcore-nio to 4.4.13 (from 4.4.12) - Updated Apache Tika to 1.24.1 (from 1.22) - Updated jmespath to 0.5.0 (from 0.3.0) - Updated Apache log4j to 2.13.1 (from 2.12.1) - Updated junit4 to 4.13 (from 4.12) - Updated junit5 to 5.6.0 (from 5.5.1) - Updated slf4j to 1.7.30 (from 1.7.28) - Updated ph-commons to 9.4.1 (from 9.3.7) - Updated ph-css to 6.2.2 (from 6.2.0) - Updated rsyntaxtextarea to 3.1.0 (from 3.0.4) - Updated rhino to 1.7.12 (from 1.7.11) - Updated SaxonHE to 9.9.1-7 (from 9.9.1-5) - Updated cglib to 3.2.12 (from 3.2.9) - Updated commons-lang3 to 3.10 (from 3.9) - Updated freemarker to 2.3.30 (from 2.3.29) - Updated hamcrest-date to 2.0.7 (from 2.0.4) - Updated equalsverifier to 3.1.13 (from 3.1.12) - Updated xstream to 1.4.11.1 (from 1.4.11) - [PR#559](https://github.com/apache/jmeter/pull/559)Add a note to the source of TrustAllSSLSocketFactory, that it is not secure to trust everyone. Based on a PR from YYTVicky (yytvicky at github) - [PR#588](https://github.com/apache/jmeter/pull/588)Add documentation on usage of InfluxDB v2 for real-time results. Based on PR from Jakub Bednář (jakub.bednar at gmail.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64400](https://bz.apache.org/bugzilla/show_bug.cgi?id=64400)Make sorting recorded samples into transaction controllers more predictable - [Bug 64267](https://bz.apache.org/bugzilla/show_bug.cgi?id=64267)When preemptive auth is disabled HTTP Sampler does not automatically respond to Basic Auth challenge #### Other Samplers #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64091](https://bz.apache.org/bugzilla/show_bug.cgi?id=64091)Precise Throughput Timer might produce less samples when low test duration is used - [Bug 64142](https://bz.apache.org/bugzilla/show_bug.cgi?id=64142)Presence of DebugPostProcessor in Test plan breaks ActiveThread Over time in report due to missing information - [Bug 64196](https://bz.apache.org/bugzilla/show_bug.cgi?id=64196)Recurse into sub samplers more deeply when checking assertions - [Bug 64196](https://bz.apache.org/bugzilla/show_bug.cgi?id=64196)Recurse into sampleResults for `AbstractScopedTestElement#getSampleList` - [Bug 64381](https://bz.apache.org/bugzilla/show_bug.cgi?id=64381)PreciseThroughputTimer: On termination, log message contains negative value #### Functions #### I18N #### Report / Dashboard - [Bug 64059](https://bz.apache.org/bugzilla/show_bug.cgi?id=64059)Response Time Percentiles Over Time, unable to change the percentiles #### Documentation - [PR#547](https://github.com/apache/jmeter/pull/547)Correct Log level documentation. Contributed by jmetertea - [PR#548](https://github.com/apache/jmeter/pull/548)Correct typos in documentation. Contributed by jmetertea - [Bug 64022](https://bz.apache.org/bugzilla/show_bug.cgi?id=64022)Correct Chinese translation for "Ignore Sub-Controller blocks". Provided by yangxiaofei77 (yangxiaofei77 at gmail.com) - [PR#552](https://github.com/apache/jmeter/pull/552)Fix `client.rmi.localport` port allocation description. Contributed by anant-93 - [PR#543](https://github.com/apache/jmeter/pull/543)Clarify documentation of `__StringToFile` function regarding default value of `Append to file?` parameter. Contributed by Ori Marko - [Bug 64302](https://bz.apache.org/bugzilla/show_bug.cgi?id=64302)Correct links to JMeter API in printable docs and BeanShell best practices and to JavaFX implementation website in all docs. Reported by 2477441814 (2477441814 at qq.com) #### General - [Bug 63945](https://bz.apache.org/bugzilla/show_bug.cgi?id=63945)NPE when opening a file after file system change - [Bug 64034](https://bz.apache.org/bugzilla/show_bug.cgi?id=64034)Shell scripts fail if space in `JAVA_HOME` path. Contributed by ray7219 (ray7219 at hotmail.com) - [Bug 63856](https://bz.apache.org/bugzilla/show_bug.cgi?id=63856)Set `connectTime` on parent samples when using a transaction controller - [Bug 64227](https://bz.apache.org/bugzilla/show_bug.cgi?id=64227)Error when loading Templates on Windows - TestPlan UI: skip adding the entry to the classpath if the user clicks cancel ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Jannis Weis](https://github.com/weisJ/darklaf) - Stefan Seide (stefan at trilobyte-se.de) - jmetertea - ray7219 - Sebastian Boga (sebastian.boga at endava.com) - Liu XP (liu_xp2003 at sina.com) - anant-93 (https://github.com/anant-93) - Ori Marko (orimarko at gmail.com) - Keith Mo(https://github.com/keithmork) - drivera-armedia (https://github.com/drivera-armedia) - [Ubik Load Pack](https://ubikloadpack.com) - Jakub Bednář (jakub.bednar at gmail.com) We also thank bug reporters who helped us improve JMeter. - Michael McDermott (mcdermott.michaelj at gmail.com) - yangxiaofei77 (yangxiaofei77 at gmail.com) - Markus Wolf (wolfm at t-systems.com) - Pierre Astruc (pierre.astruc at evertest.com) - YYTVicky (yytvicky at github) - 2477441814 at qq.com Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` ## Version 5.2.1 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy This release is a minor bugfix release. Please see the [Changes history page](/user-manual/changes-history/) to view the last release notes of version 5.2. ## Incompatible changes ## Improvements #### HTTP Samplers and Test Script Recorder #### Other samplers - [Bug 63926](https://bz.apache.org/bugzilla/show_bug.cgi?id=63926)JDBC Connection Configuration: Add ability to set connection properties #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard #### General ## Non-functional changes ## Bug fixes #### HTTP Samplers and Test Script Recorder #### Other Samplers #### Controllers #### Listeners - [Bug 63906](https://bz.apache.org/bugzilla/show_bug.cgi?id=63906)NPE for InfluxDB backend listener during failover testing #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard #### Documentation #### General - [Bug 63910](https://bz.apache.org/bugzilla/show_bug.cgi?id=63910)Broken maven poms in released 5.2 version - [Bug 63911](https://bz.apache.org/bugzilla/show_bug.cgi?id=63911)ApacheJMeter_config.jar content has changed (bin moved to run and missing files) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Vincent Lee](https://github.com/vincentclee) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` ## Version 5.2 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy This release is a major release. Please see the [Changes history page](/user-manual/changes-history/) to view the last release notes of version 5.1.1. ## Incompatible changes - HTTP(S) Test Script Recorder now appends number at end of names, while previously it added it at beginning. See [Bug 63450](https://bz.apache.org/bugzilla/show_bug.cgi?id=63450) - When using XPath Assertion with an XPath expression returning a boolean, `True if nothing matches` had no effect and always returned true, see [Bug 63455](https://bz.apache.org/bugzilla/show_bug.cgi?id=63455) - XML parsing now refuses unsecure XML, this has impacts on the following features: - XMLAssertion - XMLSchemAssertion - XPath function - XPath 1 & 2 Extractors - XPath 1 & 2 Assertions ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 63450](https://bz.apache.org/bugzilla/show_bug.cgi?id=63450)HTTP(S) Test Script Recorder: Put number at end instead of beginning - [Bug 63790](https://bz.apache.org/bugzilla/show_bug.cgi?id=63790)Embedded Resources download: Optimize CSS parsing by removing source location #### Other samplers - [Bug 63406](https://bz.apache.org/bugzilla/show_bug.cgi?id=63406)JDBC connection configuration: new option for pre-initialize to initialize the connection pool. Contributed by Franz Schwab (franz.schwab at exasol.com) - [Bug 63561](https://bz.apache.org/bugzilla/show_bug.cgi?id=63561)JDBC Request: Allow to only fetch a certain number of rows. Contributed by Franz Schwab (franz.schwab at exasol.com) - [Bug 63801](https://bz.apache.org/bugzilla/show_bug.cgi?id=63801)Add Bolt protocol support for Neo4j database. Contributed by GraphAware (www.graphaware.com) #### Controllers - [Bug 63565](https://bz.apache.org/bugzilla/show_bug.cgi?id=63565)If Controller: GC issue with JMeter during the endurance run when using with "Interpret Condition as Variable Expression?" unchecked => Improve documentation #### Listeners - [Bug 63720](https://bz.apache.org/bugzilla/show_bug.cgi?id=63720)BackendListener: InfluxDBBackendListenerClient Add support for InfluxDB 2. Contributed by Jakub Bednář (https://github.com/bednar) - [Bug 63770](https://bz.apache.org/bugzilla/show_bug.cgi?id=63770)View Results Tree: Add JMESPath Tester. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62863](https://bz.apache.org/bugzilla/show_bug.cgi?id=62863)Enable PKCS11 keystores for usage with KeyStore Manager. Based on patch by Clifford Harms (clifford.harms at gmail.com). - [PR#457](https://github.com/apache/jmeter/pull/457)Slight performance improvement in PoissonRandomTimer by using ThreadLocalRandom. Based on a patch by Xia Li. - [Bug 62787](https://bz.apache.org/bugzilla/show_bug.cgi?id=62787)New `XPath2 Assertion` supporting XPath2 with better performances than `XPath Assertion`. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63643](https://bz.apache.org/bugzilla/show_bug.cgi?id=63643)Skip BOM on files opened through `FileServer` and use the BOM to detect the character encoding, if none is given explicitly. Reported by Havlicek Honza (havlicek.honza at gmail.com) - [Bug 63727](https://bz.apache.org/bugzilla/show_bug.cgi?id=63727)New `JMESPath Extractor` element to ease extraction from JSON using [JMESPath](http://jmespath.org) technology. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63763](https://bz.apache.org/bugzilla/show_bug.cgi?id=63763)New `JMESPath Assertion` element to ease assertion on JSON using [JMESPath](http://jmespath.org) technology. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63775](https://bz.apache.org/bugzilla/show_bug.cgi?id=63775)Allow Boundary Extractor to accept empty boundaries #### Functions - [Bug 63219](https://bz.apache.org/bugzilla/show_bug.cgi?id=63219)New function `__StringToFile` to save/append a string into a file. Contributed by Ubik Load Pack (support at ubikloadpack.com) - Use `AtomicInteger` for `__counter` instead of synchronization on our own #### I18N #### Report / Dashboard - [Bug 63471](https://bz.apache.org/bugzilla/show_bug.cgi?id=63471)`StringConverter`s used for report generation should ignore white space around numbers. #### General - [Bug 63396](https://bz.apache.org/bugzilla/show_bug.cgi?id=63396)JSR223 Test Elements: Description of Parameters is misleading, same for Script - [Bug 63480](https://bz.apache.org/bugzilla/show_bug.cgi?id=63480)XPathAssertion and XPathAssertion2: Improve test coverage for input coming from variable. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63452](https://bz.apache.org/bugzilla/show_bug.cgi?id=63452)Tools / Import from cURL: Complete coverage of all command line options that are valid in JMeter use case. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63419](https://bz.apache.org/bugzilla/show_bug.cgi?id=63419)Tools / Import from cURL: Add ability to import a set of cURL commands from a file. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63760](https://bz.apache.org/bugzilla/show_bug.cgi?id=63760)JOrphanUtils: add random alphanumeric password generator - [Bug 63355](https://bz.apache.org/bugzilla/show_bug.cgi?id=63355)View Results Tree: Browser view option is not Available since Java 11, document how to make it available, see [this](/./usermanual/hints-and-tips/#browser_renderer_view_results_tree) - [Bug 62861](https://bz.apache.org/bugzilla/show_bug.cgi?id=62861)Thread Group: Provide ability to configure whether a new iteration is a new user or same user (Would be applied on Cookie Manager, Cache Manager and httpclient.reset_state_on_thread_group_iteration). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63616](https://bz.apache.org/bugzilla/show_bug.cgi?id=63616)Fix Javadoc: ``` JMeterContext#getThreadNum() ``` starts at 0 and not 1. Contributed by Ori Marko (orimarko at gmail.com) - Updated to httpclient/httpmime 4.5.10 (from 4.5.7) - Updated to dnsjava 2.1.9 (from 2.1.8) - Updated to jsoup 1.12.1 (from 1.11.3) - Updated to rsyntaxtextarea 3.0.4 (from 3.0.2) - Updated to caffeine 2.8.0 (from 2.6.2) - Updated to commons-codec 1.13 (from 1.11) - Updated to commons-lang3 3.9 (from 3.8.1) - Updated to commons-pool 2.7 (from 2.6) - Updated to commons-text 1.8 (from 1.6) - Updated to freemarker 2.3.29 (from 2.3.28) - Updated to httpcore/httpcore-nio 4.12 (from 4.11) - Updated to jodd 5.0.13 (from 5.0.6) - Updated to log4j 2.12.1 (from 2.11.1) - Updated to ph-commons 9.3.7 (from 9.2.1) - Updated to ph-css 6.2.0 (from 6.1.1) - Updated to Mozilla Rhino 1.7.11 (from 1.7.10) - Updated to Saxon-HE 9.9.1-5 (from 9.9.1-1) - Updated to slf4j 1.7.28 (from 1.7.25) - Updated to tika-core and tika-parsers 1.22 (from 1.21) - Updated jackson-annotations, jackson-core and jackson-databind to 2.9.10 (from 2.9.8) ## Non-functional changes - Migrated from subversion to [Git](https://github.com/apache/jmeter) - [Bug 63630](https://bz.apache.org/bugzilla/show_bug.cgi?id=63630)Switch build from Apache Ant to Gradle - [Bug 63529](https://bz.apache.org/bugzilla/show_bug.cgi?id=63529)Add more unit tests for org.apache.jorphan.util.JOrphanUtils. Contributed by John Bergqvist(John.Bergqvist at diffblue.com) - Updated to latest checkstyle (version 8.22) - Clean-up of code in `CompareAssertion` and other locations. Based on patch by Graham Russell (graham at ham1.co.uk) - [PR#491](https://github.com/apache/jmeter/pull/491)Increase Graphite metrics coverage. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#520](https://github.com/apache/jmeter/pull/520)Replace anonymous classes with lambda expressions. Contributed by Graham Russell (graham at ham1.co.uk). - [PR#524](https://github.com/apache/jmeter/pull/524)Migration from JUnit 4 to JUnit 5. Contributed by Graham Russell (graham at ham1.co.uk). ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 63298](https://bz.apache.org/bugzilla/show_bug.cgi?id=63298)HTTP Requests with encoded URLs are being sent in decoded format - [Bug 63364](https://bz.apache.org/bugzilla/show_bug.cgi?id=63364)When setting `subresults.disable_renaming=true`, sub results are still renamed using their parent SampleLabel while they shouldn't. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63129](https://bz.apache.org/bugzilla/show_bug.cgi?id=63129)JMeter can not identify encoding during first time page submission. Based partly on analysis and PR made by Naveen Nandwani (naveen.nandwani at india.nec.com) - [Bug 62672](https://bz.apache.org/bugzilla/show_bug.cgi?id=62672)HTTP Request sends double requests when using proxy with authentication. Based on patch by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 63574](https://bz.apache.org/bugzilla/show_bug.cgi?id=63574)HTTP Cache Manager does not cache resource if `Cache-Control` header is missing. #### Other Samplers - [Bug 63442](https://bz.apache.org/bugzilla/show_bug.cgi?id=63442)Reduce scanning for `LogParser` implementations in AccessLogSamplerBeanInfo. - [Bug 63563](https://bz.apache.org/bugzilla/show_bug.cgi?id=63563)LdapExtSampler: When sampler fails with exception differing from NamingException, no SampleResult is generated - [Bug 63469](https://bz.apache.org/bugzilla/show_bug.cgi?id=63469)JMSPublisher: Race condition in jms.client.ClientPool#clearClient #### Controllers #### Listeners - [Bug 63319](https://bz.apache.org/bugzilla/show_bug.cgi?id=63319)`ArrayIndexOutOfBoundsException` in Aggregate Graph when selecting 90 % or 95 % columns - [Bug 63423](https://bz.apache.org/bugzilla/show_bug.cgi?id=63423)Selection of table rows in Aggregate Graph gets lost too often - [Bug 63347](https://bz.apache.org/bugzilla/show_bug.cgi?id=63347)View result tree: The search field is so small that even a single character is not visible on Windows 7 - [Bug 63433](https://bz.apache.org/bugzilla/show_bug.cgi?id=63433)ListenerNotifier: Detected problem in Listener NullPointerException if filename is null. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63674](https://bz.apache.org/bugzilla/show_bug.cgi?id=63674)Strip results with subresults deeper in their hierarchy when DataStripping is enabled #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 63455](https://bz.apache.org/bugzilla/show_bug.cgi?id=63455)XPath Assertion: `True if nothing matches` does not work if XPath expression returns a boolean. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Functions #### I18N #### Report / Dashboard #### Documentation - [Bug 63513](https://bz.apache.org/bugzilla/show_bug.cgi?id=63513)Add MariaDB examples to JDBC documentation. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 63484](https://bz.apache.org/bugzilla/show_bug.cgi?id=63484)Add notes to use Apache Velocity as JSR223 script language. Based on a patch by Ori Marko (orimarko at gmail.com) - [Bug 63519](https://bz.apache.org/bugzilla/show_bug.cgi?id=63519)[PR#471](https://github.com/apache/jmeter/pull/471)Use correct method `getLabelResource()` in JMeter tutorial. Contributed by Sun Tao (buzzerrookie at hotmail.com>) #### General - [Bug 63394](https://bz.apache.org/bugzilla/show_bug.cgi?id=63394)JMeter should fail with non-zero when test execution fails (due to missing test plan or other reason). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63464](https://bz.apache.org/bugzilla/show_bug.cgi?id=63464)image/svg+xml is wrongly considered as binary - [Bug 63490](https://bz.apache.org/bugzilla/show_bug.cgi?id=63490)At end of scheduler duration lots of Samplers gets executed at the same time - [PR#480](https://github.com/apache/jmeter/pull/480)[PR#482](https://github.com/apache/jmeter/pull/482)Fix a few typos in comments and log messages. Based on patch by Anass Benomar (anassbenomar at gmail.com) - [Bug 63751](https://bz.apache.org/bugzilla/show_bug.cgi?id=63751)Correct a typo in Chinese translations. Reported by Jinliang Wang (wjl31802 at 126.com) - [Bug 63723](https://bz.apache.org/bugzilla/show_bug.cgi?id=63723)Distributed testing: JMeter controller node ends distributed test though some threads still are active - [Bug 63614](https://bz.apache.org/bugzilla/show_bug.cgi?id=63614)Distributed testing: Unable to generate Dashboard report at end of load test - [Bug 63862](https://bz.apache.org/bugzilla/show_bug.cgi?id=63862) Search Dialog / Search in View Results Tree: Uncaught exception if regex is checked and regex is invalid - [Bug 63793](https://bz.apache.org/bugzilla/show_bug.cgi?id=63793)Fix unsecure XML Parsing ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Clifford Harms (clifford.harms at gmail.com) - [Ubik Load Pack](https://ubikloadpack.com) - Xia Li - Naveen Nandwani (naveen.nandwani at india.nec.com) - Artem Fedorov (artem.fedorov at blazemeter.com) - Ori Marko (orimarko at gmail.com) - Sun Tao (buzzerrookie at hotmail.com) - John Bergqvist (John.Bergqvist at diffblue.com) - Franz Schwab (franz.schwab at exasol.com) - Graham Russell (graham at ham1.co.uk) - Anass Benomar (anassbenomar at gmail.com) - [Jakub Bednář](https://github.com/bednar) - Pascal Schumacher (pascalschumacher at apache.org) - [GraphAware](https://graphaware.com/) We also thank bug reporters who helped us improve JMeter. - Sergiy Iampol (sergiy.iampol at playtech.com) - Brian Tully (brian.tully at acquia.com) - Amer Ghazal (amerghazal at gmail.com) - Stefan Seide (stefan at trilobyte-se.de) - Havlicek Honza (havlicek.honza at gmail.com) - Pierre Astruc (pierre.astruc at evertest.com) - Jinliang Wang (wjl31802 at 126.com) Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. - Since Java 11 the JavaScript implementation [Nashorn has been deprecated](https://openjdk.java.net/jeps/335). Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn. ``` Warning: Nashorn engine is planned to be removed from a future JDK release ``` To silence these warnings, add `-Dnashorn.args=--no-deprecation-warning` to your Java arguments. That can be achieved by setting the enviroment variable `JVM_ARGS` ``` export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning" ``` ## Version 5.1.1 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy This release is mainly a bugfix release. Please see the [Changes history page](/user-manual/changes-history/) to view the last major behaviors with the version 5.1. ### Live Reporting and Web Report A new menu entry has been added to the **Tools** menu. It's allow to generate a results report from a previous CSV/JTL file. ![changes/5.1.1/01_menu_generate_report.png](/images/screenshots/changes/5.1.1/01_menu_generate_report.png) ![changes/5.1.1/02_windows_generate_report.png](/images/screenshots/changes/5.1.1/02_windows_generate_report.png) ## Incompatible changes ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62977](https://bz.apache.org/bugzilla/show_bug.cgi?id=62977)Allow sending HTTP requests without a default User-Agent header #### Other samplers - [Bug 63185](https://bz.apache.org/bugzilla/show_bug.cgi?id=63185)LDAP related elements: Add option to implicitly trust SSL/TLS connections/Disable hostname verification. Based on contribution by Brian Wolfe (wolfebrian2120 at gmail.com) #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 63178](https://bz.apache.org/bugzilla/show_bug.cgi?id=63178)CSS Selector Extractor: Improve performance of JODD (JoddExtractor) based implementation #### Functions #### I18N #### Report / Dashboard - [Bug 59896](https://bz.apache.org/bugzilla/show_bug.cgi?id=59896) Report / Dashboard: Add a menu entry to generate a report on demand from a CSV file. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [PR#444](https://github.com/apache/jmeter/pull/444)Update to latest Spock v1.2 (was 1.0). Contributed by Graham Russell (graham at ham1.co.uk) - [PR#446](https://github.com/apache/jmeter/pull/446)Improve Unit tests readability and use of Spock. Contributed by Graham Russell (graham at ham1.co.uk) ## Non-functional changes - [Bug 63203](https://bz.apache.org/bugzilla/show_bug.cgi?id=63203)Unit Tests: Replace use of `@Deprecated` by `@VisibleForTesting` for methods/constructors/classes made public for Unit Testing only - [PR#449](https://github.com/apache/jmeter/pull/449)Refactor and Test ResponseTimePercentilesOverTimeGraphConsumer. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#450](https://github.com/apache/jmeter/pull/450)Abstract graph consumer improvements. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#451](https://github.com/apache/jmeter/pull/451)Improve a few unit tests and classes. Contributed by Graham Russell (graham at ham1.co.uk) ## Bug fixes #### HTTP Samplers and Test Script Recorder #### Other Samplers - [Bug 63202](https://bz.apache.org/bugzilla/show_bug.cgi?id=63202)JMS Publisher: ObjectMessageRenderer creates XStream instance with uninitialized security #### Controllers #### Listeners - [Bug 63204](https://bz.apache.org/bugzilla/show_bug.cgi?id=63204)`RenderAsJSON#prettyJSON`: `JSONParser#parse` cannot return JSONValue #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62446](https://bz.apache.org/bugzilla/show_bug.cgi?id=62446)Counter documentation is wrong in required fieds. Contributed by orimarko at gmail.com - [Bug 62327](https://bz.apache.org/bugzilla/show_bug.cgi?id=62327)TestPlan: In library table if path is modified and plan saved, the modification is lost on file reload #### Functions - [Bug 63241](https://bz.apache.org/bugzilla/show_bug.cgi?id=63241)`__threadGroupName` causes a NullPointerException if called from non Test threads #### I18N #### Report / Dashboard - [Bug 63198](https://bz.apache.org/bugzilla/show_bug.cgi?id=63198)Response Time Vs Request and Latency Vs Request graphs don't line up with throughput. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Documentation #### General - [Bug 63201](https://bz.apache.org/bugzilla/show_bug.cgi?id=63201)SearchTreeDialog disappears behind master JFrame. Contributed by Benoit Vatan (benoit.vatan at gmail.com) - [Bug 63220](https://bz.apache.org/bugzilla/show_bug.cgi?id=63220)`Function Helper Dialog`, `Export transactions for report` and `Import from cURL` disappear being master JFrame. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63207](https://bz.apache.org/bugzilla/show_bug.cgi?id=63207)java.lang.NullPointerException: null when run JMeter 5.1 with proxy options - [Bug 58183](https://bz.apache.org/bugzilla/show_bug.cgi?id=58183)Rampup may not be respected if thread take time to start leading to threads continuing to start post ramp up time ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](https://ubikloadpack.com) - Benoit Vatan (benoit.vatan at gmail.com) - Graham Russell (graham at ham1.co.uk) - Brian Wolfe (wolfebrian2120 at gmail.com) - orimarko at gmail.com We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 5.1 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ### Core improvements JDBC testing has been improved with ability to set init SQL statements and add compatibility with JDBC drivers that do not support QueryTimeout ![changes/5.1/jdbc-connection-config-init-request.png](/images/screenshots/changes/5.1/jdbc-connection-config-init-request.png) - Various bug fixes have been implemented, like gathering the correct headers when recording requests through the HTTP(S) Test Script Recorder using HTTPS - In version 5.0, JMeter was changed to rename Sub results using a custom Naming Policy ([Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550)). This change could be annoying for Functional Testing, a new property `subresults.disable_renaming=true` has been introduced to revert if needed to previous behaviour. An alternative is to check `Functional Test Mode` in Test Plan, see [Bug 63055](https://bz.apache.org/bugzilla/show_bug.cgi?id=63055) ### UX improvements Templates can provide parameters that are filled in on test plan generation, `Recording` template uses this feature ![changes/5.1/templates-parametes.png](/images/screenshots/changes/5.1/templates-parametes.png) A new `Tools` menu has been introduced to collect those entries, that are used for general usage around JMeter, like: - `Function Helper Dialog` - `Export transactions for report` - `Generate Schematic View` which provides an overview as HTML of the Test plan - `Import from cURL` which allows you to create or update your test plan by importing a cURL command - `Compile JSR223 Test Elements` - `Create a heap dump` - `Create a thread dump` ![changes/5.1/jmeter-new-menu-tools.png](/images/screenshots/changes/5.1/jmeter-new-menu-tools.png) ### Test Plan Ability to create a Test plan from a cURL command. ![changes/5.1/http-request-from-curl-request.png](/images/screenshots/changes/5.1/http-request-from-curl-request.png) ### Scripting / Debugging enhancements - A menu item to compile all JSR223 Elements is now available in `Tools` menu ### Live Reporting and Web Report - A JSON file containing summary of a load test statistics is now generated when using `-e` or `-g` options. - Percentiles computing graphed over time algorithm has been modified to restart for each time slot - More user-friendly behaviour when reporting folder does not exist or is not empty through `-f` command line option ## Incompatible changes - In `Response Time Percentiles Over Time (successful responses)` graph of the HTML report, before this version, percentile computation of each time slot used the percentile data of previous time slot as a base. Starting with this version, each time slot is independant. See [Bug 62883](https://bz.apache.org/bugzilla/show_bug.cgi?id=62883) - `ClientJMeterEngine#rsetProperties` signature has been changed to use `HashMap<String,String>` instead of Properties, see [Bug 63034](https://bz.apache.org/bugzilla/show_bug.cgi?id=63034) - A new Menu item `Tools` has been introduced, some menu items that were in `Help` menu are now under this new menu item. See [Bug 63094](https://bz.apache.org/bugzilla/show_bug.cgi?id=63094) - `slf4j-ext` has been removed from libraries (lib folder) and JMeter pom. It was not used by default and due to CVE-2018-8088 and unavailability of a stable version containing a fix to this issue, we decided to remove it. If you still needed, you can add it in lib folder. ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62840](https://bz.apache.org/bugzilla/show_bug.cgi?id=62840)HTTP Request: Add option `httpclient4.gzip_relax_mode` to avoid error when unzipping what seems to be invalid streams - [Bug 63025](https://bz.apache.org/bugzilla/show_bug.cgi?id=63025)Enhance Search & Replace functionality for HTTP Request to include port and protocol field. Initial code fix by Mohamed Ibrahim (rollno748 at gmail.com) #### Other samplers - [Bug 62934](https://bz.apache.org/bugzilla/show_bug.cgi?id=62934)Add compatibility for JDBC drivers that do not support QueryTimeout - [Bug 62935](https://bz.apache.org/bugzilla/show_bug.cgi?id=62935)Pass custom `mail.*` properties to Mail Reader Sampler. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 63055](https://bz.apache.org/bugzilla/show_bug.cgi?id=63055)Don't rename SampleResult Label when test is running in Functional mode or property `subresults.disable_renaming=true`. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. #### Controllers #### Listeners - [Bug 62822](https://bz.apache.org/bugzilla/show_bug.cgi?id=62822)[PR#407](https://github.com/apache/jmeter/pull/407)Render uninitialized min and max values in Summary Report as `#N/A` #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62766](https://bz.apache.org/bugzilla/show_bug.cgi?id=62766)Keystore Config: We should load all aliases by default. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62832](https://bz.apache.org/bugzilla/show_bug.cgi?id=62832)JDBC Connection Configuration: Be able to set init SQL statements. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Functions - [Bug 63037](https://bz.apache.org/bugzilla/show_bug.cgi?id=63037)When using `CSVRead` search the script base path for files, too. #### I18N #### Report / Dashboard - [Bug 62883](https://bz.apache.org/bugzilla/show_bug.cgi?id=62883)Report / Dashboard: Change the way percentiles are computed for Response Time Percentiles Over Time (successful responses) graph - [Bug 63060](https://bz.apache.org/bugzilla/show_bug.cgi?id=63060)Report Generator: A generator should only check for folder/files it generates and only delete those ones - [Bug 63059](https://bz.apache.org/bugzilla/show_bug.cgi?id=63059)Create a new JsonExporter that exports as JSON the content of data computed for HTML Dashboard Statistics table. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63081](https://bz.apache.org/bugzilla/show_bug.cgi?id=63081)Command line Option `-f` does not delete report folder when using generation only through command line option `-g`. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 62959](https://bz.apache.org/bugzilla/show_bug.cgi?id=62959)Ability to create a Test plan from a cURL command. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#394](https://github.com/apache/jmeter/pull/394)Allow `null` values in `FieldStringEditor`. Based on patch by Mingun (alexander_sergey at mail.ru) - [Bug 62826](https://bz.apache.org/bugzilla/show_bug.cgi?id=62826)When changing LAF, make JMeter restart if user clicks yes to popup - [Bug 62257](https://bz.apache.org/bugzilla/show_bug.cgi?id=62257)[PR#401](https://github.com/apache/jmeter/pull/401)Expand/Collapse short key (minus sign) on numpad doesn't work. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62752](https://bz.apache.org/bugzilla/show_bug.cgi?id=62752)Add to Documentation: `ctx.getThreadNum()` is zero-based while `\${__threadNum}` is one-based - [PR#411](https://github.com/apache/jmeter/pull/411)Use `SHA-1` instead of `SHA1` in `org.apache.jmeter.save.SaveService`. Contributed by Paco (paco.xu at daocloud.io) - [Bug 62914](https://bz.apache.org/bugzilla/show_bug.cgi?id=62914)Add a hint in Thread Group UI about duration of test - [Bug 62925](https://bz.apache.org/bugzilla/show_bug.cgi?id=62925)Add support for ThreadDump to the JMeter non-GUI - [Bug 62870](https://bz.apache.org/bugzilla/show_bug.cgi?id=62870)Templates: Add ability to provide parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62829](https://bz.apache.org/bugzilla/show_bug.cgi?id=62829)Allow specifying Proxy server scheme for HTTP request sampler, Advanced tab and command line option. Contributed by Hitesh Patel (hitesh.h.patel at gmail.com) - [Bug 59633](https://bz.apache.org/bugzilla/show_bug.cgi?id=59633)Menus `Save Test Plan as`, `Save as Test Fragment` and `Save Selection as ...` should use a new file name in File Dialog - [Bug 61486](https://bz.apache.org/bugzilla/show_bug.cgi?id=61486)Make jmeter-server and non GUI mode run headless - [Bug 63093](https://bz.apache.org/bugzilla/show_bug.cgi?id=63093)Add `Compile JSR223 Test Elements` menu item. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63094](https://bz.apache.org/bugzilla/show_bug.cgi?id=63094)Introduce a new Tools menu - [Bug 63101](https://bz.apache.org/bugzilla/show_bug.cgi?id=63101)Propose a menu item to generate readable overview of Test Plan - [Bug 63144](https://bz.apache.org/bugzilla/show_bug.cgi?id=63144)View listener tree take a long time to open response that has huge text. Contributed by Ubik Load Pack (support at ubikloadpack.com) ## Non-functional changes - [PR#408](https://github.com/apache/jmeter/pull/408)Log an informational message instead of an stack trace, when JavaFX is not found for the `RenderInBrowser` component. - [PR#412](https://github.com/apache/jmeter/pull/412)Update Chinese translation. Contributed by 刘士 (liushilive at outlook.com). - [PR#406](https://github.com/apache/jmeter/pull/406)Add a short paragraph on how to use a security manager with JMeter. - [Bug 62893](https://bz.apache.org/bugzilla/show_bug.cgi?id=62893)Use StringEscapeUtils from commons-text (version 1.6) instead of the deprecated ones from commons-lang3. - [Bug 62972](https://bz.apache.org/bugzilla/show_bug.cgi?id=62972)[PR#435](https://github.com/apache/jmeter/pull/435)Replace calls to deprecated method `Class#newInstance`. - [Bug 63034](https://bz.apache.org/bugzilla/show_bug.cgi?id=63034)ClientJMeterEngine: Make rsetProperties use `HashMap<String,String>` instead of Properties - Updated to httpclient/httpmime 4.5.7 (from 4.5.6) - Updated to httpcore 4.4.11 (from 4.4.10) - Updated to httpcore-nio 4.4.11 (from 4.4.10) - Updated to tika-core and tika-parsers 1.20 (from 1.18) - Updated to commons-dbcp2-2.5.0 (from commons-dbcp2-2.4.0) - Updated to commons-lang3-3.8.1 (from commons-lang3-3.8) - Updated to groovy-all-2.4.16 (from groovy-all-2.4.15) - Updated to httpasyncclient-4.1.4.jar (from 4.1.3) - Updated to jsoup-1.11.3 (from 1.11.2) - Updated to cglib-nodep-3.2.9 (from cglib-nodep-3.2.7) - Updated to ph-commons-9.2.1 (from ph-commons-9.1.2) - Updated to log4j-2.11.1 (from log4j-2.11.0) - Updated to xmlgraphics-commons 2.3 (from 2.2) - [Bug 63033](https://bz.apache.org/bugzilla/show_bug.cgi?id=63033)Updated to Saxon-HE 9.9.1-1 (from 9.8.0-12). Thanks at Saxonica - Updated to xstream 1.4.11 (from 1.4.10) - Updated to jodd 5.0.6 (from 4.1.4) - Updated to asm-7.0 (from 6.1) - Update to ActiveMQ 5.15.8 (from 5.5.16) - Updated to rsyntaxtextarea-3.0.2 (from 2.6.1) - Updated to apache-rat-0.13 (from 0.12) - Updated to jacocoant-0.8.3 (from 0.8.2) - Updated to hsqldb-2.4.1 (from 2.4.0) - Updated to mina-core-2.0.19 (from 2.0.16) - [Bug 62818](https://bz.apache.org/bugzilla/show_bug.cgi?id=62818)Updated to xercesImpl to 2.12.0 (from 2.11.0). Reported by Stefan Seide (stefan at trilobyte-se.de) - [Bug 62744](https://bz.apache.org/bugzilla/show_bug.cgi?id=62744)Upgrade jquery to version 3.3.1, jquery-ui to 1.12.1, bootstrap to 3.3.7 - [Bug 62821](https://bz.apache.org/bugzilla/show_bug.cgi?id=62821)[PR#405](https://github.com/apache/jmeter/pull/405)Use SHA-512 checksums instead of MD5 to verify jar downloads - [Bug 63053](https://bz.apache.org/bugzilla/show_bug.cgi?id=63053)Remove referrals to never implemented internals from user documentation. Reported by U. Poblotzki (u.poblotzki at thalia.de) - [Bug 63082](https://bz.apache.org/bugzilla/show_bug.cgi?id=63082)[PR#437](https://github.com/apache/jmeter/pull/437)Use utf-8 for properties files in source - [Bug 63177](https://bz.apache.org/bugzilla/show_bug.cgi?id=63177)Rename NON GUI mode into CLI Mode in documentation ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 62785](https://bz.apache.org/bugzilla/show_bug.cgi?id=62785)[PR#400](https://github.com/apache/jmeter/pull/400)Incomplete search path applied to the filenames used in the upload functionality of the HTTP sampler. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 62842](https://bz.apache.org/bugzilla/show_bug.cgi?id=62842)HTTP(S) Test Script Recorder: Brotli compression is not supported leading to "`Content Encoding Error`" - [Bug 60424](https://bz.apache.org/bugzilla/show_bug.cgi?id=60424)Hessian Burlap application: JMeter inserts `0x0D` before `0x0A` automatically (http binary post data) - [Bug 62940](https://bz.apache.org/bugzilla/show_bug.cgi?id=62940)Use different `cn` and type of SAN extension when we are generating certificates based on IP addresses. - [Bug 62916](https://bz.apache.org/bugzilla/show_bug.cgi?id=62916)HTTP Test Script Recorder fails with UnsupportedOperationException if recording is started after a distributed test has been run - [Bug 62987](https://bz.apache.org/bugzilla/show_bug.cgi?id=62987)A TestBean element under HTTP(S) Test Script recorder does not work. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63015](https://bz.apache.org/bugzilla/show_bug.cgi?id=63015)Abnormal NoHttpResponseException when running request through proxy HTTP(S) Test Script Recorder after a first failing request. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62852](https://bz.apache.org/bugzilla/show_bug.cgi?id=62852)HTTP Request Header missing information when using a proxy. Thanks to Oleg Kalnichevski (olegk at apache.org) - [Bug 63048](https://bz.apache.org/bugzilla/show_bug.cgi?id=63048)JMeter does not retrieve link resources of type "shortcut icon" or "icon". Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Other Samplers - [Bug 62775](https://bz.apache.org/bugzilla/show_bug.cgi?id=62775)If many jars are in a folder referenced by `user.classpath`, startup can be extremely slow due to JUnit - [Bug 63031](https://bz.apache.org/bugzilla/show_bug.cgi?id=63031)Incorrect JDBC driver class: `org.firebirdsql.jdbc.FBDrivery`. Contributed by Sonali (arora.sonali99 at gmail.com) #### Controllers - [Bug 62806](https://bz.apache.org/bugzilla/show_bug.cgi?id=62806)ModuleController cloning by Run behaves differently whether in GUI or Non GUI mode. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62847](https://bz.apache.org/bugzilla/show_bug.cgi?id=62847)If Controller cannot use variable for index exposed by LoopController/WhileController/ForEachController - [Bug 63064](https://bz.apache.org/bugzilla/show_bug.cgi?id=63064)Ignore spaces at the end and beginning of expressions used in IfController #### Listeners - [Bug 62770](https://bz.apache.org/bugzilla/show_bug.cgi?id=62770)Aggregate Graph throws `ArrayIndexOutOfBoundsException` - [Bug 63069](https://bz.apache.org/bugzilla/show_bug.cgi?id=63069)ResultCollector does not write end of XML file if user exits while a Recording or a test is running. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63138](https://bz.apache.org/bugzilla/show_bug.cgi?id=63138)InfluxDB BackendListenerClient: In case of error, log is in debug, it should be in error #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62774](https://bz.apache.org/bugzilla/show_bug.cgi?id=62774)XPath2Extractor: Scope variable is broken. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62860](https://bz.apache.org/bugzilla/show_bug.cgi?id=62860)JSON Extractor: Avoid NPE and noisy error message "`Error processing JSON content in`" when variable is not found #### Functions #### I18N #### Report / Dashboard - [Bug 62777](https://bz.apache.org/bugzilla/show_bug.cgi?id=62777)Web Report / Dashboard: Hide All in `Response Time Percentiles Over Time (successful responses)` fails. - [Bug 62780](https://bz.apache.org/bugzilla/show_bug.cgi?id=62780)Web Report / Dashboard: Display All in `Response Time Vs Request` fails. - [Bug 62781](https://bz.apache.org/bugzilla/show_bug.cgi?id=62781)Web Report / Dashboard: Display All in `Response Time Overview` fails. - [Bug 62782](https://bz.apache.org/bugzilla/show_bug.cgi?id=62782)Web Report / Dashboard: Remove duplicate/unused dependencies - [Bug 62894](https://bz.apache.org/bugzilla/show_bug.cgi?id=62894)Report / Dashboard: Throughput is in wrong column which is confusing as unit is millisecond - [Bug 63016](https://bz.apache.org/bugzilla/show_bug.cgi?id=63016)Empty HTML report if source csv contains labels with quotes. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Documentation - Change `Test Action` (old name) to `Flow Control Action` in Component Reference documentation. Contributed by Ori Marko (orimarko at gmail.com) #### General - [Bug 62745](https://bz.apache.org/bugzilla/show_bug.cgi?id=62745)Fix undefined disabled icon. Contributed by Till Neunast (https://github.com/tilln) - [Bug 62743](https://bz.apache.org/bugzilla/show_bug.cgi?id=62743)Client auth must be enabled on distributed testing - [Bug 62767](https://bz.apache.org/bugzilla/show_bug.cgi?id=62767)NPE when searching under certain conditions. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62790](https://bz.apache.org/bugzilla/show_bug.cgi?id=62790)`ArrayIndexOutOfBoundsException` when calling replace without selecting the first match - [Bug 62795](https://bz.apache.org/bugzilla/show_bug.cgi?id=62795)JMeter controller node sometimes ends distributed test even though some of the worker nodes have not finished - [Bug 62336](https://bz.apache.org/bugzilla/show_bug.cgi?id=62336)[PR#396](https://github.com/apache/jmeter/pull/396)Some shortcuts are not working correctly on windows. Contributed by Michael Pavlov (michael.paulau at gmail.com) - [Bug 62889](https://bz.apache.org/bugzilla/show_bug.cgi?id=62889)Format JSON Arrays when displayed with JSON Path Tester. - [Bug 62900](https://bz.apache.org/bugzilla/show_bug.cgi?id=62900)ObjectProperty#getStringValue() can throw NullPointerException - [Bug 63099](https://bz.apache.org/bugzilla/show_bug.cgi?id=63099)Escape commata in function helper dialog only outside of variable replacement structures. - [Bug 63105](https://bz.apache.org/bugzilla/show_bug.cgi?id=63105)Export Transactions for Report: fix 2 bugs - [Bug 63106](https://bz.apache.org/bugzilla/show_bug.cgi?id=63106)Apply naming policy does not refresh UI - [Bug 63180](https://bz.apache.org/bugzilla/show_bug.cgi?id=63180)Apply Naming Policy allows multi selection but only considers first node - [Bug 63090](https://bz.apache.org/bugzilla/show_bug.cgi?id=63090)Remove slf4j-ext due to CVE-2018-8088 ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Oleg Kalnichevski (olegk at apache.org) - Till Neunast (https://github.com/tilln) - Mingun (alexander_sergey at mail.ru) - [Ubik Load Pack](https://ubikloadpack.com) - Artem Fedorov (artem.fedorov at blazemeter.com) - Stefan Seide (stefan at trilobyte-se.de) - 刘士 (liushilive at outlook.com) - Michael Pavlov (michael.paulau at gmail.com) - Ori Marko (orimarko at gmail.com) - Paco (paco.xu at daocloud.io) - Hitesh Patel (hitesh.h.patel at gmail.com) - Sonali (arora.sonali99 at gmail.com) - Mohamed Ibrahim (rollno748 at gmail.com) - U. Poblotzki (u.poblotzki at thalia.de) - [Saxonica](https://www.saxonica.com) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 5.0 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ### Core improvements Rest support has been improved in many fields - Multipart/form-data requests now work for `PUT`, `DELETE` … - It is now also possible to send a JSON Body with attached file - Parameters entered in Parameters Tab are now used in body instead of being ignored ![changes/5.0/jmeter_5_rest1.png](/images/screenshots/changes/5.0/jmeter_5_rest1.png) ![changes/5.0/jmeter_5_rest2.png](/images/screenshots/changes/5.0/jmeter_5_rest2.png) In distributed testing, JMeter now automatically prefixes thread names with engine host and port, this makes the counting of threads correct in the HTML report without any other configuration as it was required before ![changes/5.0/jmeter_5_distributed.png](/images/screenshots/changes/5.0/jmeter_5_distributed.png) XPath 2.0 is supported in a new element called `XPath2 extractor` providing easier XML namespaces handling, up to date XPath syntax and better performances ![changes/5.0/jmeter_5_xpath2_extractor.png](/images/screenshots/changes/5.0/jmeter_5_xpath2_extractor.png) ![changes/5.0/jmeter_5_xpath2_tester.png](/images/screenshots/changes/5.0/jmeter_5_xpath2_tester.png) Upgrade to HTTP Components 4.6 last APIs has been completed and JMeter does not rely anymore on deprecated APIs of this library It is now possible to control in an easier way Loop breaking and Loop switching to next iteration. This is available in `Flow Control Action` and `Result Status Action Handler` elements ![changes/5.0/jmeter_5_flow_control_action.png](/images/screenshots/changes/5.0/jmeter_5_flow_control_action.png) ![changes/5.0/jmeter_5_result_status_handler.png](/images/screenshots/changes/5.0/jmeter_5_result_status_handler.png) While Controller now exports a variable containing its current index named `__jm__<Name of your element>__idx`. So for example, if your While Controller is named WC, then you can access the looping index through `\${__jm__WC__idx}` ### Scripting / Debugging enhancements Search feature has been improved to allow you to iterate in the tree over search results and do necessary replacements through `Next`/`Previous`/`Replace`/`Replace/Find` buttons ![changes/5.0/jmeter_5_search_feature.png](/images/screenshots/changes/5.0/jmeter_5_search_feature.png) In View Results Tree, the request and response headers/body are clearly separated to allow you to better inspect requests and responses. You can also search in all those tabs for a particular value ![changes/5.0/jmeter_5_vrt_request_body.png](/images/screenshots/changes/5.0/jmeter_5_vrt_request_body.png) ![changes/5.0/jmeter_5_vrt_response_body.png](/images/screenshots/changes/5.0/jmeter_5_vrt_response_body.png) Recording feature has been improved to provide a popup that is always on top when you navigate in browser allowing you to name transactions while you navigate in your application. ![changes/5.0/jmeter_5_recording.png](/images/screenshots/changes/5.0/jmeter_5_recording.png) You can now restart JMeter from menu **File → Restart** ![changes/5.0/jmeter_5_restart.png](/images/screenshots/changes/5.0/jmeter_5_restart.png) ### Live Reporting and Web Report Reporting feature has been enhanced A new Graph Total Transactions per second has been added to the HTML Web Report ![changes/5.0/jmeter_5_total_trans_per_sec.png](/images/screenshots/changes/5.0/jmeter_5_total_trans_per_sec.png) It is now possible to graph over time custom metrics available as JMeter Variables through `sample_variables`. Those custom metrics graphs will be available in the HTML Report in `Custom Graphs section` ![changes/5.0/jmeter_5_custom_graphs.png](/images/screenshots/changes/5.0/jmeter_5_custom_graphs.png) Hits per second graph now takes into account the embedded resources ![changes/5.0/jmeter_5_hits_per_sec.png](/images/screenshots/changes/5.0/jmeter_5_hits_per_sec.png) In Live reporting, the sent and received bytes are now sent to Backends (InfluxDB or Graphite) ### Functions A New function `[__threadGroupName](/user-manual/functions/#__threadGroupName)` has been introduced to obtain ThreadGroup name. ## Incompatible changes - Since JMeter 5.0, when using default HC4 Implementation, JMeter will reset HTTP state (SSL State + Connections) on each thread group iteration. If you don't want this behaviour, set `httpclient.reset_state_on_thread_group_iteration=false` - Since JMeter 5.0, in relation to above remark, `https.use.cached.ssl.context` is deprecated and not used anymore. - Since JMeter 5.0, when using CSV output, sub results will now be also output to CSV file. To revert to previous behaviour set `jmeter.save.saveservice.subresults=false`, see [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470), [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917), [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550). - Since JMeter 5.0, `CSS/JQuery Extractor` has been renamed to `CSS Selector Extractor` - Since JMeter 5.0, `Test Action` has been renamed to `Flow Control Action` - Since JMeter 5.0, JMeter renames subResults to `parentName-N` where N is a number to ensure that Hits Per Second graph includes resources downloads, see [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550), [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470) and [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62260](https://bz.apache.org/bugzilla/show_bug.cgi?id=62260)Improve Rest support. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 58757](https://bz.apache.org/bugzilla/show_bug.cgi?id=58757)HTTP Request : Updated deprecated methods of HttpComponents to last APIs of httpclient-4.5.X. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62212](https://bz.apache.org/bugzilla/show_bug.cgi?id=62212)Recorder : Improve UX by providing a popup above all windows to be able to change Transaction names and pauses while using Browser. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62248](https://bz.apache.org/bugzilla/show_bug.cgi?id=62248)HTTP Request : Parameters entered in Parameters Tab should be used in body instead of being ignored. Partly based on a patch by Artem Fedorov contributed by Blazemeter. - [Bug 60015](https://bz.apache.org/bugzilla/show_bug.cgi?id=60015)Multipart/form-data works only for `POST` using HTTPClient4 while it should for `PUT`, `DELETE`, … Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62317](https://bz.apache.org/bugzilla/show_bug.cgi?id=62317)HTTP(S) Test Script Recorder: allow to add ResultSaver to created sampler #### Other samplers - [PR#376](https://github.com/apache/jmeter/pull/376)JUnitSampler logs exceptions except assertion-failures from test cases as warnings. Contributed by Davide Angelocola (davide.angelocola at fisglobal.com) - [Bug 62244](https://bz.apache.org/bugzilla/show_bug.cgi?id=62244)Rename `Test Action` to `Flow Control Action` - [Bug 62302](https://bz.apache.org/bugzilla/show_bug.cgi?id=62302)Move JSR223 Sampler up the menu. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62595](https://bz.apache.org/bugzilla/show_bug.cgi?id=62595)SMTPSampler does not allow configuring the SSL/TLS protocols to be used on handshake. Contributed by Felipe Cuozzo (felipe.cuozzo at gmail.com) #### Controllers - [Bug 62237](https://bz.apache.org/bugzilla/show_bug.cgi?id=62237)While Controller : Export variable containing current index of iteration. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Listeners - [Bug 62195](https://bz.apache.org/bugzilla/show_bug.cgi?id=62195)Save Responses to a file : Improve component and UI. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62209](https://bz.apache.org/bugzilla/show_bug.cgi?id=62209)InfluxBackendListenerClient: First Assertion Failure Message must be sent if error code and response code are empty or OK - [Bug 62269](https://bz.apache.org/bugzilla/show_bug.cgi?id=62269)Bug 62269 - View Results Tree : Response and Request Tabs should contains Header and Body tabs. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62270](https://bz.apache.org/bugzilla/show_bug.cgi?id=62270)View Results Tree : Allow searching in Request headers, Response Headers, and Request body. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62276](https://bz.apache.org/bugzilla/show_bug.cgi?id=62276)InfluxDBBackendListenerClient / GraphiteBackendListenerClient : Add sent and received bytes to metrics. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62320](https://bz.apache.org/bugzilla/show_bug.cgi?id=62320)Counter : Reference Name property is not clear - [Bug 60991](https://bz.apache.org/bugzilla/show_bug.cgi?id=60991)XPath Extractor : Implement XPath 2.0. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62593](https://bz.apache.org/bugzilla/show_bug.cgi?id=62593)Rename CSS/JQuery Extractor to CSS Selector Extractor. Contributed by Ori Marko (orimarko at gmail.com) #### Functions - [Bug 62178](https://bz.apache.org/bugzilla/show_bug.cgi?id=62178)Add default value to `[__V](/user-manual/functions/#__V)` function. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62178](https://bz.apache.org/bugzilla/show_bug.cgi?id=62178)Add function `[__threadGroupName](/user-manual/functions/#__threadGroupName)` function to obtain ThreadGroup name. Mainly contributed by Ori Marko (orimarko at gmail.com) - [Bug 62533](https://bz.apache.org/bugzilla/show_bug.cgi?id=62533)Allow use epoch time as Date String value in function `[__dateTimeConvert](/user-manual/functions/#__dateTimeConvert)` - [Bug 62541](https://bz.apache.org/bugzilla/show_bug.cgi?id=62541)Allow `[__jexl3](/user-manual/functions/#__jexl3)`, `[__jexl2](/user-manual/functions/#__jexl2)` functions to support new syntax as `var x;`. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 61834](https://bz.apache.org/bugzilla/show_bug.cgi?id=61834)Function Helper Dialog : Improve tests by showing variables and keeping them available between evaluations #### I18N #### Report / Dashboard - [Bug 62243](https://bz.apache.org/bugzilla/show_bug.cgi?id=62243)Dashboard : make option "`--forceDeleteResultFile`"/"`-f`" option delete folder referenced by "`-o`" option - [Bug 62367](https://bz.apache.org/bugzilla/show_bug.cgi?id=62367)HTML Report Generator: Add Graph Total Transactions per Second. Contributed mainly by Martha Laks (laks.martha at gmail.com) - [Bug 62166](https://bz.apache.org/bugzilla/show_bug.cgi?id=62166)Report/Dashboard: Provide ability to register custom graphs and metrics in the JMeter Dashboard. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62542](https://bz.apache.org/bugzilla/show_bug.cgi?id=62542)Report/Dashboard : Display more information on filters when graph is empty. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62426](https://bz.apache.org/bugzilla/show_bug.cgi?id=62426)Optimize performance of report generation. Based on feedback by Allen (444104595 at qq.com) - [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550)Modify SubResult Naming Policy - [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917)Load Test with embedded resources download : Hits per seconds does not take into account the downloaded resources #### General - [Bug 62684](https://bz.apache.org/bugzilla/show_bug.cgi?id=62684)Distributed Testing : Add automatically to thread name a prefix to identify engine. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62155](https://bz.apache.org/bugzilla/show_bug.cgi?id=62155)Search Feature: Make Search text field get focus - [Bug 62156](https://bz.apache.org/bugzilla/show_bug.cgi?id=62156)Search Feature : Distinguish between node that matches search and node that contains a child that matches search - [Bug 62234](https://bz.apache.org/bugzilla/show_bug.cgi?id=62234)Search/Replace Feature : Enhance UX and add Replace/Next/Previous/Replace & Find features. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62238](https://bz.apache.org/bugzilla/show_bug.cgi?id=62238)Add ability to Switch to next iteration of Current Loop. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62239](https://bz.apache.org/bugzilla/show_bug.cgi?id=62239)Add ability to Break Current Loop - [Bug 61635](https://bz.apache.org/bugzilla/show_bug.cgi?id=61635)Add a menu to restart JMeter - [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470)CSV Output : Enable logging of sub results when `jmeter.save.saveservice.subresults=true`. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62473](https://bz.apache.org/bugzilla/show_bug.cgi?id=62473)Setting "`saveservice_properties`" has counter intuitive behaviour - [Bug 62354](https://bz.apache.org/bugzilla/show_bug.cgi?id=62354)Correct calculation and usage of units for second per user (reported by jffagot05 at gmail.com) - [Bug 62700](https://bz.apache.org/bugzilla/show_bug.cgi?id=62700)Introduce `jsr223.init.file` to allow calling a JSR-223 script on JMeter startup - [Bug 62128](https://bz.apache.org/bugzilla/show_bug.cgi?id=62128)Try to guess `JMETER_HOME` correctly, when `jmeter.bat` is called from a batch file in another directory. Contributed by logox01 (logox01 at gmx.at) - [PR#386](https://github.com/apache/jmeter/pull/386)Add parameter support for RMI keystore creation scripts. Contributed by Logan Mauzaize (t524467 at airfrance.fr) - [Bug 62065](https://bz.apache.org/bugzilla/show_bug.cgi?id=62065)Use Maven artifact for JAF Module instead of embedded module - [Bug 61714](https://bz.apache.org/bugzilla/show_bug.cgi?id=61714)Update Real-time results documentation - [PR#382](https://github.com/apache/jmeter/pull/382)Correct typo in documentation. Reported by Perze Ababa (perze.ababa at gmail.com>) - [PR#392](https://github.com/apache/jmeter/pull/392)Correct typo in documentation. Reported by Aaron Levin - [PR#379](https://github.com/apache/jmeter/pull/379) Improve chinese translations. Contributed by XmeterNet ## Non-functional changes - [PR#358](https://github.com/apache/jmeter/pull/358)[PR#365](https://github.com/apache/jmeter/pull/365)[PR#366](https://github.com/apache/jmeter/pull/366)[PR#375](https://github.com/apache/jmeter/pull/375)Updated to latest checkstyle (v8.8). Expanded Checkstyle to files in `src` and `test`; fixed newly checked files. Based on contribution by Graham Russell (graham at ham1.co.uk) - [Bug 62095](https://bz.apache.org/bugzilla/show_bug.cgi?id=62095)Correct description for right boundary parameter in Boundary Extractor. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62113](https://bz.apache.org/bugzilla/show_bug.cgi?id=62113)Updated to latest Bouncycastle (v1.60). Based on contribution by Olaf Flebbe (oflebbe at apache.org) - [Bug 62171](https://bz.apache.org/bugzilla/show_bug.cgi?id=62171)Remove `.md5` checksums and keep only `.sha512` checksums for source and binary archives - Updated to groovy-all-2.4.15 (from groovy-all-2.4.13) - Updated to asm-6.1 (from 6.0) - Updated to tika-core and tika-parsers 1.18 (from 1.17) - [Bug 62482](https://bz.apache.org/bugzilla/show_bug.cgi?id=62482)Sync documentation to the implementation of the ForEachController. Based on contribution by Ori Marko (orimarko at gmail.com) - [Bug 62529](https://bz.apache.org/bugzilla/show_bug.cgi?id=62529)Updated to httpclient-4.5.6 (from httpclient 4.5.5) and updated to freemarker-2.3.28 (from freemarker-2.3.23). Based on patch by Ori Marko (orimarko at gmail.com) - Updated to httpmime-4.5.6 (from httpmime-4.5.5) - Updated to caffeine-2.6.2 (from caffeine-2.6.1) - Updated to cglib-nodep-3.2.7 (from cglib-nodep-3.2.6) - Updated to commons-dbcp2-2.4.0 (from commons-dbcp2-2.2.0) - Updated to commons-pool2-2.6.0 (from commons-pool2-2.5.0) - Updated to httpcore-4.4.10 (from httpcore-4.4.9) - Updated to httpcore-nio-4.4.10 (from httpcore-nio-4.4.9) - Updated to log4j-2.11.0 (from log4j-2.10.0) - Updated to ph-css-6.1.1 (from ph-css-6.0.0) - Updated to ph-commons-9.1.2 (from ph-commons-9.0.0) - Updated to rhino-1.7.10 (from +rhino-1.7.7.2) - Updated to commons-lang3-3.8 (from commons-lang3-3.7) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 62114](https://bz.apache.org/bugzilla/show_bug.cgi?id=62114)HTTP(S) Test Script Recorder : Client certificate authentication uses the first SSLManager created. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61058](https://bz.apache.org/bugzilla/show_bug.cgi?id=61058)HTTP Request : Add option `httpclient4.deflate_relax_mode` to avoid "Unexpected end of ZLIB input stream" when deflating what seems to be invalid streams. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 43612](https://bz.apache.org/bugzilla/show_bug.cgi?id=43612)HTTP PUT does not honor request parameters. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 60190](https://bz.apache.org/bugzilla/show_bug.cgi?id=60190)Content-Type is added for `POST` unconditionally. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62462](https://bz.apache.org/bugzilla/show_bug.cgi?id=62462)[PR#387](https://github.com/apache/jmeter/pull/387)Make delegation of credentials in SPNEGO possible again. - [Bug 58807](https://bz.apache.org/bugzilla/show_bug.cgi?id=58807)`Reset SSL State on Thread Group iteration only (was https.use.cached.ssl.context=false` is broken) - [Bug 62716](https://bz.apache.org/bugzilla/show_bug.cgi?id=62716)When Recording, JMeter removes Authorization from generated Header Manager when using Bearer Token #### Other Samplers - [Bug 62235](https://bz.apache.org/bugzilla/show_bug.cgi?id=62235)Java 9 - illegal reflective access by org.apache.jmeter.util.HostNameSetter - [Bug 62464](https://bz.apache.org/bugzilla/show_bug.cgi?id=62464)Set start- and end-time on JMS publisher sampler, even if initialization fails. - [Bug 62616](https://bz.apache.org/bugzilla/show_bug.cgi?id=62616)FTPSampler: Upload file-size is not counted in sentBytes #### Controllers - [Bug 62265](https://bz.apache.org/bugzilla/show_bug.cgi?id=62265)ModuleController behaves strangely #### Listeners - [Bug 62097](https://bz.apache.org/bugzilla/show_bug.cgi?id=62097)Update JTable in Aggregate Report only when new data has arrived. That way selections of rows will be kept longer around. - [Bug 62203](https://bz.apache.org/bugzilla/show_bug.cgi?id=62203)Influxdb BackendListener client: store user tags to annotation and internal transaction. Contributed by Sergey Batalin (sergey_batalin at mail.ru) - [Bug 62251](https://bz.apache.org/bugzilla/show_bug.cgi?id=62251)TextGraphiteMetricsSender does not invalidate lost connections in case of network errors - [Bug 60705](https://bz.apache.org/bugzilla/show_bug.cgi?id=60705)Fix headers of Aggregate Reports and friends when columns are moved around. - [Bug 62463](https://bz.apache.org/bugzilla/show_bug.cgi?id=62463)Distributed client/server setup: use different RMI ports for the remote objects when using SSL #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61664](https://bz.apache.org/bugzilla/show_bug.cgi?id=61664)HTTP Authorization Manager : Digest works only with legacy [RFC 2069](https://tools.ietf.org/html/2069), [RFC 2617](https://tools.ietf.org/html/2617) is not implemented. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62252](https://bz.apache.org/bugzilla/show_bug.cgi?id=62252)HTTP header merging logic does not correspond to the documentation - [Bug 62554](https://bz.apache.org/bugzilla/show_bug.cgi?id=62554)BoundaryExtractor : Field to check is not reset - [Bug 62553](https://bz.apache.org/bugzilla/show_bug.cgi?id=62553)Random element might return same value even if property "Per thread user (User)" is set to TRUE - [Bug 62637](https://bz.apache.org/bugzilla/show_bug.cgi?id=62637)Take scheduler into account when calcuting delay for Synchronizing Timer #### Functions #### I18N - [Bug 62310](https://bz.apache.org/bugzilla/show_bug.cgi?id=62310)French translation of Precise Throughput Timer label #### Report / Dashboard - [Bug 62333](https://bz.apache.org/bugzilla/show_bug.cgi?id=62333)Report Dashboard - When one series contains no value, the graph colors logic is wrong. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62283](https://bz.apache.org/bugzilla/show_bug.cgi?id=62283)Report Dashboard - Date is not correctly displayed on chart when granularity is ≤ 1 day - [Bug 62520](https://bz.apache.org/bugzilla/show_bug.cgi?id=62520)The tool-tip text when we hover on the point in 'Latency Vs Request' graph should be 'Median Latency' #### Documentation - [Bug 62211](https://bz.apache.org/bugzilla/show_bug.cgi?id=62211)Fix HTTP Request Server Documentation. Contributed by Ori Marko (orimarko at gmail.com) - [PR#388](https://github.com/apache/jmeter/pull/388)Fix a typo. Contributed by Giancarlo Romeo (giancarloromeo at gmail.com) #### General - [Bug 62107](https://bz.apache.org/bugzilla/show_bug.cgi?id=62107)JMeter fails to start under Windows when `JM_LAUNCH` contains spaces - [Bug 62110](https://bz.apache.org/bugzilla/show_bug.cgi?id=62110)A broken JUnit class (due to missing dependency) breaks JMeter menus. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#377](https://github.com/apache/jmeter/pull/377)Small fix of the docs. Contributed by Peter Doornbosch (peter.doornbosch at luminis.eu) - [Bug 62124](https://bz.apache.org/bugzilla/show_bug.cgi?id=62124)Recording templates : Add more exclusions and use Transaction Name by default - [Bug 62127](https://bz.apache.org/bugzilla/show_bug.cgi?id=62127)Store filename as String instead of File in FileEditor. This will prevent conversion of filenames from Unix style path separators to Windows style when used for example in CSV Data Set Config. - [Bug 56150](https://bz.apache.org/bugzilla/show_bug.cgi?id=56150)Keep the index right, when scrolling through the menu items. - [Bug 62240](https://bz.apache.org/bugzilla/show_bug.cgi?id=62240)If SampleMonitor implementation is a TestBean if will not be initialized correctly - [Bug 62295](https://bz.apache.org/bugzilla/show_bug.cgi?id=62295)Correct order of elements when duplicating a selection of multiple elements. - [Bug 62397](https://bz.apache.org/bugzilla/show_bug.cgi?id=62397)Don't break lines at commata when using JSON Path Tester - [Bug 62281](https://bz.apache.org/bugzilla/show_bug.cgi?id=62281)Prevent NPE in MapProperty. Patch by belugabehr (dam6923 at gmail.com) - [Bug 62457](https://bz.apache.org/bugzilla/show_bug.cgi?id=62457)In usermanual, the UUID Function's example is wrong. Contributed by helppass (onegaicimasu at hotmail.com) - [Bug 62478](https://bz.apache.org/bugzilla/show_bug.cgi?id=62478)Escape commata in parameters when constructing function strings in the GUI function helper. Reported by blue414 (blue414 at 163.com) - [Bug 62463](https://bz.apache.org/bugzilla/show_bug.cgi?id=62463)Fix usage of ports, when `client.rmi.localport` is set for distributed runs. - [Bug 62545](https://bz.apache.org/bugzilla/show_bug.cgi?id=62545)Don't use a colon as part of the "tab" string when indenting JSON in RenderAsJSON. - Part of [Bug 62637](https://bz.apache.org/bugzilla/show_bug.cgi?id=62637) Avoid Integer overrun when dealing with very large values in `TimerService#adjustDelay` - [Bug 62683](https://bz.apache.org/bugzilla/show_bug.cgi?id=62683)Error dialog has no text when user opens completely invalid test plan. ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Graham Russell (graham at ham1.co.uk) - Ori Marko (orimarko at gmail.com) - Davide Angelocola (davide.angelocola at fisglobal.com) - [Ubik Load Pack](https://ubikloadpack.com) - Olaf Flebbe (oflebbe at apache.org) - Peter Doornbosch (peter.doornbosch at luminis.eu) - logox01 (logox01 at gmx.at) - Sergey Batalin (sergey_batalin at mail.ru) - [XMeter](https://www.xmeter.net) - Imane Ankhila (iankhila at ahlane.net) - jffagot05 (jffagot05 at gmail.com) - Perze Ababa (perze.ababa at gmail.com) - Martha Laks (laks.martha at gmail.com) - Logan Mauzaize (t524467 at airfrance.fr) - belugabehr (dam6923 at gmail.com) - Giancarlo Romeo (giancarloromeo at gmail.com) - helppass (onegaicimasu at hotmail.com) - blue414 (blue414 at 163.com) - Aaron Levin - Allen (444104595 at qq.com) - Felipe Cuozzo (felipe.cuozzo at gmail.com) - bangnab (ambrosetti.nicola at gmail.com) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Known problems and workarounds - View Results Tree may freeze rendering large response particularly if this response has no spaces, see [Bug 60816](https://bz.apache.org/bugzilla/show_bug.cgi?id=60816). This is due to an identified Java Bug [UI stuck when calling `JEditorPane.setText()` or `JTextArea.setText()` with long text without space](https://bugs.openjdk.java.net/browse/JDK-8172336). - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 4.0 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ### Core improvements JMeter now supports JAVA 9. New [`Boundary Extractor`](/usermanual/component-reference/#Boundary_Extractor) element available which provides easy extraction with better performances ![changes/4.0/boundary_extractor.png](/images/screenshots/changes/4.0/boundary_extractor.png) New [`JSON Assertion`](/usermanual/component-reference/#JSON_Assertion) element available to assert on JSON responses. ![changes/4.0/json_assertion.png](/images/screenshots/changes/4.0/json_assertion.png) New [`Precise Throughput Timer`](/usermanual/component-reference/#Precise_Throughput_Timer) element available which produces Poisson arrivals with given constant throughput. ![changes/4.0/precise_throughput_timer.png](/images/screenshots/changes/4.0/precise_throughput_timer.png) JMS Point-to-Point sampler has been enhanced with `read`, `browse`, `clear` options. ![changes/4.0/jmsptp_communication_styles.png](/images/screenshots/changes/4.0/jmsptp_communication_styles.png) Best property values are now selected on many Test Elements to ensure best practices are the defaults: - Newly added `If Controller` now uses by default Expression which is the most performing option. ![changes/4.0/if_controller_condition.png](/images/screenshots/changes/4.0/if_controller_condition.png) ![changes/4.0/if_controller_expression.png](/images/screenshots/changes/4.0/if_controller_expression.png) - Newly added JSR223 Test Element now cache compiled script by default if language used provides this feature. ![changes/4.0/jsr223_cache_compilation.png](/images/screenshots/changes/4.0/jsr223_cache_compilation.png) [`Loop controller`](/usermanual/component-reference/#Loop_Controller) and [`ForEach Controller`](/usermanual/component-reference/#ForEach_Controller) now expose their current iteration as a variable named `__jm__<Name of your element>__idx` that you can use like this for example for a Loop Controller named `MyLoopController`: ```bash \${__jm__MyLoopController__idx} ``` . See [Bug 61802](https://bz.apache.org/bugzilla/show_bug.cgi?id=61802) Cookies are now shown in View Results Tree during recording. They were previously always shown as empty. [`Response Assertion`](/usermanual/component-reference/#Response_Assertion) now allows you to customize assertion message and assert on Request Data. ![changes/4.0/response_assertion_enhancements.png](/images/screenshots/changes/4.0/response_assertion_enhancements.png) ### UX improvements JMeter now uses [Darcula LAF](https://github.com/bulenkov/Darcula) by default Workbench has been dropped from UI, you can now use Non Test Elements as immediate children of Test Plan. ![changes/4.0/goodbye_workbench.png](/images/screenshots/changes/4.0/goodbye_workbench.png) Menu UX have been improved to make most used elements available more rapidly. ![changes/4.0/menu_organization.png](/images/screenshots/changes/4.0/menu_organization.png) HTTP(S) Test Script Recorder now allows you to name your transactions while recording in a more human readable way. ![changes/4.0/recorder_naming_samplers.png](/images/screenshots/changes/4.0/recorder_naming_samplers.png) UX improvements made on, among the most notable : - Module Controller informs user at least one Controller is required - Function Helper Dialog (The wizard that helps using and testing functions) has been improved in many fields. ![changes/4.0/function_helper_dialog_enhancements.png](/images/screenshots/changes/4.0/function_helper_dialog_enhancements.png) - Switch Controller trims text to avoid issues when a space is introduced before/after name - Test Plan is now saved before running the test plan ### Functions New Function [`__digest`](/usermanual/functions/#__digest) provides easy computing of SHA-XXX, MDX hashes: ```bash \${__digest(MD5,Apache JMeter 4.0 rocks !,,,)} ``` will return `0e16c3ce9b6c9971c69ad685fd875d2b` New Function [`__dateTimeConvert`](/usermanual/functions/#__dateTimeConvert) provides easy conversion between date formats: ```bash \${__dateTimeConvert(01 Jan 2017,dd MMM yyyy,dd/MM/yyyy,)} ``` will return `01/01/2017` New Function [`__changeCase`](/usermanual/functions/#__changeCase) provides ability to switch to Upper / Lower / Capitalized cases ```bash \${__changeCase(Avaro omnia desunt\, inopi pauca\, sapienti nihil,UPPER,)} ``` will return `AVARO OMNIA DESUNT, INOPI PAUCA, SAPIENTI NIHIL` New Functions [`__isVarDefined`](/usermanual/functions/#__isVarDefined) and [`__isPropDefined`](/usermanual/functions/#__isPropDefined) provide testing of properties and variables availability ```bash \${__isPropDefined(START.HMS)} ``` will return `true` ```bash \${__isVarDefined(JMeterThread.last_sample_ok)} ``` will return `true` ### Scripting and Plugin Development You can now call `SampleResult#setIgnore()` if you don't want your sampler to be visible in results `JavaSamplerContext` used by `AbstractJavaSamplerClient` has been enhanced with new methods to easy plugin development. JMeter now distributes additional Maven sources and javadoc artifacts into [Maven repository](https://repo1.maven.org/maven2/org/apache/jmeter/ApacheJMeter_core/4.0/) Plugins can now register listeners to be notified when a Test Plan is opened/closed ### Live Reporting and Web Report InfluxDB backend listener now allows you to add custom tags by adding them with prefix `TAG_`, see [Bug 61794](https://bz.apache.org/bugzilla/show_bug.cgi?id=61794) In Web Report responseTime distribution graph is more precise Some bugfixes have been made on report generation, see [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900), [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900)61956, [Bug 61899](https://bz.apache.org/bugzilla/show_bug.cgi?id=61899). Graphs _Latency Vs Request_ and _Response Time Vs Request_ did not exceed 1000 RPS due to [Bug 61962](https://bz.apache.org/bugzilla/show_bug.cgi?id=61962) ### Configuration of JMeter environment JVM settings for the JMeter start scripts can be placed in a separate file (`bin/setenv.sh` on Unix and `bin\setenv.bat` on Windows), that gets called on startup. The startup script itself does not have to be edited anymore. ## Incompatible changes - `Start time` and `End date` of Thread Group have been removed, see [Bug 61549](https://bz.apache.org/bugzilla/show_bug.cgi?id=61549) - In distributed testing, mode `Hold` has been removed. Use alternative and more efficient modes - For 3rd party plugins, the following method in `org.apache.jmeter.gui.tree.JMeterTreeNode` has been dropped for migration to Java 9 ([Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529)) ```java public Enumeration<JMeterTreeNode> children() ``` - `tearDown Thread Group` will now run on stop and shutdown of a test by default. If you don't want this behaviour, uncheck `Run tearDown Thread Groups after shutdown of main threads` on `Test Plan` element, see [Bug 61656](https://bz.apache.org/bugzilla/show_bug.cgi?id=61656) - Properties `sampleresult.getbytes.headers_size` and `sampleresult.getbytes.body_real_size` have been dropped, see [Bug 61587](https://bz.apache.org/bugzilla/show_bug.cgi?id=61587) - JMeter will now save your test plan whenever you run it. This behaviour can be controlled by property `save_automatically_before_run`, see [Bug 61731](https://bz.apache.org/bugzilla/show_bug.cgi?id=61731) - Workbench element has been dropped, you now directly add `Non Test Element` as children of Test Plan. When loading a Test Plan that contains the element JMeter will move the `Mirror Server`, `Property Display` and HTTP(s) `Test Script Recorder` elements as direct children of Test Plan. For any other element, it will create a `Test Fragment` element called `Workbench Test Fragment and move the elements in it`. - Following classes have been dropped (`org.apache.jmeter.functions.util.ArgumentEncoder`, `org.apache.jmeter.functions.util.ArgumentDecoder`), see [PR#335](https://github.com/apache/jmeter/pull/335) - In JMS Point-to-Point sampler, setting timeout to 0 will now mean infinite timeout while previously it would be switched to 2000 ms, see [Bug 61829](https://bz.apache.org/bugzilla/show_bug.cgi?id=61829) - When Assertions are at different scopes, they are executed starting with the most OUTER one to the most INNER one. See [Bug 61846](https://bz.apache.org/bugzilla/show_bug.cgi?id=61846) - JMeter now starts by default using English locale. This change is due to missing translations in many supported languages. You can change locale by modifying in jmeter and jmeter.bat (or preferably setenv.sh/setenv.bat) the `JVM_ARGS` system property values. We'd also be very grateful if you can contribute translations in supported languages. - SwitchController now trims by default the content of switch to avoid issue related to unwanted spaces. See [Bug 61771](https://bz.apache.org/bugzilla/show_bug.cgi?id=61771) - JMeter JVM heap settings have changed from `-Xms512m -Xmx512m` to `-Xms1g -Xmx1g` - Beanshell version has been upgraded to bsh-2.0b6 which introduces breaking changes and more strict parsing rules ## Improvements #### HTTP Samplers and Test Script Recorder - [PR#316](https://github.com/apache/jmeter/pull/316)Warn about empty truststore loading. Contributed by Vincent Herilier (https://github.com/vherilier) - [Bug 61639](https://bz.apache.org/bugzilla/show_bug.cgi?id=61639)HTTP(S) Test Script Recorder: In request filtering tab, uncheck by default "Notify Child Listeners of filtered samplers" - [Bug 61672](https://bz.apache.org/bugzilla/show_bug.cgi?id=61672)HTTP(S) Test Script Recorder: Have the ability to choose the sampler name while keeping the ability to just add a prefix - [Bug 53957](https://bz.apache.org/bugzilla/show_bug.cgi?id=53957)HTTP Request: In Parameters tab, allow pasting of content coming from Firefox and Chrome (unparsed) - [Bug 61587](https://bz.apache.org/bugzilla/show_bug.cgi?id=61587)Drop properties `sampleresult.getbytes.headers_size` and `sampleresult.getbytes.body_real_size` - [Bug 61843](https://bz.apache.org/bugzilla/show_bug.cgi?id=61843)HTTP(S) Test Script Recorder: Add SAN to JMeter generated CA Certificate. Contributed by Matthew Buckett - [Bug 61901](https://bz.apache.org/bugzilla/show_bug.cgi?id=61901)Support for `https.cipherSuites` System property. Contributed by Jeremy Arnold (jeremy at arnoldzoo.org) #### Other samplers - [Bug 61544](https://bz.apache.org/bugzilla/show_bug.cgi?id=61544)JMS Point-to-Point Sampler: Enhance communication styles with read, browse, clear. Based on a contribution by Benny van Wijngaarden (benny at smaragd-it.nl) - [Bug 61829](https://bz.apache.org/bugzilla/show_bug.cgi?id=61829)JMS Point-to-Point: If Receive Queue is empty and a timeout is set, it is not taken into account. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61739](https://bz.apache.org/bugzilla/show_bug.cgi?id=61739)Java Request / JavaSamplerClient: Improve `org.apache.jmeter.protocol.java.sampler.JavaSamplerContext` - [Bug 61762](https://bz.apache.org/bugzilla/show_bug.cgi?id=61762)Start Next Thread Loop should be used everywhere #### Controllers - [Bug 61675](https://bz.apache.org/bugzilla/show_bug.cgi?id=61675)If Controller: Use expression by default and add a warning when the other mode is used. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61770](https://bz.apache.org/bugzilla/show_bug.cgi?id=61770)Module Controller: Inform user in UI that he needs to have at least one Controller in his plan. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61771](https://bz.apache.org/bugzilla/show_bug.cgi?id=61771)SwitchController: Switch field should be trimmed by safety #### Listeners - [Bug 57760](https://bz.apache.org/bugzilla/show_bug.cgi?id=57760)View Results Tree: Cookie Header is wrongly shown as empty (no cookies) when viewing a recorder Sample Result. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61769](https://bz.apache.org/bugzilla/show_bug.cgi?id=61769)View Results Tree: Use syntax highlighter in XPath Tester, JSON Path Tester and CSS/JQuery Tester. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61776](https://bz.apache.org/bugzilla/show_bug.cgi?id=61776)View Results Tree: Expansion of `Add expand/collapse all` menu in render XML view. Contributed by Maxime Chassagneux and Graham Russell - [Bug 61852](https://bz.apache.org/bugzilla/show_bug.cgi?id=61852)View Results Tree: Add a Boundary Extractor Tester - [Bug 61794](https://bz.apache.org/bugzilla/show_bug.cgi?id=61794)Influxdb backend: Add as many custom tags as wanted by just create new lines and prefix theirs name by "`TAG_`" on the GUI backend listener #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60213](https://bz.apache.org/bugzilla/show_bug.cgi?id=60213)New component: Boundary based extractor - [Bug 61845](https://bz.apache.org/bugzilla/show_bug.cgi?id=61845)New Component JSON Assertion based on AtlanBH JSON Path Assertion donated to JMeter-Plugins and migrated into JMeter core by Artem Fedorov (artem at blazemeter.com) - [Bug 61931](https://bz.apache.org/bugzilla/show_bug.cgi?id=61931)New Component: Precise Throughput Timer, timer that produces Poisson arrivals with given constant throughput. Contributed by Vladimir Sitnikov (sitnikov.vladimir at gmail.com) - [Bug 61644](https://bz.apache.org/bugzilla/show_bug.cgi?id=61644)HTTP Cache Manager: "Use Cache-Control/Expires header when processing GET requests" should be checked by default - [Bug 61645](https://bz.apache.org/bugzilla/show_bug.cgi?id=61645)Response Assertion: Add ability to assert on Request Data - [Bug 51140](https://bz.apache.org/bugzilla/show_bug.cgi?id=51140)Response Assertion: add ability to set a specific error/failure message that is later shown in the Assertion Result. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61534](https://bz.apache.org/bugzilla/show_bug.cgi?id=61534)Convert AssertionError to a failed assertion, allowing users to use assert in their code. Fixing a regression introduced in 3.2 - [Bug 61756](https://bz.apache.org/bugzilla/show_bug.cgi?id=61756)Extractors: Improve label name "Reference name" to make it clear what it makes - [Bug 61758](https://bz.apache.org/bugzilla/show_bug.cgi?id=61758)`Apply to:` field in Extractors, Assertions: When entering a value in `JMeter Variable Name`, the radio box `JMeter Variable Name` should be selected by default. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61846](https://bz.apache.org/bugzilla/show_bug.cgi?id=61846)Scoped Assertion should follow same order of evaluation as Post Processors #### Functions - [Bug 61724](https://bz.apache.org/bugzilla/show_bug.cgi?id=61724)Add `__digest` function to provide computing of Hashes (SHA-XXX, MDX). Based on a contribution by orimarko at gmail.com - [Bug 61735](https://bz.apache.org/bugzilla/show_bug.cgi?id=61735)Add `__dateTimeConvert` function to provide date formats conversions. Based on a contribution by orimarko at gmail.com - [Bug 61760](https://bz.apache.org/bugzilla/show_bug.cgi?id=61760)Add `__isPropDefined` and `__isVarDefined` functions to know if property or variable exist. Contributed by orimarko at gmail.com - [Bug 61759](https://bz.apache.org/bugzilla/show_bug.cgi?id=61759)Add `__changeCase` function to change different cases of a string. Based on a contribution by orimarko at gmail.com - [Bug 61561](https://bz.apache.org/bugzilla/show_bug.cgi?id=61561)Function helper dialog should display exception in result - [Bug 61738](https://bz.apache.org/bugzilla/show_bug.cgi?id=61738)Function Helper Dialog: Add Copy in Generate and clarify labels. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62027](https://bz.apache.org/bugzilla/show_bug.cgi?id=62027)Help: Introduce property `help.local` to allow choosing between local (offline) documentation and online documentation - [Bug 61593](https://bz.apache.org/bugzilla/show_bug.cgi?id=61593)Remove Detail, Add, Add from Clipboard, Delete buttons in Function Helper GUI #### I18N - [Bug 61606](https://bz.apache.org/bugzilla/show_bug.cgi?id=61606)Translate button `Browse…` in some elements (which use FileEditor class) - [Bug 61747](https://bz.apache.org/bugzilla/show_bug.cgi?id=61747)HTTP(S) Test Script Recorder: add the missing doc to "Create transaction after request (ms)" #### Report / Dashboard - [Bug 61871](https://bz.apache.org/bugzilla/show_bug.cgi?id=61871)Reduce jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity default value from 500ms to 100ms - [Bug 61879](https://bz.apache.org/bugzilla/show_bug.cgi?id=61879)Remove useless files in HTML report template #### General - [Bug 61591](https://bz.apache.org/bugzilla/show_bug.cgi?id=61591)Drop Workbench from test tree. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61549](https://bz.apache.org/bugzilla/show_bug.cgi?id=61549)Thread Group: Remove start and end date - [Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529)Migration to Java 9. Partly contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61709](https://bz.apache.org/bugzilla/show_bug.cgi?id=61709)SampleResult: Add a method `setIgnore()` to make JMeter ignore the SampleResult and not send it to listeners - [Bug 61806](https://bz.apache.org/bugzilla/show_bug.cgi?id=61806)Allow to use `SampleResult#setIgnore()` in post-processors and assertions script (JSR223 elements) - [Bug 61607](https://bz.apache.org/bugzilla/show_bug.cgi?id=61607)Add browse button in all BeanShell elements to select BeanShell script - [Bug 61627](https://bz.apache.org/bugzilla/show_bug.cgi?id=61627)Don't clear LogView anymore when clicking on Warning/Errors Indicator - [Bug 61629](https://bz.apache.org/bugzilla/show_bug.cgi?id=61629)Add Think Times to Children menu should not consider disabled elements - [Bug 61655](https://bz.apache.org/bugzilla/show_bug.cgi?id=61655)SampleSender: Drop HoldSampleSender implementation - [Bug 61656](https://bz.apache.org/bugzilla/show_bug.cgi?id=61656)`tearDown Thread Group` should run by default at stop or shutdown of test - [Bug 61659](https://bz.apache.org/bugzilla/show_bug.cgi?id=61659)`JMeterVariables#get()` should apply `toString()` on non string objects - [Bug 61555](https://bz.apache.org/bugzilla/show_bug.cgi?id=61555)Metaspace should be restricted as default - [Bug 61693](https://bz.apache.org/bugzilla/show_bug.cgi?id=61693)JMeter aware of Docker (`-XX:+UnlockExperimentalVMOptions` `-XX:+UseCGroupMemoryLimitForHeap`) - [Bug 61694](https://bz.apache.org/bugzilla/show_bug.cgi?id=61694)Add `-server` option in `jmeter.bat` - [Bug 61697](https://bz.apache.org/bugzilla/show_bug.cgi?id=61697)Introduce Darcula Look And Feel to make JMeter UI more attractive - [Bug 61704](https://bz.apache.org/bugzilla/show_bug.cgi?id=61704)Toolbar: Improve a bit the right part - [Bug 61731](https://bz.apache.org/bugzilla/show_bug.cgi?id=61731)Enhance Test plan Backup with option to save before run. Based on a contribution by orimarko at gmail.com - [Bug 61640](https://bz.apache.org/bugzilla/show_bug.cgi?id=61640)JSR223 Test Elements: Enable by default caching. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61785](https://bz.apache.org/bugzilla/show_bug.cgi?id=61785)Add **Help → Useful links** to create issues and download nightly build - [Bug 61808](https://bz.apache.org/bugzilla/show_bug.cgi?id=61808)Fix main frame position. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61802](https://bz.apache.org/bugzilla/show_bug.cgi?id=61802)Loop / ForEach Controller should expose a variable for current iteration. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#349](https://github.com/apache/jmeter/pull/349)Add i18n resources(zh_CN). Contributed by Helly Guo (https://github.com/hellyguo) - [PR#351](https://github.com/apache/jmeter/pull/351)Fixed about dialog position on first view. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#352](https://github.com/apache/jmeter/pull/352)Menu bar - added mnemonics to more menu items. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#353](https://github.com/apache/jmeter/pull/353)Re-wrote some existing tests in Spock. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61919](https://bz.apache.org/bugzilla/show_bug.cgi?id=61919)UX: Reorder Menus. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61920](https://bz.apache.org/bugzilla/show_bug.cgi?id=61920)Plugins: Add ability to listen to Test Plan loading/closing. Contributed by Peter Doornbosch (https://bitbucket.org/pjtr/) - [Bug 61935](https://bz.apache.org/bugzilla/show_bug.cgi?id=61935)Plugins: Let GUI component (dynamically) decide whether it can be added via the menu or not. Contributed by Peter Doornbosch (https://bitbucket.org/pjtr/) - [Bug 61969](https://bz.apache.org/bugzilla/show_bug.cgi?id=61969)When changing LAF through GUI, user should be informed that it is better to restart - [Bug 61970](https://bz.apache.org/bugzilla/show_bug.cgi?id=61970)JMeter now uses English as default locale to avoid missing translations in some locales make UI look weird - [Bug 56368](https://bz.apache.org/bugzilla/show_bug.cgi?id=56368)Create and Deploy source artifacts to Maven central - [Bug 61973](https://bz.apache.org/bugzilla/show_bug.cgi?id=61973)Create and Deploy javadoc artifacts to Maven central - [PR#371](https://github.com/apache/jmeter/pull/371)Fix example in documentation for [XPath Assertion](/user-manual/component-reference/#XPath_Assertion). Contributed by Konstantin Kalinin (kkalinin at hotmail.com) - [Bug 62039](https://bz.apache.org/bugzilla/show_bug.cgi?id=62039)Distributed testing: Provide ability to use SSL ## Non-functional changes - Updated to bsh-2.0b6 (from bsh-2.0b5) - Updated to groovy-all-2.4.13 (from groovy-all-2.4.12) - Updated to rhino-1.7.7.2 (from rhino-1.7.7.1) - Updated to tika-core and tika-parsers 1.17 (from 1.16) - Updated to commons-dbcp2-2.2.0 (from 2.1.1) - Updated to caffeine 2.6.1 (from 2.5.5) - Updated to commons-codec-1.11 (from 1.10) - Updated to commons-io-2.6 (from 2.5) - Updated to commons-lang3-3.7 (from 3.6) - Updated to commons-pool2-2.5.0 (from 2.4.2) - Updated to asm-6.0 (from 5.2) - Updated to jsoup-1.11.2 (from 1.10.3) - Updated to cglib-nodep-3.2.6 (from 3.2.5) - Updated to ph-css 6.0.0 (from 5.0.4) - Updated to ph-commons 9.0.0 (from 8.6.6) - Updated to log4j2 2.10.0 (from 2.8.2) - Updated to httpcore 4.4.9 (from 4.4.7) - Updated to httpclient 4.5.5 (from 4.5.3) - Updated to jodd 4.1.4 (from 3.8.6) - [Bug 61642](https://bz.apache.org/bugzilla/show_bug.cgi?id=61642)Improve FTP test coverage - [Bug 61641](https://bz.apache.org/bugzilla/show_bug.cgi?id=61641)Improve JMS test coverage - [Bug 61651](https://bz.apache.org/bugzilla/show_bug.cgi?id=61651)Improve TCP test coverage - [Bug 61651](https://bz.apache.org/bugzilla/show_bug.cgi?id=61651)Improve OS test coverage. Partly contributed by Aleksei Balan (abalanonline at gmail.com) - [PR#319](https://github.com/apache/jmeter/pull/319)Removed commented out code. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#322](https://github.com/apache/jmeter/pull/322)General JavaDoc cleanup. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#323](https://github.com/apache/jmeter/pull/323)Extracted method and used streams to improve readability. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#324](https://github.com/apache/jmeter/pull/324)Save backup refactor. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#327](https://github.com/apache/jmeter/pull/327)Utilising more modern Java, simplifying code and formatting code and comments. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#332](https://github.com/apache/jmeter/pull/332)Add the spock framework for groovy unit tests. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#334](https://github.com/apache/jmeter/pull/334)Enable running of JUnit tests from within IntelliJ with default config. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#335](https://github.com/apache/jmeter/pull/335)Removed `functions.util.*` as they don't seem to be used (for many years). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61867](https://bz.apache.org/bugzilla/show_bug.cgi?id=61867)[PR#345](https://github.com/apache/jmeter/pull/345)Updated to latest checkstyle (v8.5), Added many more rules to checkstyle, Included checking of test files and more file types. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#350](https://github.com/apache/jmeter/pull/350)Parallelised unit tests. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61966](https://bz.apache.org/bugzilla/show_bug.cgi?id=61966)Setup Test Results Analyzer in jenkins - [PR#343](https://github.com/apache/jmeter/pull/343)Reduce the size of some images in the documentation. Contributed by Graham Russell (graham at ham1.co.uk) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 61569](https://bz.apache.org/bugzilla/show_bug.cgi?id=61569)JMS Point-to-Point Test Plan: Synchronization issue when putting reply. Contributed by Igor Panainte (panainte.i at gmail.com) #### Other Samplers - [Bug 61698](https://bz.apache.org/bugzilla/show_bug.cgi?id=61698)Test Action: It stop is selected, samplers following Test Action can run - [Bug 61707](https://bz.apache.org/bugzilla/show_bug.cgi?id=61707)Test Action: Target is ignored when pause is selected, so it should be disabled - [Bug 61827](https://bz.apache.org/bugzilla/show_bug.cgi?id=61827)JMSPublisher: Don't add new line at the end of the file. Contributed by Graham Russell (graham at ham1.co.uk) #### Controllers - [Bug 61556](https://bz.apache.org/bugzilla/show_bug.cgi?id=61556)Clarify in documentation performance impacts of `\${}` var usage in IfController and groovy. Contributed by Justin McCartney (be_strew at yahoo.co.uk) - [Bug 61713](https://bz.apache.org/bugzilla/show_bug.cgi?id=61713)Test Fragment has option to Change Controller and Insert Parent. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61965](https://bz.apache.org/bugzilla/show_bug.cgi?id=61965)Module and Include Controller should not allow to add meaningless elements in their context. - [Bug 62062](https://bz.apache.org/bugzilla/show_bug.cgi?id=62062)ThroughputController: StackOverFlowError triggered when throughput=0 (Total Executions or Percentage Executions) Partly implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter Ltd. #### Listeners - [Bug 61742](https://bz.apache.org/bugzilla/show_bug.cgi?id=61742)BackendListener: fix default value for `backend_graphite.send_interval` - [Bug 61878](https://bz.apache.org/bugzilla/show_bug.cgi?id=61878)BackendListener: NPE if BackendListenerClient#getDefaultParameters returns null - [Bug 61950](https://bz.apache.org/bugzilla/show_bug.cgi?id=61950)View Results Tree: Content-Type `audio/mpegurl` is wrongly considered as binary #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61716](https://bz.apache.org/bugzilla/show_bug.cgi?id=61716)Header Manager: When pasting Headers from Firefox or Chrome spaces are introduced as first character of value #### Functions - [Bug 61588](https://bz.apache.org/bugzilla/show_bug.cgi?id=61588)Better log message for [__RandomDate()](/user-manual/functions/#__RandomDate__) function - [Bug 61619](https://bz.apache.org/bugzilla/show_bug.cgi?id=61619)In Function Helper Dialog, the 1st function doesn't display default parameters - [Bug 61628](https://bz.apache.org/bugzilla/show_bug.cgi?id=61628)If split string has empty separator default separator is not used - [Bug 61752](https://bz.apache.org/bugzilla/show_bug.cgi?id=61752)`__RandomDate`: Function does not allow missing last parameter used for variable name #### I18N #### Report / Dashboard - [Bug 61807](https://bz.apache.org/bugzilla/show_bug.cgi?id=61807)Web Report: fix error in `getTop5ErrorMetrics`. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900)Report Generator: Report generation fails if separator is a regex reserved char like `|` - [Bug 61925](https://bz.apache.org/bugzilla/show_bug.cgi?id=61925)CsvSampleReader does not increment row in nextSample(). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61956](https://bz.apache.org/bugzilla/show_bug.cgi?id=61956)Report Generation: `-f` of `-forceDeleteResultFile` option does not work. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61899](https://bz.apache.org/bugzilla/show_bug.cgi?id=61899)Report Generation: When `jmeter.save.saveservice.print_field_names` is false and `sample_variables` are set report generation fails. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61962](https://bz.apache.org/bugzilla/show_bug.cgi?id=61962)Latency Vs Request and Response Time Vs Request graphs do not exceed 1000 RPS. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 61661](https://bz.apache.org/bugzilla/show_bug.cgi?id=61661)Avoid startup/shutdown problems due to 3rd party Thread Listener plugins throwing RuntimeException - [Bug 61625](https://bz.apache.org/bugzilla/show_bug.cgi?id=61625)File Editor used in BeanInfo behaves strangely under all LAFs with impact on CSVDataSet, JSR223, BSF, Beanshell Element - [Bug 61844](https://bz.apache.org/bugzilla/show_bug.cgi?id=61844)Maven pom.xml: Libraries used in testing should have scope test - [Bug 61842](https://bz.apache.org/bugzilla/show_bug.cgi?id=61842)Saving with no changes causes a save and duplicate, identical backup file ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Igor Panainte (panainte.i at gmail.com) - Emilian Bold (emi at apache.org) - [Ubik Load Pack](https://ubikloadpack.com) - Justin McCartney (be_strew at yahoo.co.uk) - Vincent Herilier (https://github.com/vherilier) - Aleksei Balan (abalanonline at gmail.com) - Graham Russell (graham at ham1.co.uk) - orimarko at gmail.com - Artem Fedorov (artem at blazemeter.com) - [BlazeMeter Ltd](https://www.blazemeter.com) - Benny van Wijngaarden (benny at smaragd-it.nl) - Matthew Buckett (https://github.com/buckett) - Helly Guo (https://github.com/hellyguo) - Peter Doornbosch (https://bitbucket.org/pjtr/) - Jeremy Arnold (jeremy at arnoldzoo.org) - Vladimir Sitnikov (sitnikov.vladimir at gmail.com) - Konstantin Kalinin (kkalinin at hotmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - user7294900 on Stackoverflow (orimarko at gmail.com) Apologies if we have omitted anyone else. ## Known problems and workarounds - View Results Tree may freeze rendering large response particularly if this response has no spaces, see [Bug 60816](https://bz.apache.org/bugzilla/show_bug.cgi?id=60816). This is due to an identified Java Bug [UI stuck when calling `JEditorPane.setText()` or `JTextArea.setText()` with long text without space](https://bugs.openjdk.java.net/browse/JDK-8172336). - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 3.3 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy :::note JMeter does not yet support JAVA 9, next JMeter version will support it, you can help and follow progress on this item in [Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529). ::: :::note Using last minor version of JAVA 8 is advised to avoid facing any JDK bug. ::: ### Core improvements HTTP Sampler now supports Brotli decompression. CacheManager now completely supports Vary header. InfluxDB BackendListener now supports sending results to InfluxDB through UDP protocol. ![changes/3.3/influxdb_udp.png](/images/screenshots/changes/3.3/influxdb_udp.png) It has also been enhanced to send number of errors by response code and message for each transaction TCP Sampler now computes latency, see [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156) Upgraded dependencies to last available versions bringing performance improvements and bug fixes Continued to improve the quality of our code and tests coverage. See [Quality report](https://builds.apache.org/analysis/overview?id=12927) ### UX improvements More work has been done to better support HiDPI. Some bugs, that crept in with the work on lowering the memory usage of View Results Tree, were fixed. The constant `DEFAULT_IMPLEMENTATION` was removed from CookieManager, as it lost it purpose with the removal of the alternate HTTP Client implementation in the last release JDBC Sampler UX has been improved by adding select boxes for drivers and validation queries. ![changes/3.3/jdbc_config_validation_driver_url.png](/images/screenshots/changes/3.3/jdbc_config_validation_driver_url.png) ![changes/3.3/jdbc_config_validation_query.png](/images/screenshots/changes/3.3/jdbc_config_validation_query.png) If Controller and While Controller UX have been improved ![changes/3.3/jmeter_if_controller.png](/images/screenshots/changes/3.3/jmeter_if_controller.png) ### Report/Dashboard improvements A new Help menu item has been added to simplify configuration of report generation. ![changes/3.3/jmeter_export_transactions_menu.png](/images/screenshots/changes/3.3/jmeter_export_transactions_menu.png) ![changes/3.3/jmeter_export_transactions_result.png](/images/screenshots/changes/3.3/jmeter_export_transactions_result.png) ### Documentation improvements Incorporated feedback about unclear documentation. ### Functions Function Helper Dialog: a new field that shows execution result has been added. ![changes/3.3/jmeter_function_result.png](/images/screenshots/changes/3.3/jmeter_function_result.png) New functions: - `[__timeShift](/user-manual/functions/#__timeShift)` - return a date in various formats with the specified amount of seconds/minutes/hours/days added. ![changes/3.3/jmeter_function_add_time.png](/images/screenshots/changes/3.3/jmeter_function_add_time.png) - `[__RandomDate](/user-manual/functions/#__RandomDate)` - generate random date within a specific date range. ![changes/3.3/jmeter_function_random_date.png](/images/screenshots/changes/3.3/jmeter_function_random_date.png) ## Incompatible changes - In InfluxDbBackendListenerClient, `statut` property has been renamed to `status` - In CookieManager, `DEFAULT_POLICY` and `DEFAULT_IMPLEMENTATION` constants are now private. :::note If you're using `ignorecookies` with HC3CookieHandler (< JMeter 3.1) configuration will be reset, ensure you put it back. ::: - JMeter will not truncate anymore by default responses exceeding 10 MB. If you want to enable this truncation, see property `httpsampler.max_bytes_to_store_per_request` - `org.apache.jmeter.protocol.tcp.sampler.TCPClient.read(InputStream)` has been deprecated in favor or org.apache.jmeter.protocol.tcp.sampler.TCPClient.read(InputStream, SampleResult), ensure you update your implementation to be able to compute latency, see [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156) #### Removed elements or functions - `_StringFromFile` function has been dropped, use `[__StringFromFile](/user-manual/functions/#__StringFromFile)` instead ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 61056](https://bz.apache.org/bugzilla/show_bug.cgi?id=61056)HTTP : Support brotli decoding - [Bug 61135](https://bz.apache.org/bugzilla/show_bug.cgi?id=61135)CookieManager : Drop Implementation select box and cleanup class - [Bug 61492](https://bz.apache.org/bugzilla/show_bug.cgi?id=61492)HTTP(S) Test Script Recorder : Add the possibility to change the value of proxy.pause in the GUI #### Other samplers - [Bug 61320](https://bz.apache.org/bugzilla/show_bug.cgi?id=61320)Test Action : Set duration to `0` by default - [Bug 61504](https://bz.apache.org/bugzilla/show_bug.cgi?id=61504)JDBC Connection Configuration : Set Max Number of Connections to `0` by default - [Bug 61505](https://bz.apache.org/bugzilla/show_bug.cgi?id=61505)JDBC Connection Configuration : Set "Validation Query" to `empty` by default to use `isValid` method of JDBC driver - [Bug 61506](https://bz.apache.org/bugzilla/show_bug.cgi?id=61506)JDBC Connection Configuration : Add a list for main databases validation queries for "Validation Query" attribute - [Bug 61507](https://bz.apache.org/bugzilla/show_bug.cgi?id=61507)JDBC Connection Configuration : Add a list for main databases JDBC driver class name for "JDBC Driver class" attribute - [Bug 61525](https://bz.apache.org/bugzilla/show_bug.cgi?id=61525)OS Process Sampler : Add browser button to Command and Working directory fields - [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156)TCPSampler : Latency is not measured for TCP Sampler. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61039](https://bz.apache.org/bugzilla/show_bug.cgi?id=61039)CSV data set config : Add browser button to Filename field - [Bug 61527](https://bz.apache.org/bugzilla/show_bug.cgi?id=61527)CSV data set config : Add a list for main file encoding values for File encoding attribute #### Controllers - [Bug 61131](https://bz.apache.org/bugzilla/show_bug.cgi?id=61131)IfController and WhileController : Improve UX #### Listeners - [Bug 61167](https://bz.apache.org/bugzilla/show_bug.cgi?id=61167)InfluxdbBackendListener : add number of errors by response code and message for each transaction - [Bug 61068](https://bz.apache.org/bugzilla/show_bug.cgi?id=61068)Introduce property `resultcollector.action_if_file_exists` to control the popup "File already exists" when starting a test - [Bug 61457](https://bz.apache.org/bugzilla/show_bug.cgi?id=61457)InfluxDB backend listener client : Support sending result to InfluxDB through UDP protocol. Partly based on [PR#302](https://github.com/apache/jmeter/pull/302) by Junlong Wu (github id mybreeze77) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61176](https://bz.apache.org/bugzilla/show_bug.cgi?id=61176)[PR#298](https://github.com/apache/jmeter/pull/298) Cache responses that have `vary` header in the `CacheManager`. #### Functions - [Bug 61040](https://bz.apache.org/bugzilla/show_bug.cgi?id=61040)Add a time shifting function - [Bug 61126](https://bz.apache.org/bugzilla/show_bug.cgi?id=61126)Function Helper Dialog : Add a field that shows execution result - [Bug 61508](https://bz.apache.org/bugzilla/show_bug.cgi?id=61508)Add a random date within a specific date range function #### I18N - [Bug 61509](https://bz.apache.org/bugzilla/show_bug.cgi?id=61509)Better label/translation/documentation for labels start and max for Counter element #### Report / Dashboard - [Bug 61481](https://bz.apache.org/bugzilla/show_bug.cgi?id=61481)Help Menu Item to export transaction for Web report #### General - When looking for classes in `ActionRouter`, fall back to location of the jar, where `ActionRouter` is loaded from. Provided by Emilian Bold (emi at apache.org) - [Bug 61510](https://bz.apache.org/bugzilla/show_bug.cgi?id=61510)Set 'Max Number of Connections' to `0` into 'JDBC Connection Configuration' for the 'JDBC Load Test template' - [Bug 61399](https://bz.apache.org/bugzilla/show_bug.cgi?id=61399)Make some bin and extras scripts Shellcheck compatible. Contributed by Wolfgang Wagner (internetwolf2000 at hotmail.com) ## Non-functional changes - Updated to groovy 2.4.12 (from 2.4.10) - Updated to caffeine 2.5.5 (from 2.4.0) - Updated to commons-jexl3 3.1 (from 3.0) - Updated to ph-css 5.0.4 (from 5.0.3) - Updated to ph-commons 8.6.6 (from 8.6.0) - Updated to log4j2 2.8.2 (from 2.8.1) - Updated to xmlgraphics-commons 2.2 (from 2.1) - Updated to jodd 3.8.6 (from 3.8.1) - Updated to xstream 1.4.10 (from 1.4.9) - Updated to Apache Tika 1.16 (from 1.14) - Updated to jsoup-1.10.3 (from 1.10.2) - Updated to commons-lang3 3.6 (from 3.5) - Updated to json-path 2.4.0 (from 2.2.0) - Updated to httpcore 4.4.7 (from 4.4.6) - [Bug 61438](https://bz.apache.org/bugzilla/show_bug.cgi?id=61438)Change the cryptographic signature of packages from sha-1 to sha-512 ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 61384](https://bz.apache.org/bugzilla/show_bug.cgi?id=61384)Don't set the charset on enclosing `multipart/form-data` header. It irritates some servers. The charset was added sometime back while refactoring to use a newer API of http client. See [Bug 56141](https://bz.apache.org/bugzilla/show_bug.cgi?id=56141) for more info. - [Bug 61456](https://bz.apache.org/bugzilla/show_bug.cgi?id=61456)`java.lang.ArrayIndexOutOfBoundsException` when recording with JMeter and weird Basic Auth Authorization header - [Bug 61395](https://bz.apache.org/bugzilla/show_bug.cgi?id=61395)Large server response truncation can impact recording #### Other Samplers - [Bug 60889](https://bz.apache.org/bugzilla/show_bug.cgi?id=60889)JMeter JDBC sample calls `SELECT USER()` when testing with MySQL JDBC due to `Connection#toString` call for response headers. - [Bug 61259](https://bz.apache.org/bugzilla/show_bug.cgi?id=61259)JDBC Request : since JMeter 3.0, when JDBC auto-commit is `false`, a rollback statement happens each time a Request is executed. Partly contributed by Liu XP (liu_xp2003 at sina.com) - [Bug 61319](https://bz.apache.org/bugzilla/show_bug.cgi?id=61319)Fix regression: SMTP Sampler could not send mails, when no attachments were specified. #### Controllers - [Bug 61375](https://bz.apache.org/bugzilla/show_bug.cgi?id=61375)Use system DNS resolver as last resort, when resolving entries in the static host table. #### Listeners - [Bug 61005](https://bz.apache.org/bugzilla/show_bug.cgi?id=61005)View Results Tree - Browser Response Data is not clearing - [Bug 61121](https://bz.apache.org/bugzilla/show_bug.cgi?id=61121)InfluxdbBackendListenerClient: Only all percentiles are sent, not `KO` and `OK` - [Bug 60961](https://bz.apache.org/bugzilla/show_bug.cgi?id=60961)Try to keep status of selected and expanded elements in View Results Tree when new elements are added. - [Bug 61198](https://bz.apache.org/bugzilla/show_bug.cgi?id=61198)Backend Listener does not work properly in main script when included scripts also contain Backend Listener - [Bug 61493](https://bz.apache.org/bugzilla/show_bug.cgi?id=61493)Max/Min threads are interchanged in Graphite and InfluxDB backend listener #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58743](https://bz.apache.org/bugzilla/show_bug.cgi?id=58743)[PR#293](https://github.com/apache/jmeter/pull/293) TableEditor can't be saved, when using two or more instances. Bugfix provided by Emilian Bold (emi at apache.org) - [Bug 61314](https://bz.apache.org/bugzilla/show_bug.cgi?id=61314)HTTP URL Re-writing Modifier doesn't replace existing `jsessionid` in http sampler, but adds it to the end - [Bug 61336](https://bz.apache.org/bugzilla/show_bug.cgi?id=61336)BeanShell Assertion : mistake in Chinese translation #### Functions - [Bug 61258](https://bz.apache.org/bugzilla/show_bug.cgi?id=61258)StringFromFile function is mentioned twice in the Function helper dialog - [Bug 61260](https://bz.apache.org/bugzilla/show_bug.cgi?id=61260)`[__XPath](/user-manual/functions/#__XPath)` function returns null despite XPath checker founds matches - [Bug 58876](https://bz.apache.org/bugzilla/show_bug.cgi?id=58876)TestPlanName function returns `null` for a newly saved Test Plan and uses previously opened one for a new one #### I18N #### Report / Dashboard - [Bug 61129](https://bz.apache.org/bugzilla/show_bug.cgi?id=61129)Report/Dashboard : If response code is empty but a `failureMessage` is present, Errors and Top 5 Errors are not accurate. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61151](https://bz.apache.org/bugzilla/show_bug.cgi?id=61151)Report/Dashboard : Top 5 Errors by Sampler and Errors : If assertion contains html code, the html part is hidden #### General - [Bug 60743](https://bz.apache.org/bugzilla/show_bug.cgi?id=60743)Stopping / Shutting down Test might create a deadlock due to HTTPCORE-446, fixed by HttpCore upgrade to 4.4.7 - [Bug 60994](https://bz.apache.org/bugzilla/show_bug.cgi?id=60994)Fix some typo in comments or log messages. [PR#289](https://github.com/apache/jmeter/pull/289) and [PR#290](https://github.com/apache/jmeter/pull/290) - [Bug 61011](https://bz.apache.org/bugzilla/show_bug.cgi?id=61011)Replace occurrences count is not correct (Path and Host replacement are counted twice) - [Bug 61026](https://bz.apache.org/bugzilla/show_bug.cgi?id=61026)Cannot run program "keytool": CreateProcess error=2 when starting JMeter 3.2 in GUI mode - [Bug 61054](https://bz.apache.org/bugzilla/show_bug.cgi?id=61054)Endless loop in `JOrphanUtils#replaceAllWithRegex` when regex is contained in replacement - [Bug 60995](https://bz.apache.org/bugzilla/show_bug.cgi?id=60995)HTTP Test Script Recorder: Port field is very small under some L&F - [Bug 61073](https://bz.apache.org/bugzilla/show_bug.cgi?id=61073)HTTP(S) Test Script Recorder panel have some fields with bad size on HiDPI screen or GTK+ L&F on Linux/XWayland - [Bug 57958](https://bz.apache.org/bugzilla/show_bug.cgi?id=57958)Fix transaction sample not generated if thread stops/restarts. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61050](https://bz.apache.org/bugzilla/show_bug.cgi?id=61050)Handle uninitialized RessourceBundle more gracefully, when calling `JMeterUtils#getResString`. - [Bug 61100](https://bz.apache.org/bugzilla/show_bug.cgi?id=61100)Invalid GC Log Filename on Windows - [Bug 57962](https://bz.apache.org/bugzilla/show_bug.cgi?id=57962)Allow to use variables (from User Defined Variables only) in all listeners in worker node mode - [Bug 61270](https://bz.apache.org/bugzilla/show_bug.cgi?id=61270)Fixed width fonts too small in text areas to read under HiDPI (user manual bug) - [Bug 61292](https://bz.apache.org/bugzilla/show_bug.cgi?id=61292)Make processing of samples in reporter more robust. - [Bug 61359](https://bz.apache.org/bugzilla/show_bug.cgi?id=61359)When cutting an element from Tree, Test plan is not marked as dirty - [Bug 61380](https://bz.apache.org/bugzilla/show_bug.cgi?id=61380)JMeter shutdown using timers releases thundering herd of interrupted samplers - [Bug 57055](https://bz.apache.org/bugzilla/show_bug.cgi?id=57055)CheckDirty.doAction should clear previousGuiItems for `SUB_TREE_SAVED` ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Anass Benomar (abenomar at umanis.com, Mithrandir0407 at github) - Anthony Kearns (anthony.kearns atrightside.co) - Emilian Bold (emi at apache.org) - Liu XP (liu_xp2003 at sina.com) - [Ubik Load Pack](http://ubikloadpack.com) - Wolfgang Wagner (internetwolf2000 at hotmail.com) - Junlong Wu (github id mybreeze77) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Liu XP (liu_xp2003 at sina.com) - Alexander Podelko (apodelko at yahoo.com) Apologies if we have omitted anyone else. ## Known problems and workarounds - View Results Tree may freeze rendering large response particularly if this response has no spaces, see [Bug 60816](https://bz.apache.org/bugzilla/show_bug.cgi?id=60816). This is due to an identified Java Bug [UI stuck when calling `JEditorPane.setText()` or `JTextArea.setText()` with long text without space](https://bugs.openjdk.java.net/browse/JDK-8172336). - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like `md2WithRSAEncryption`) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with Java 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 3.2 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ## IMPORTANT CHANGES JMeter now requires Java 8. Ensure you use the most up to date version. JMeter logging has been migrated to SLF4J and Log4j 2. This affects configuration and 3rd party plugins, see below **"Logging changes"**. Starting with JMeter version 3.2 the number of results in View Results Tree is limited by default to 500 entries. If you want more entries, you have to set the property `view.results.tree.max_results` to a higher value, or to `0`, if you don't want to impose any limit. You can set the property in bin/user.properties. More info might be found [here](/usermanual/component-reference/#View_Results_Tree). ### Core improvements - JMeter now provides a new BackendListener implementation that interfaces InfluxDB. ![changes/3.2/backend_influxdb.png](/images/screenshots/changes/3.2/backend_influxdb.png) This implementation sends data using Asynchronous HTTP calls to InfluxDB through its [HTTP API](https://docs.influxdata.com/influxdb/v1.2/guides/writing_data/) and give you the following graphs with annotations: ![backend_listener_influxdb_graph.png](/images/screenshots/backend_listener_influxdb_graph.png) - DNS Cache Manager now has a table to allow static host resolution. ![changes/3.2/dns_cache_manager_static_hosts.png](/images/screenshots/changes/3.2/dns_cache_manager_static_hosts.png) - JMS Publisher and Subscriber now allow reconnection on error with pause. ![changes/3.2/jms_publisher_reconnect.png](/images/screenshots/changes/3.2/jms_publisher_reconnect.png) ![changes/3.2/jms_subscriber_reconnect_pause.png](/images/screenshots/changes/3.2/jms_subscriber_reconnect_pause.png) - Variables in JMS Publisher are now supported for all types of messages. Add the encoding type of the file to parse its content - XPath Extractor now allows extraction randomly, by index or for all matches. ![changes/3.2/xpath_extractor_matchno.png](/images/screenshots/changes/3.2/xpath_extractor_matchno.png) - Response Assertion now allows to work on Request Header, provides a "OR" combination and has a better cell renderer ![changes/3.2/response_assertion.png](/images/screenshots/changes/3.2/response_assertion.png) - JMeter now uses Oracle Nashorn Javascript engine instead of Rhino. This provides a faster execution of Javascript. - HTTP HC4 Implementation now provides preemptive Basic Auth enabled by default - Embedded resources download in CSS has been improved to avoid useless repetitive parsing to find the resources - An important work on code quality and code coverage with tests has been done since Sonar has been setup on the project. You can see Sonar report [here](https://builds.apache.org/analysis/overview?id=12927). ### UX improvements - When running a Test, GUI is now more responsive and less impacting on memory usage thanks to a limitation on the number of Sample Results listeners hold and a rework of the way GUI is updated - HTTP Request GUI has been simplified and provides more place for parameters and body. ![changes/3.2/http_request.png](/images/screenshots/changes/3.2/http_request.png) - HTTP(S) Test Script Recorder has been simplified and clarified. ![changes/3.2/http_recorder_1.png](/images/screenshots/changes/3.2/http_recorder_1.png) ![changes/3.2/http_recorder_2.png](/images/screenshots/changes/3.2/http_recorder_2.png) - A `replace` feature has been added to Search feature to allow replacement in some elements. ![changes/3.2/search_replace.png](/images/screenshots/changes/3.2/search_replace.png) :::note ReplaceAll does not do replacement on all elements, it does it on: - HeaderManager: Replacement in values - Http Request: Replacement in Arguments, Path and Host ::: - View Results Tree now provides a more up to date Browser renderer which requires JavaFX. - You can now add through a contextual menu think times, this will add think times between samplers and Transaction Controllers of selected node. ![changes/3.2/menu_add_think_times.png](/images/screenshots/changes/3.2/menu_add_think_times.png) - You can now apply a naming policy to children of a Transaction Controller. A default policy exists but you can implement your own through `[org.apache.jmeter.gui.action.TreeNodeNamingPolicy](/./api/org/apache/jmeter/gui/action/TreeNodeNamingPolicy/)` and configuring property `naming_policy.impl` ![changes/3.2/menu_apply_naming_policy.png](/images/screenshots/changes/3.2/menu_apply_naming_policy.png) - Sorting per column has been added to View Results in Table, Summary Report, Aggregate Report and Aggregate Graph elements. ![changes/3.2/sorting.png](/images/screenshots/changes/3.2/sorting.png) ### Report/Dashboard improvements - Statistics have been reorganized to clarify report: ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - It is now possible to customize APDEX thresholds per transaction based on regular expression or sample name. The below example will apply different thresholds for samples sample(\\d+), sampleA and scenarioB than default ones (500 and 1500 for satisfied and tolerated thresholds) declared: ``` jmeter.reportgenerator.apdex_satisfied_threshold=500 jmeter.reportgenerator.apdex_tolerated_threshold=1500 jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000;\ sampleA:3000|4000;\ scenarioB:5000|6000 ``` ### Documentation improvements - PDF Documentations have been migrated and updated to HTML user manual ## Incompatible changes - JMeter requires now at least a Java 8 version to run. - JMeter logging has been migrated to SLF4J and Log4j 2, this involves changes in the way configuration is done. JMeter now relies on standard [Log4j 2 configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html) in file `log4j2.xml` See `Logging changes` section below for further details. - The following jars have been removed after migration from LogKit to SLF4J (see [Bug 60589](https://bz.apache.org/bugzilla/show_bug.cgi?id=60589)): - ApacheJMeter_slf4j_logkit.jar - avalon-framework-4.1.4.jar - commons-logging-1.2.jar - excalibur-logger-1.1.jar - logkit-2.0.jar - The `commons-httpclient-3.1.jar` has been removed after drop of HC3.1 support(see [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727)) - JMeter now sets through `-Djava.security.egd=file:/dev/urandom` the algorithm for secure random - Process Sampler now returns error code 500 when an error occurs. It previously returned an empty value. - In `org.apache.jmeter.protocol.http.sampler.HTTPHCAbstractImpl` two protected static fields (`localhost` and `nonProxyHostSuffixSize`) have been renamed to (`LOCALHOST` and `NON_PROXY_HOST_SUFFIX_SIZE`) to follow static fields naming convention - JMeter now uses by default Oracle Nashorn engine instead of Mozilla Rhino for better performances. This should not have an impact unless you use some advanced features. You can revert back to Rhino by settings property `javascript.use_rhino=true`. You can read this [migration guide](https://wiki.openjdk.java.net/display/Nashorn/Rhino+Migration+Guide) for more details on Nashorn. See [Bug 60672](https://bz.apache.org/bugzilla/show_bug.cgi?id=60672) - [Bug 60729](https://bz.apache.org/bugzilla/show_bug.cgi?id=60729)The Random Variable Config Element now allows minimum==maximum. Previous versions logged an error when minimum==maximum and did not set the configured variable. - [Bug 60730](https://bz.apache.org/bugzilla/show_bug.cgi?id=60730)The JSON PostProcessor now sets the `_ALL` variable (assuming `Compute concatenation var` was checked) even if the JSON path matches only once. Previous versions did not set the `_ALL` variable in this case. #### Removed elements or functions - SOAP/XML-RPC Request has been removed as part of [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727). Use HTTP Request element as a replacement. See [Building a WebService Test Plan](/./usermanual/build-ws-test-plan/) - [Bug 60423](https://bz.apache.org/bugzilla/show_bug.cgi?id=60423)Drop Monitor Results listener - Drop deprecated class `org.apache.jmeter.protocol.system.NativeCommand` - Drop deprecated class `org.apache.jmeter.protocol.http.config.gui.MultipartUrlConfigGui` - Drop deprecated class `org.apache.jmeter.testelement.TestListener` - Drop deprecated class `org.apache.jmeter.reporters.FileReporter` - Drop deprecated class `org.apache.jmeter.protocol.http.modifier.UserSequence` - Drop deprecated class `org.apache.jmeter.protocol.http.parser.HTMLParseError` - Drop unused methods `org.apache.jmeter.protocol.http.control.HeaderManager#getSOAPHeader` and `org.apache.jmeter.protocol.http.control.HeaderManager#setSOAPHeader(Object)` - `org.apache.jmeter.protocol.http.util.Base64Encode` has been deprecated, you can use `java.util.Base64` as a replacement #### Logging changes JMeter logging has been migrated to SLF4J and Log4j 2. This affects logging configuration and 3rd party plugins (if they use JMeter logging). The following sections describe what changes need to be made. ##### Setting the logging level and log file The default logging level can be changed on the command-line using the `-L` parameter. Likewise the `-l` parameter can be used to change the name of the log file. However the `log_level` properties no longer work. The default logging levels and file name are defined in the `log4j2.xml` configuration file in the launch directory (usually `JMETER_HOME/bin`) :::note If you need to change the level programmatically from Groovy code or Beanshell, you need to do the following: ```java import org.apache.logging.log4j.core.config.Configurator; ⋮ final String loggerName = te.getClass().getName(); // te being a JMeter class Configurator.setAllLevels(loggerName, Level.DEBUG); ``` ::: ##### Changes to 3rd party plugin logging :::note 3rd party plugins should migrate their logging code from logkit to slf4j. This is fairly easy and can be done by replacing: ```java import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; ⋮ private static final Logger log = LoggingManager.getLoggerForClass(); ``` By: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; ⋮ private static final Logger log = LoggerFactory.getLogger(YourClassName.class); ``` ::: ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 59934](https://bz.apache.org/bugzilla/show_bug.cgi?id=59934)Fix race-conditions in CssParser. Based on a patch by Jerome Loisel (loisel.jerome at gmail.com) - [Bug 60543](https://bz.apache.org/bugzilla/show_bug.cgi?id=60543)HTTP Request / Http Request Defaults UX: Move to advanced panel Timeouts, Implementation, Proxy. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60548](https://bz.apache.org/bugzilla/show_bug.cgi?id=60548)HTTP Request : Allow Upper Panel to be collapsed - [Bug 57242](https://bz.apache.org/bugzilla/show_bug.cgi?id=57242)HTTP Authorization is not pre-emptively set with HttpClient4 - [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727)Drop commons-httpclient-3.1 and related elements. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60790](https://bz.apache.org/bugzilla/show_bug.cgi?id=60790)HTTP(S) Test Script Recorder : Improve information on certificate expiration and have better UX for Start/Stop - [Bug 60888](https://bz.apache.org/bugzilla/show_bug.cgi?id=60888)HttpRequest : Add option to allow retrial of all requests including NON Idempotent HTTP methods - [Bug 60896](https://bz.apache.org/bugzilla/show_bug.cgi?id=60896)HTTP(S) Test Script Recorder : Improve UX by reducing number of properties on screen #### Other samplers - [Bug 60740](https://bz.apache.org/bugzilla/show_bug.cgi?id=60740)Support variable for all JMS messages (bytes, object, …) and sources (file, folder), based on [PR#241](https://github.com/apache/jmeter/pull/241). Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60585](https://bz.apache.org/bugzilla/show_bug.cgi?id=60585)JMS Publisher and JMS Subscriber : Allow reconnection on error and pause between errors. Based on [PR#240](https://github.com/apache/jmeter/pull/240) from by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [PR#259](https://github.com/apache/jmeter/pull/259) - Refactored and reformatted SmtpSampler. Contributed by Graham Russell (graham at ham1.co.uk) #### Controllers - [Bug 60672](https://bz.apache.org/bugzilla/show_bug.cgi?id=60672)JavaScript function / IfController : use Nashorn engine by default #### Listeners - [Bug 60144](https://bz.apache.org/bugzilla/show_bug.cgi?id=60144)View Results Tree : Add a more up to date Browser Renderer to replace old Render - [Bug 60542](https://bz.apache.org/bugzilla/show_bug.cgi?id=60542)View Results Tree : Allow Upper Panel to be collapsed. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 52962](https://bz.apache.org/bugzilla/show_bug.cgi?id=52962)Allow sorting by columns for View Results in Table, Summary Report, Aggregate Report and Aggregate Graph. Based on a [PR#245](https://github.com/apache/jmeter/pull/245) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60590](https://bz.apache.org/bugzilla/show_bug.cgi?id=60590)BackendListener : Add Influxdb BackendListenerClient implementation to JMeter. Partly based on [PR#246](https://github.com/apache/jmeter/pull/246) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60591](https://bz.apache.org/bugzilla/show_bug.cgi?id=60591)BackendListener : Add a time boxed sampling. Based on a [PR#237](https://github.com/apache/jmeter/pull/237) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60678](https://bz.apache.org/bugzilla/show_bug.cgi?id=60678)View Results Tree : Text renderer, search should not popup "Text Not Found" - [Bug 60691](https://bz.apache.org/bugzilla/show_bug.cgi?id=60691)View Results Tree : In Renderers (XPath, JSON Path Tester, RegExp Tester and CSS/JQuery Tester) lower panel is sometimes not visible as upper panel is too big and cannot be resized - [Bug 60687](https://bz.apache.org/bugzilla/show_bug.cgi?id=60687)Make GUI more responsive when it gets a lot of events. - [Bug 60791](https://bz.apache.org/bugzilla/show_bug.cgi?id=60791)View Results Tree: Trigger search on Enter key in Search Feature and display red background if no match - [Bug 60822](https://bz.apache.org/bugzilla/show_bug.cgi?id=60822)ResultCollector does not ensure unique file name entries in files HashMap #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60154](https://bz.apache.org/bugzilla/show_bug.cgi?id=60154)User Parameters GUI: allow rows to be moved up & down in the list. Contributed by Murdecai777 (https://github.com/Murdecai777). - [Bug 60507](https://bz.apache.org/bugzilla/show_bug.cgi?id=60507)Added '`Or`' Function into ResponseAssertion. Based on a contribution from 忻隆 (298015902 at qq.com) - [Bug 58943](https://bz.apache.org/bugzilla/show_bug.cgi?id=58943)Create a Better Think Time experience. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60602](https://bz.apache.org/bugzilla/show_bug.cgi?id=60602)XPath Extractor : Add Match No. to allow extraction randomly, by index or all matches - [Bug 60710](https://bz.apache.org/bugzilla/show_bug.cgi?id=60710)XPath Extractor : When content on which assertion applies is not XML, in View Results Tree the extractor is marked in Red and named SAXParseException. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60712](https://bz.apache.org/bugzilla/show_bug.cgi?id=60712)Response Assertion : Improve Renderer of Patterns - [Bug 59174](https://bz.apache.org/bugzilla/show_bug.cgi?id=59174)Add a table with static hosts to the DNS Cache Manager. This enables better virtual hosts testing with HttpClient4. #### Functions - [Bug 60883](https://bz.apache.org/bugzilla/show_bug.cgi?id=60883)[PR#288](https://github.com/apache/jmeter/pull/288) - Add `\${__escapeXml()}` function. Contributed by Michael Osipov (michaelo at apache.org) #### I18N - Improve translation "`save_as`" in French. Based on a [PR#252](https://github.com/apache/jmeter/pull/252) by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60785](https://bz.apache.org/bugzilla/show_bug.cgi?id=60785)Improvement of Japanese translation. Patch by Kimono (kimono.outfit.am at gmail.com). #### Report / Dashboard - [Bug 60637](https://bz.apache.org/bugzilla/show_bug.cgi?id=60637)Improve Statistics table design ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - [Bug 60112](https://bz.apache.org/bugzilla/show_bug.cgi?id=60112)Report / Dashboard : Add ability to customize APDEX thresholds per Transaction name. Contributed by Stephane Leplus (s.leplus at ubik-ingenierie.com) #### General - [Bug 58164](https://bz.apache.org/bugzilla/show_bug.cgi?id=58164)Check if file already exists on ResultCollector listener before starting the loadtest - [Bug 54525](https://bz.apache.org/bugzilla/show_bug.cgi?id=54525)Search Feature : Enhance it with ability to replace - [Bug 60530](https://bz.apache.org/bugzilla/show_bug.cgi?id=60530)Add API to create JMeter threads while test is running. Based on a contribution by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60514](https://bz.apache.org/bugzilla/show_bug.cgi?id=60514)Ability to apply a naming convention on Children of a Transaction Controller. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60711](https://bz.apache.org/bugzilla/show_bug.cgi?id=60711)Improve Delete button behaviour for Assertions / Header Manager / User Parameters GUIs / Exclude, Include in HTTP(S) Test Script Recorder - [Bug 60593](https://bz.apache.org/bugzilla/show_bug.cgi?id=60593)Switch to G1 GC algorithm - [Bug 60595](https://bz.apache.org/bugzilla/show_bug.cgi?id=60595)Add a SplashScreen at the start of JMeter GUI. Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 55258](https://bz.apache.org/bugzilla/show_bug.cgi?id=55258)Drop "Close" icon from toolbar and add "New" to menu. Partly based on contribution from Sanduni Kanishka (https://github.com/SanduniKanishka) - [Bug 59995](https://bz.apache.org/bugzilla/show_bug.cgi?id=59995)Allow user to change font size with two new menu items and use `jmeter.hidpi.scale.factor` for scaling fonts. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60654](https://bz.apache.org/bugzilla/show_bug.cgi?id=60654)Validation Feature : Be able to ignore BackendListener. Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60646](https://bz.apache.org/bugzilla/show_bug.cgi?id=60646)Workbench : Save it by default - [Bug 60684](https://bz.apache.org/bugzilla/show_bug.cgi?id=60684)Thread Group: Validate ended prematurely by Scheduler with 0 or very short duration. Contributed by Andrew Burton (andrewburtonatwh at gmail.com). - [Bug 60589](https://bz.apache.org/bugzilla/show_bug.cgi?id=60589)Migrate LogKit to SLF4J - Drop Avalon, LogKit and Excalibur with backward compatibility for 3rd party modules. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60565](https://bz.apache.org/bugzilla/show_bug.cgi?id=60565)Migrate LogKit to SLF4J - Optimize logging statements. e.g, message format args, throwable args, unnecessary if-enabled-logging in simple ones, etc. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60564](https://bz.apache.org/bugzilla/show_bug.cgi?id=60564)Migrate LogKit to SLF4J - Replace LogKit loggers with SLF4J ones and keep the current LogKit binding solution for backward compatibility with plugins. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60664](https://bz.apache.org/bugzilla/show_bug.cgi?id=60664)Add a UI menu to set log level. Contributed by Woonsan Ko (woonsan at apache.org) - [PR#276](https://github.com/apache/jmeter/pull/276) - Added some translations for polish locale. Contributed by Bartosz Siewniak (barteksiewniak at gmail.com) - [Bug 60792](https://bz.apache.org/bugzilla/show_bug.cgi?id=60792)Create a new Help menu item to create a thread dump - [Bug 60813](https://bz.apache.org/bugzilla/show_bug.cgi?id=60813)JSR223 Test element : Take into account JMeterStopTestNowException, JMeterStopTestException and JMeterStopThreadException - [Bug 60814](https://bz.apache.org/bugzilla/show_bug.cgi?id=60814)Menu : Add `Open Recent` menu item to make recent files loading more obvious - [Bug 60815](https://bz.apache.org/bugzilla/show_bug.cgi?id=60815)Drop "Reset GUI" from menu - [Bug 60886](https://bz.apache.org/bugzilla/show_bug.cgi?id=60886)Build improvements to better enable builds in environments that are behind a proxy. Partly contributed by Michael Osipov (michaelo at apache.org) ## Non-functional changes - [Bug 60415](https://bz.apache.org/bugzilla/show_bug.cgi?id=60415)Drop support for Java 7. - Updated to dnsjava-2.1.8.jar (from 2.1.7) - Updated to groovy 2.4.10 (from 2.4.7) - Updated to httpcore 4.4.6 (from 4.4.5) - Updated to httpclient 4.5.3 (from 4.5.2) - Updated to jodd 3.8.1 (from 3.7.1.jar) - Updated to jsoup-1.10.2 (from 1.10.1) - Updated to ph-css 5.0.3 (from 4.1.6) - Updated to ph-commons 8.6.0 (from 6.2.4) - Updated to slf4j-api 1.7.25 (from 1.7.21) - Updated to asm 5.2 (from 5.1) - Updated to rsyntaxtextarea-2.6.1 (from 2.6.0) - Updated to commons-net-3.6 (from 3.5) - Updated to json-smart-2.3 (from 2.2.1) - Updated to accessors-smart-1.2 (from 1.1) - Converted the old pdf tutorials to xml. - [PR#255](https://github.com/apache/jmeter/pull/255) - Utilised Java 8 (and 7) features to tidy up code. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 59435](https://bz.apache.org/bugzilla/show_bug.cgi?id=59435)JMeterTestCase no longer supports JUnit3 ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 60531](https://bz.apache.org/bugzilla/show_bug.cgi?id=60531)HTTP Cookie Manager : changing Implementation does not update Cookie Policy - [Bug 60575](https://bz.apache.org/bugzilla/show_bug.cgi?id=60575)HTTP GET Requests could have a content-type header without a body. - [Bug 60682](https://bz.apache.org/bugzilla/show_bug.cgi?id=60682)HTTP Request : Get method may fail on redirect due to Content-Length header being set - [Bug 60643](https://bz.apache.org/bugzilla/show_bug.cgi?id=60643)HTTP(S) Test Script Recorder doesn't correctly handle restart or start after stop. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60652](https://bz.apache.org/bugzilla/show_bug.cgi?id=60652)HTTP PUT Requests might leak file descriptors. - [Bug 60689](https://bz.apache.org/bugzilla/show_bug.cgi?id=60689)`httpclient4.validate_after_inactivity` has no impact leading to usage of potentially stale/closed connections - [Bug 60690](https://bz.apache.org/bugzilla/show_bug.cgi?id=60690)Default values for "httpclient4.validate_after_inactivity" and "httpclient4.time_to_live" which are equal to each other makes validation useless - [Bug 60758](https://bz.apache.org/bugzilla/show_bug.cgi?id=60758)HTTP(s) Test Script Recorder : Number request may generate duplicate numbers. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 56939](https://bz.apache.org/bugzilla/show_bug.cgi?id=56939)Parameters are not passed with OPTIONS HTTP Request - [Bug 60778](https://bz.apache.org/bugzilla/show_bug.cgi?id=60778)Http Java Impl does not show Authorization header in SampleResult even if it is sent - [Bug 60837](https://bz.apache.org/bugzilla/show_bug.cgi?id=60837)GET with body, PUT are not retried even if `httpclient4.retrycount` is higher than 0 - [Bug 60842](https://bz.apache.org/bugzilla/show_bug.cgi?id=60842)Trim extracted URLs when loading embedded resources using the Lagarto based HTML Parser. - [Bug 60928](https://bz.apache.org/bugzilla/show_bug.cgi?id=60928)Http Request : Connection Leak when keepalive is used with Embedded Resources #### Other Samplers - [Bug 603982](https://bz.apache.org/bugzilla/show_bug.cgi?id=603982)Guard Exception handler of the `JDBCSampler` against null messages - [Bug 55652](https://bz.apache.org/bugzilla/show_bug.cgi?id=55652)JavaSampler silently resets classname if class can not be found #### Controllers #### Listeners - [Bug 60648](https://bz.apache.org/bugzilla/show_bug.cgi?id=60648)GraphiteBackendListener can lose some metrics at end of test if test is very short - [Bug 60650](https://bz.apache.org/bugzilla/show_bug.cgi?id=60650)AbstractBackendListenerClient does not reset UserMetric between runs - [Bug 60759](https://bz.apache.org/bugzilla/show_bug.cgi?id=60759)View Results Tree : Search feature does not search in URL. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60859](https://bz.apache.org/bugzilla/show_bug.cgi?id=60859)Save Responses to a file : 2 elements with different configuration will overlap #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60438](https://bz.apache.org/bugzilla/show_bug.cgi?id=60438)[PR#235](https://github.com/apache/jmeter/pull/235) - Clear old variables before extracting new ones in JSON Extractor. Based on a patch by Qi Chen (qi.chensh at ele.me) - [Bug 60607](https://bz.apache.org/bugzilla/show_bug.cgi?id=60607)DNS Cache Manager configuration is ignored - [Bug 60729](https://bz.apache.org/bugzilla/show_bug.cgi?id=60729)The Random Variable Config Element should allow minimum==maximum - [Bug 60730](https://bz.apache.org/bugzilla/show_bug.cgi?id=60730)The JSON PostProcessor should set the `_ALL` variable even if the JSON path matches only once. - [Bug 60747](https://bz.apache.org/bugzilla/show_bug.cgi?id=60747)Response Assertion : Add Request Headers to `Field to Test` - [Bug 60763](https://bz.apache.org/bugzilla/show_bug.cgi?id=60763)XMLAssertion should not leak errors to console - [Bug 60797](https://bz.apache.org/bugzilla/show_bug.cgi?id=60797)TestAction in pause mode can last beyond configured duration of test #### Functions - [Bug 60819](https://bz.apache.org/bugzilla/show_bug.cgi?id=60819)Function __fileToString does not honor the documentation contract when file is not found #### I18N #### Report / Dashboard - [Bug 60726](https://bz.apache.org/bugzilla/show_bug.cgi?id=60726)Report / Dashboard : Top 5 errors by samplers must not take into account the series filtering - [Bug 60919](https://bz.apache.org/bugzilla/show_bug.cgi?id=60919)Report / Dashboard : Latency Vs Request and Response Time Vs Request are wrong if granularity is different from 1000 (1 second) #### General - [Bug 60775](https://bz.apache.org/bugzilla/show_bug.cgi?id=60775)NamePanel ctor calls overrideable method - [Bug 60428](https://bz.apache.org/bugzilla/show_bug.cgi?id=60428)JMeter Graphite Backend Listener throws exception when test ends and `useRegexpForSamplersList` is set to `true`. Based on patch by Liu XP (liu_xp2003 at sina.com) - [Bug 60442](https://bz.apache.org/bugzilla/show_bug.cgi?id=60442)Fix a typo in `build.xml` (gavin at 16degrees.com.au) - [Bug 60449](https://bz.apache.org/bugzilla/show_bug.cgi?id=60449)JMeter Tree : Annoying behaviour when node name is empty - [Bug 60494](https://bz.apache.org/bugzilla/show_bug.cgi?id=60494)Add sonar analysis task to build - [Bug 60501](https://bz.apache.org/bugzilla/show_bug.cgi?id=60501)Search Feature : Performance issue when regexp is checked - [Bug 60444](https://bz.apache.org/bugzilla/show_bug.cgi?id=60444)Intermittent failure of `TestHTTPMirrorThread#testSleep()`. Contributed by Thomas Schapitz (ts-nospam12 at online.de) - [Bug 60621](https://bz.apache.org/bugzilla/show_bug.cgi?id=60621)The "`report-template`" folder is missing from `ApacheJMeter_config-3.1.jar` in maven central - [Bug 60744](https://bz.apache.org/bugzilla/show_bug.cgi?id=60744)GUI elements are not cleaned up when reused during load of Test Plan which can lead them to be partially initialized with a previous state for a new Test Element - [Bug 60812](https://bz.apache.org/bugzilla/show_bug.cgi?id=60812)JMeterThread does not honor contract of JMeterStopTestNowException - [Bug 60857](https://bz.apache.org/bugzilla/show_bug.cgi?id=60857)SaveService omits XML header if _file_encoding is not defined in saveservice.properties - [Bug 60830](https://bz.apache.org/bugzilla/show_bug.cgi?id=60830)Timestamps in CSV file could be corrupted due to sharing a SimpleDateFormatter across threads ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Jerome Loisel (loisel.jerome at gmail.com) - Liu XP (liu_xp2003 at sina.com) - Qi Chen (qi.chensh at ele.me) - (gavin at 16degrees.com.au) - Thomas Schapitz (ts-nospam12 at online.de) - Murdecai777 (https://github.com/Murdecai777) - Logan Mauzaize (logan.mauzaize at gmail.com) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - 忻隆 (298015902 at qq.com) - [Ubik Load Pack](http://ubikloadpack.com) - Graham Russell (graham at ham1.co.uk) - Sanduni Kanishka (https://github.com/SanduniKanishka) - Andrew Burton (andrewburtonatwh at gmail.com) - Woonsan Ko (woonsan at apache.org) - Bartosz Siewniak (barteksiewniak at gmail.com) - Kimono (kimono.outfit.am at gmail.com) - Michael Osipov (michaelo at apache.org) - Stephane Leplus (s.leplus at ubik-ingenierie.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Tuukka Mustonen (tuukka.mustonen at gmail.com) who gave us a lot of useful feedback which helped resolve [Bug 60689](https://bz.apache.org/bugzilla/show_bug.cgi?id=60689) and [Bug 60690](https://bz.apache.org/bugzilla/show_bug.cgi?id=60690) - Amar Darisa (amar.darisa at gmail.com) who helped us with his feedback on [Bug 60682](https://bz.apache.org/bugzilla/show_bug.cgi?id=60682) Apologies if we have omitted anyone else. ## Known problems and workarounds - View Results Tree may freeze rendering large response particularly if this response has no spaces, see [Bug 60816](https://bz.apache.org/bugzilla/show_bug.cgi?id=60816). This is due to an identified Java Bug [UI stuck when calling JEditorPane.setText() or JTextArea.setText() with long text without space](https://bugs.openjdk.java.net/browse/JDK-8172336). - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 8+. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later (but be aware that Java 9 is not certified yet for JMeter). - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with JAVA 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 3.1 Summary - [New and Noteworthy](#New and Noteworthy) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Known problems and workarounds](#Known problems and workarounds) - [Thanks](#Thanks) ## New and Noteworthy ## Improve Report/Dashboard The Dashboard has been improved with 3 new graphs and 1 summary table: - Connect Time over Time graph : ![dashboard/report_connect_time_over_time.png](/images/screenshots/dashboard/report_connect_time_over_time.png) - Response Time Percentiles Over Time (successful responses) graph : ![dashboard/response_time_percentiles_over_time.png](/images/screenshots/dashboard/response_time_percentiles_over_time.png) - Response Time Overview graph : ![dashboard/response_time_overview.png](/images/screenshots/dashboard/response_time_overview.png) - Top 5 errors by Sampler table : ![dashboard/top_5_errors_by_sampler.png](/images/screenshots/dashboard/top_5_errors_by_sampler.png) - More details on errors in Errors table - Average response time added to Statistics table : ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - Active Threads table now stacks threads : ![dashboard/report_active_threads_over_time.png](/images/screenshots/dashboard/report_active_threads_over_time.png) ## New Metrics A new `sent_bytes` metric has been introduced which reports the bytes sent to server. Another metric `connect_time` has been enabled by default in this version ## Handling Big responses JMeter is now able to handle in terms of metrics responses bigger than 2GB, limit has been increased to 9223372 TB. To handle such big responses, it can also now truncate part of the response to avoid overflooding memory. See `httpsampler.max_bytes_to_store_per_request` property. ## New `__groovy` function Introduce a new function `__groovy` that enables Groovy functions. This can be handy, as JavaScript can be quite slow (same for BeanShell), when used in highly concurrent test plans. ## Use Groovy as default for JSR-223 elements Groovy is now set as the default language for JSR-223 elements. If you want to use another of the supported language, you have to make an explicit choice. :::note By default `Cache compiled script if available` is not checked by default although we advise you to check it and ensure you don't use `\${varName}` syntax to access JMeter variables but `vars.get("varName")` instead. ::: ## Formatted HTML source view in Results Tree View The HTML source code in the Results Tree View can now be viewed formatted. This is extremely useful, if the code of the webpage has been stripped of all superfluous whitespace. ![New formatted HTML source view](/images/screenshots/html-formatted-tree-view.png) _New formatted HTML source view_ ## Ability to update all timers in Test plan with a new property A new property `timer.factor=1.0f` has been introduced which allows you to multiply pause times computed by Gaussian, Uniform and Poisson Timers by it. This allows you to update Think Times from one place and let you gain productivity. ### Core improvements - Various GUI and UX fixes - Memory usage improvements - JDBC Request is now able to return Blob/Clob and computes latency and connect time - CSS Parsing introduced in 3.0 has been optimized by introduction of a parsing cache - HTTP Request is now able to handle body in GET request, this is useful for Elastic Search requests for example. ### Documentation improvements - Documentation review and improvements for easier startup - New [properties reference](/usermanual/properties-reference/) documentation section ## Incompatible changes - A cache for CSS Parsing of URLs has been introduced in this version, it is enabled by default. It is controlled by property `css.parser.cache.size`. It can be disabled by setting its value to `0`. See [Bug 59885](https://bz.apache.org/bugzilla/show_bug.cgi?id=59885) - ThroughputController defaults have changed. Now defaults are Percent Executions which is global and no more per user. See [Bug 60023](https://bz.apache.org/bugzilla/show_bug.cgi?id=60023) - Since version 3.1, HTML report ignores empty `Transaction Controller` (possibly generated by `If Controller` or `Throughput Controller`) when computing metrics. This provides more accurate metrics - Since version 3.1, Summariser ignores SampleResults generated by `Transaction Controller` when computing the live statistics, see [Bug 60109](https://bz.apache.org/bugzilla/show_bug.cgi?id=60109) - Since version 3.1, when using Stripped modes (by default `StrippedBatch` is used), response will be stripped also for failing SampleResults, you can revert this to previous behaviour by setting `sample_sender_strip_also_on_error=false` in `user.properties`, see [Bug 60137](https://bz.apache.org/bugzilla/show_bug.cgi?id=60137) - Since version 3.1, `jmeter.save.saveservice.connect_time` property value is `true`, meaning CSV file for results will contain an additional column containing connection time, see [Bug 60106](https://bz.apache.org/bugzilla/show_bug.cgi?id=60106) - Since version 3.1, Random Timer subclasses (Gaussian Random Timer, Uniform Random Timer and Poisson Random Timer) implement interface `[org.apache.jmeter.timers.ModifiableTimer](/./api/org/apache/jmeter/timers/ModifiableTimer/)` - Since version 3.1, if you don't select any language in JSR223 Test Elements, Apache Groovy language will be used. See [Bug 59945](https://bz.apache.org/bugzilla/show_bug.cgi?id=59945) - Since version 3.1, CSV DataSet now trims variable names to avoid issues due to spaces between variables names when configuring CSV DataSet. This should not have any impact for you unless you use space at the beginning or end of your variable names. See [Bug 60221](https://bz.apache.org/bugzilla/show_bug.cgi?id=60221) - Since version 3.1, HTTP Request is able when using HttpClient4 (default) implementation to handle responses bigger than `2147483647` Bytes, that is 2GB. To allow this two properties have been introduced: - `httpsampler.max_bytes_to_store_per_request` (defaults to 10MB) will control what is held in memory. By default JMeter will only keep in memory the first 10MB of a response. If you have responses larger than this value and use assertions that are after the first 10MB, then you must increase this value - `httpsampler.max_buffer_size` will control the buffer used to read the data. Previously JMeter used a buffer equal to Content-Length header which could lead to failures and make JMeter less resistant to faulty applications, but note this may impact response times and give slightly different results than previous versions if your application returned a Content-Length header higher than current default value (65KB) See [Bug 53039](https://bz.apache.org/bugzilla/show_bug.cgi?id=53039) #### Deprecated and removed elements or functions :::note These elements do not appear anymore in the menu, if you need them modify `not_in_menu` property. The JMeter team advises not to use them anymore and migrate to their replacement. ::: - [Bug 60222](https://bz.apache.org/bugzilla/show_bug.cgi?id=60222)Remove deprecated elements Distribution Graph, Spline Visualizer - [Bug 60224](https://bz.apache.org/bugzilla/show_bug.cgi?id=60224)Deprecate `[Monitor Results](/./usermanual/component-reference/#Monitor_Results_(DEPRECATED))` listener. It will be dropped in next version. - [Bug 60323](https://bz.apache.org/bugzilla/show_bug.cgi?id=60323)Deprecate BSF Elements (Use JSR223 Elements instead). They will probably be dropped in N+2 version. The following elements are deprecated: - `[BSF Sampler](/./usermanual/component-reference/#BSF_Sampler_(DEPRECATED))` - `[BSF Listener](/./usermanual/component-reference/#BSF_Listener_(DEPRECATED))` - `[BSF Assertion](/./usermanual/component-reference/#BSF_Assertion_(DEPRECATED))` - `[BSF Timer](/./usermanual/component-reference/#BSF_Timer_(DEPRECATED))` - `[BSF PreProcessor](/./usermanual/component-reference/#BSF_PreProcessor_(DEPRECATED))` - `[BSF PostProcessor](/./usermanual/component-reference/#BSF_PostProcessor_(DEPRECATED))` - [Bug 60225](https://bz.apache.org/bugzilla/show_bug.cgi?id=60225)Drop deprecated `__jexl` function, jexl support in BSF and dependency on `commons-jexl-1.1.jar`. This function can be easily replaced with `[__jexl3](/./usermanual/functions/#__jexl3)` function - [Bug 60268](https://bz.apache.org/bugzilla/show_bug.cgi?id=60268)Drop org.apache.jmeter.gui.action.Analyze and deprecate org.apache.jmeter.reporters.FileReporter (will be removed in next version) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 59882](https://bz.apache.org/bugzilla/show_bug.cgi?id=59882)Reduce memory allocations for better throughput. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) through [PR#217](https://github.com/apache/jmeter/pull/217) and [PR#228](https://github.com/apache/jmeter/pull/228) - [Bug 59885](https://bz.apache.org/bugzilla/show_bug.cgi?id=59885)Optimize css parsing for embedded resources download by introducing a cache. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) through [PR#219](https://github.com/apache/jmeter/pull/219) - [Bug 60092](https://bz.apache.org/bugzilla/show_bug.cgi?id=60092)View Result Tree: Add shortened version of the PUT body to sampler result. - [Bug 60229](https://bz.apache.org/bugzilla/show_bug.cgi?id=60229)Add a new metric : sent_bytes. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 53039](https://bz.apache.org/bugzilla/show_bug.cgi?id=53039)HTTP Request : Be able to handle responses which size exceeds `2147483647` bytes (that is 2GB) - [Bug 60265](https://bz.apache.org/bugzilla/show_bug.cgi?id=60265)HTTP Request : In Files Upload Tab you cannot resize columns - [Bug 60318](https://bz.apache.org/bugzilla/show_bug.cgi?id=60318)Ignore CSS warnings when parsing with ph-css library. - [Bug 60358](https://bz.apache.org/bugzilla/show_bug.cgi?id=60358)Http Request : Allow sending Body Data for HTTP GET request #### Other samplers - [PR#211](https://github.com/apache/jmeter/pull/211)Differentiate the timing for JDBC Sampler. Use latency and connect time. Contributed by Thomas Peyrard (thomas.peyrard at murex.com) - [Bug 59620](https://bz.apache.org/bugzilla/show_bug.cgi?id=59620)Fix button action in "JMS Publisher → Random File from folder specified below" to allow to select a directory - [Bug 60066](https://bz.apache.org/bugzilla/show_bug.cgi?id=60066)Handle CLOBs and BLOBs and limit them if necessary when storing them in result sampler. #### Controllers - [Bug 59351](https://bz.apache.org/bugzilla/show_bug.cgi?id=59351)Improve log/error/message for IncludeController. Partly contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 60023](https://bz.apache.org/bugzilla/show_bug.cgi?id=60023)ThroughputController : Make "Percent Executions" and global the default values. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60082](https://bz.apache.org/bugzilla/show_bug.cgi?id=60082)Validation mode : Be able to force Throughput Controller to run as if it was set to 100% - [Bug 59349](https://bz.apache.org/bugzilla/show_bug.cgi?id=59349)Trim spaces in input filename in IncludeController. - [Bug 60081](https://bz.apache.org/bugzilla/show_bug.cgi?id=60081)Interleave Controller : Add an option to alternate across threads #### Listeners - [Bug 59953](https://bz.apache.org/bugzilla/show_bug.cgi?id=59953)GraphiteBackendListener : Add Average metric. Partly contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 59975](https://bz.apache.org/bugzilla/show_bug.cgi?id=59975)View Results Tree : Text renderer annoyingly scrolls down when content is bulky. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60109](https://bz.apache.org/bugzilla/show_bug.cgi?id=60109)Summariser : Make it ignore TC generated SampleResult in its summary computations - [Bug 59948](https://bz.apache.org/bugzilla/show_bug.cgi?id=59948)Add a formatted and sane HTML source code render to View Results Tree - [Bug 60252](https://bz.apache.org/bugzilla/show_bug.cgi?id=60252)Add sent kbytes/s to Aggregate Report and Summary report - [Bug 60267](https://bz.apache.org/bugzilla/show_bug.cgi?id=60267)UX : In View Results Tree it should be possible to close the Configure popup by typing escape. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 59845](https://bz.apache.org/bugzilla/show_bug.cgi?id=59845)Log messages about JSON Path mismatches at `debug` level instead of `error`. - [PR#212](https://github.com/apache/jmeter/pull/212)Allow multiple selection and delete in HTTP Authorization Manager. Based on a patch by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59816](https://bz.apache.org/bugzilla/show_bug.cgi?id=59816)[PR#213](https://github.com/apache/jmeter/pull/213)Allow multiple selection and delete in HTTP Header Manager. Based on a patch by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59967](https://bz.apache.org/bugzilla/show_bug.cgi?id=59967)CSS/JQuery Extractor : Allow empty default value. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59974](https://bz.apache.org/bugzilla/show_bug.cgi?id=59974)Response Assertion : Add button "`Add from clipboard`". Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60050](https://bz.apache.org/bugzilla/show_bug.cgi?id=60050)CSV Data Set : Make it clear in the logs when a thread will exit due to this configuration - [Bug 59962](https://bz.apache.org/bugzilla/show_bug.cgi?id=59962)Cache Manager does not update expires date when response code is `304`. - [Bug 60018](https://bz.apache.org/bugzilla/show_bug.cgi?id=60018)Timer : Add a factor to apply on pauses. Partly based on a patch by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60203](https://bz.apache.org/bugzilla/show_bug.cgi?id=60203)Use more available space for textarea in XPath Assertion. - [Bug 60220](https://bz.apache.org/bugzilla/show_bug.cgi?id=60220)Rename JSON Path Post Processor to JSON Extractor - [Bug 60221](https://bz.apache.org/bugzilla/show_bug.cgi?id=60221)CSV DataSet : trim variable names - [Bug 59329](https://bz.apache.org/bugzilla/show_bug.cgi?id=59329)Trim spaces in input filename in CSVDataSet. #### Functions - [Bug 59963](https://bz.apache.org/bugzilla/show_bug.cgi?id=59963)New function `__RandomFromMultipleVars`: Ability to compute a random value from values of one or more variables. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59991](https://bz.apache.org/bugzilla/show_bug.cgi?id=59991)New function `__groovy` to evaluate Groovy Script. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### I18N - [PR#214](https://github.com/apache/jmeter/pull/214)Add spanish translation for delayed starting of threads. Contributed by Asier Lostalé (asier.lostale at openbravo.com). - [Bug 60348](https://bz.apache.org/bugzilla/show_bug.cgi?id=60348)Change chinese translation for `Save as`. Contributed by XMeter (support at xmeter.net). #### Report / Dashboard - [Bug 59954](https://bz.apache.org/bugzilla/show_bug.cgi?id=59954)Web Report/Dashboard : Add average metric - [Bug 59956](https://bz.apache.org/bugzilla/show_bug.cgi?id=59956)Web Report / Dashboard : Add ability to generate a graph for a range of data - [Bug 60065](https://bz.apache.org/bugzilla/show_bug.cgi?id=60065)Report / Dashboard : Improve Dashboard Error Summary by adding response message to "Type of error". Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60079](https://bz.apache.org/bugzilla/show_bug.cgi?id=60079)Report / Dashboard : Add a new "Response Time Overview" graph - [Bug 60080](https://bz.apache.org/bugzilla/show_bug.cgi?id=60080)Report / Dashboard : Add a new "Connect Time Over Time " graph. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60091](https://bz.apache.org/bugzilla/show_bug.cgi?id=60091)Report / Dashboard : Have a new report containing min/max and percentiles graphs. - [Bug 60108](https://bz.apache.org/bugzilla/show_bug.cgi?id=60108)Report / Dashboard : In Requests Summary rounding is too aggressive - [Bug 60098](https://bz.apache.org/bugzilla/show_bug.cgi?id=60098)Report / Dashboard : Reduce default value for "`jmeter.reportgenerator.statistic_window`" to reduce memory impact - [Bug 60115](https://bz.apache.org/bugzilla/show_bug.cgi?id=60115)Add date format property for start/end date filter into Report generator - [Bug 60171](https://bz.apache.org/bugzilla/show_bug.cgi?id=60171)Report / Dashboard : Active Threads Over Time should stack lines to give the total amount of threads running - [Bug 60250](https://bz.apache.org/bugzilla/show_bug.cgi?id=60250)Report / Dashboard : Need to Add Sent KB/s in Statistics Report of HTML Dashboard - [Bug 60287](https://bz.apache.org/bugzilla/show_bug.cgi?id=60287)Report / Dashboard : Have a new Top5 Errors by sampler table in Dashboard. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 59803](https://bz.apache.org/bugzilla/show_bug.cgi?id=59803)Use `isValid()` method from JDBC driver, if no `validationQuery` is given in JDBC Connection Configuration. - [Bug 57493](https://bz.apache.org/bugzilla/show_bug.cgi?id=57493)Create a documentation page for properties - [Bug 59924](https://bz.apache.org/bugzilla/show_bug.cgi?id=59924)The log level of _XXX_ package is set to `DEBUG` if `log_level._XXXX_` property value contains spaces, same for `__log` function - [Bug 59777](https://bz.apache.org/bugzilla/show_bug.cgi?id=59777)Extract SLF4J binding into its own jar and make it a JMeter lib. :::note If you get a warning about multiple SLF4J bindings on startup. Remove either the Apache JMeter provided binding `lib/ApacheJMeter_slf4j_logkit.jar`, or all of the other reported bindings. For more information you can have a look at [SLF4Js own info page.](http://www.slf4j.org/codes.html#multiple_bindings) ::: - [Bug 60085](https://bz.apache.org/bugzilla/show_bug.cgi?id=60085)Remove cache for prepared statements, as it didn't work with the current JDBC pool implementation and current JDBC drivers should support caching of prepared statements themselves. - [Bug 60137](https://bz.apache.org/bugzilla/show_bug.cgi?id=60137)In Distributed testing when using StrippedXXXX modes strip response also on error - [Bug 60106](https://bz.apache.org/bugzilla/show_bug.cgi?id=60106)Settings defaults : Switch "`jmeter.save.saveservice.connect_time`" to true (after 3.0) - [PR#229](https://github.com/apache/jmeter/pull/229) tiny memory allocation improvements. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59945](https://bz.apache.org/bugzilla/show_bug.cgi?id=59945)For all JSR223 elements, if script language has not been chosen on the UI, the script will be interpreted as a groovy script. - [Bug 60266](https://bz.apache.org/bugzilla/show_bug.cgi?id=60266)Usability/ UX : It should not be possible to close/exit/Revert/Load/Load a recent project or create from template a JMeter plan or open a new one if a test is running - [Bug 57305](https://bz.apache.org/bugzilla/show_bug.cgi?id=57305)Remove dependency of `ProxyControl` on `GuiPackage`. Based on patches by jarek102 (jarek102 at gmail.com) and Wyatt Epp (wyatt.epp at gmail.com) ## Non-functional changes - Updated to jsoup-1.10.1 (from 1.8.3) - Updated to ph-css 4.1.6 (from 4.1.4) - Updated to tika-core and tika-parsers 1.14 (from 1.12) - Updated to commons-io 2.5 (from 2.4) - Updated to commons-lang3 3.5 (from 3.4) - Updated to commons-net 3.5 (from 3.4) - Updated to groovy 2.4.7 (from 2.4.6) - Updated to httpcore 4.4.5 (from 4.4.4) - Updated to slf4j-api 1.7.21 (from 1.7.13) - Updated to rsyntaxtextarea-2.6.0 (from 2.5.8) - Updated to xstream 1.4.9 (from 1.4.8) - Updated to jodd 3.7.1 (from 3.6.7.jar) - Updated to xmlgraphics-commons 2.1 (from 2.0.1) - [PR#215](https://github.com/apache/jmeter/pull/215)Reduce duplicated code by using the newly added method `GuiUtils#cancelEditing`. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [PR#218](https://github.com/apache/jmeter/pull/218)Misc cleanup. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [PR#216](https://github.com/apache/jmeter/pull/216)Re-use pattern when possible. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 60364](https://bz.apache.org/bugzilla/show_bug.cgi?id=60364)Document Test Coverage. Contributed by Thomas Schapitz (ts-nospam12 at online.de) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 58888](https://bz.apache.org/bugzilla/show_bug.cgi?id=58888)HTTP(S) Test Script Recorder (ProxyControl) does not add TestElement's returned by `SamplerCreator#createChildren()` - [Bug 59902](https://bz.apache.org/bugzilla/show_bug.cgi?id=59902)Https handshake failure when setting `httpclient.socket.https.cps` property - [Bug 60084](https://bz.apache.org/bugzilla/show_bug.cgi?id=60084)JMeter 3.0 embedded resource URL is silently encoded - [Bug 60376](https://bz.apache.org/bugzilla/show_bug.cgi?id=60376)Http Test Script Recorder : If deflate is used by server then recording may break application #### Other Samplers - [Bug 59113](https://bz.apache.org/bugzilla/show_bug.cgi?id=59113)JDBC Connection Configuration : Transaction Isolation level not correctly set if constant used instead of numerical #### Controllers - [Bug 60361](https://bz.apache.org/bugzilla/show_bug.cgi?id=60361)ModuleController : If a Test plan contains a Module Controller which references an unexistant Controller, JMeter in GUI mode will not stop #### Listeners - [Bug 59712](https://bz.apache.org/bugzilla/show_bug.cgi?id=59712)Display original query in RequestView when decoding fails. Based on a patch by Teemu Vesala (teemu.vesala at qentinel.com) - [Bug 60278](https://bz.apache.org/bugzilla/show_bug.cgi?id=60278)Since 2.13 (and [Bug 57514](https://bz.apache.org/bugzilla/show_bug.cgi?id=57514)), Aggregate Graph, Summary Report and Aggregate Report lost precision in the Error, Rate and Bandwidth values saved in the saved file csv - [Bug 60360](https://bz.apache.org/bugzilla/show_bug.cgi?id=60360)View Result Tree : Request Tab does not show body of a DELETE request #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 59964](https://bz.apache.org/bugzilla/show_bug.cgi?id=59964)JSR223 Test Element : Cache compiled script if available is not correctly reset. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59609](https://bz.apache.org/bugzilla/show_bug.cgi?id=59609)Format extracted JSON Objects in JSON Post Processor correctly as JSON. - [Bug 60332](https://bz.apache.org/bugzilla/show_bug.cgi?id=60332)View Results Tree : With Windows LAF, JSON Extractor does not show JSON Path Expression and Result panel #### Functions #### I18N #### General - [Bug 59400](https://bz.apache.org/bugzilla/show_bug.cgi?id=59400)Get rid of UnmarshalException on stopping when `-X` option is used. - [Bug 59607](https://bz.apache.org/bugzilla/show_bug.cgi?id=59607)JMeter crashes when reading large test plan (greater than 2GB). Based on fix by Felix Draxler (felix.draxler at sap.com) - [Bug 59621](https://bz.apache.org/bugzilla/show_bug.cgi?id=59621)Error count in report dashboard is one off. - [Bug 59657](https://bz.apache.org/bugzilla/show_bug.cgi?id=59657)Only set font in JSyntaxTextArea, when property `jsyntaxtextarea.font.family` is set. - [Bug 59720](https://bz.apache.org/bugzilla/show_bug.cgi?id=59720)Batch test file comparisons fail on Windows as XML files are generated as EOL=LF - Code cleanups. Patches by Graham Russell (graham at ham1.co.uk) - [Bug 59722](https://bz.apache.org/bugzilla/show_bug.cgi?id=59722)Use StandardCharsets to reduce the possibility of misspelling Charset names. - [Bug 59723](https://bz.apache.org/bugzilla/show_bug.cgi?id=59723)Use `jmeter.properties` for testing whenever possible - [Bug 59726](https://bz.apache.org/bugzilla/show_bug.cgi?id=59726)Unit test to check that CSV header text and sample format don't change unexpectedly - [Bug 59889](https://bz.apache.org/bugzilla/show_bug.cgi?id=59889)Change encoding to UTF-8 in reports for dashboard. - [Bug 60053](https://bz.apache.org/bugzilla/show_bug.cgi?id=60053)In Non GUI mode, a Stacktrace is shown at end of test while report is being generated - [Bug 60049](https://bz.apache.org/bugzilla/show_bug.cgi?id=60049)When using Timers with high delays or Constant Throughput Timer with low throughput, Scheduler may take a lot of time to exit, same for Shutdown test - [Bug 60089](https://bz.apache.org/bugzilla/show_bug.cgi?id=60089)Report / Dashboard : Bytes throughput Over Time has reversed Sent and Received bytes. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60090](https://bz.apache.org/bugzilla/show_bug.cgi?id=60090)Report / Dashboard : Empty Transaction Controller should not count in metrics - [Bug 60103](https://bz.apache.org/bugzilla/show_bug.cgi?id=60103)Report / Dashboard : Requests summary includes Transaction Controller leading to wrong percentage - [Bug 60105](https://bz.apache.org/bugzilla/show_bug.cgi?id=60105)Report / Dashboard : Report requires Transaction Controller "`generate parent sample`" option to be checked, fix related issues - [Bug 60107](https://bz.apache.org/bugzilla/show_bug.cgi?id=60107)Report / Dashboard : In StatisticSummary, TransactionController SampleResult makes Total line wrong - [Bug 60110](https://bz.apache.org/bugzilla/show_bug.cgi?id=60110)Report / Dashboard : In Response Time Percentiles, slider is useless - [Bug 60135](https://bz.apache.org/bugzilla/show_bug.cgi?id=60135)Report / Dashboard : Active Threads Over Time should be in OverTime section - [Bug 60125](https://bz.apache.org/bugzilla/show_bug.cgi?id=60125)Report / Dashboard : Dashboard cannot be generated if the default delimiter is `\t`. Based on a report from Tamas Szabadi (tamas.szabadi at rightside.co) - [Bug 59439](https://bz.apache.org/bugzilla/show_bug.cgi?id=59439)Report / Dashboard : AbstractOverTimeGraphConsumer.createGroupInfos() should be abstract - [Bug 59918](https://bz.apache.org/bugzilla/show_bug.cgi?id=59918)Ant generated HTML report is broken (extras folder) - [Bug 60295](https://bz.apache.org/bugzilla/show_bug.cgi?id=60295)JSON Extractor doesn't index array elements when only one element is found. Based on a patch by Roberto Braga (roberto.braga at sociale.it) - [Bug 60299](https://bz.apache.org/bugzilla/show_bug.cgi?id=60299)Thread Group with Scheduler : Weird behaviour when End-Time is in the past ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Felix Draxler (felix.draxler at sap.com) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - Graham Russell (graham at ham1.co.uk) - Teemu Vesala (teemu.vesala at qentinel.com) - Asier Lostalé (asier.lostale at openbravo.com) - Thomas Peyrard (thomas.peyrard at murex.com) - Benoit Wiart (b.wiart at ubik-ingenierie.com) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Ubik Load Pack](http://ubikloadpack.com) - Tamas Szabadi (tamas.szabadi at rightside.co) - Roberto Braga (roberto.braga at soziale.it) - jarek102 at gmail.com - Wyatt Epp (wyatt.epp at gmail.com) - Thomas Schapitz (ts-nospam12 at online.de) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ```json [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK7_u79, JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with JAVA 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 3.0 Summary - [New and Noteworthy](#New and Noteworthy) - [Known bugs](#Known bugs) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Thanks](#Thanks) ## New and Noteworthy ## Test plan creation and debugging improvements ### New Search Feature in View Results Tree to allow searching for text / regexp in Request/Responses/Headers/Cookies/… This will ease correlation and Test plans creation ![changes/3.0/view_results_tree_search_feature.png](/images/screenshots/changes/3.0/view_results_tree_search_feature.png) ### New JSON Post Processor to better extract data from JSON content using user friendly JSON-PATH syntax JSON is now a first class citizen in JMeter with the introduction of a new [JSONPath](http://goessner.net/articles/JsonPath/) post processor. This post processor is very similar to Regular Expression Post Processor but is well suited for JSON code. It is based on [Jayway JSON Path library](https://github.com/jayway/JsonPath) ![changes/3.0/json_path_extractor.png](/images/screenshots/changes/3.0/json_path_extractor.png) ### New validation feature, in one click run a selection of Thread Groups with `1` user, no pause and `1` iteration ![changes/3.0/thread_group_validate.png](/images/screenshots/changes/3.0/thread_group_validate.png) ### JSR223 Test Elements do not require a Cache Compilation Key anymore Just check `Cache compiled script if available` checkbox and the elements (Pre-Processor, Post-Processor, Assertions, Listeners, …) will pre-compile the script and cache the compiled code if the underlying language supports it ![changes/3.0/jsr223_cache_compiled.png](/images/screenshots/changes/3.0/jsr223_cache_compiled.png) ### Nashorn can now be used as Javascript engine providing better performance and easier usage To enable [Nashorn](http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html), you need to set in `user.properties`: ``` javascript.use_rhino=false ``` Nashorn can be used with Java 8 in the following elements: - IfController - JSR223 Test elements with `javascript` language selected - `__javaScript` function ### Jexl3 has been integrated. It provides new scripting features and much better documentation [JEXL3](http://commons.apache.org/proper/commons-jexl/) can now be used thanks to a new function `__jexl3`. JEXL is a language very similar to JSTL. ### Simplified HTTP Request UI A new "`Advanced`" tab has been added to HTTP Request to simplify configuration. The file upload feature has been moved into a dedicated tab. This increases the space available for parameters in UI and simplifies the UX. ![changes/3.0/http_request_basic.png](/images/screenshots/changes/3.0/http_request_basic.png) ![changes/3.0/http_request_advanced.png](/images/screenshots/changes/3.0/http_request_advanced.png) ### HTTP Request Defaults improvements You can now configure Source Address (IP Spoofing like feature) and "`Save response as MD5 hash`" in Advanced Tab ![changes/3.0/http_request_defaults_advanced.png](/images/screenshots/changes/3.0/http_request_defaults_advanced.png) ## Reporting improvements ### New Reporting Feature generating dynamic Graphs in HTML pages (APDEX, Summary report and Graphs) A dynamic HTML report can now be generated either at the end of a load test or from a result file whenever you want. See [Generating dashboard](/./usermanual/generating-dashboard/) for more details. This report provides the following metrics: - [APDEX](https://en.wikipedia.org/wiki/Apdex) (Application Performance Index) table that computes the APDEX based on configurable values for tolerated and satisfied thresholds - A request summary graph showing the Success and failed transaction percentage: ![changes/3.0/report_apdex_and_summary.png](/images/screenshots/changes/3.0/report_apdex_and_summary.png) - A Statistics table providing in one table a summary of all metrics per transaction including 3 configurable percentiles : ![changes/3.0/report_statistics.png](/images/screenshots/changes/3.0/report_statistics.png) - An error table providing a summary of all errors and their proportion in the total requests : ![changes/3.0/report_errors.png](/images/screenshots/changes/3.0/report_errors.png) - Zoomable chart where you can check/uncheck every transaction to show/hide it for: - Response times Over Time : ![changes/3.0/report_response_times_over_time.png](/images/screenshots/changes/3.0/report_response_times_over_time.png) - Bytes throughput Over Time : ![changes/3.0/report_bytes_throughput_over_time.png](/images/screenshots/changes/3.0/report_bytes_throughput_over_time.png) - Latencies Over Time : ![changes/3.0/report_latencies_over_time.png](/images/screenshots/changes/3.0/report_latencies_over_time.png) - Hits per second : ![changes/3.0/report_hits_per_second.png](/images/screenshots/changes/3.0/report_hits_per_second.png) - Response codes per second : ![changes/3.0/report_codes_per_second.png](/images/screenshots/changes/3.0/report_codes_per_second.png) - Transactions per second : ![changes/3.0/report_transactions_per_second.png](/images/screenshots/changes/3.0/report_transactions_per_second.png) - Response Time vs Request per second : ![changes/3.0/report_response_time_vs_request.png](/images/screenshots/changes/3.0/report_response_time_vs_request.png) - Latency vs Request per second : ![changes/3.0/report_latencies_vs_request.png](/images/screenshots/changes/3.0/report_latencies_vs_request.png) - Response times percentiles : ![changes/3.0/report_response_time_percentiles.png](/images/screenshots/changes/3.0/report_response_time_percentiles.png) - Active Threads Over Time : ![changes/3.0/report_active_threads_over_time.png](/images/screenshots/changes/3.0/report_active_threads_over_time.png) - Times vs Threads : ![changes/3.0/report_time_vs_threads.png](/images/screenshots/changes/3.0/report_time_vs_threads.png) - Response Time Distribution : ![changes/3.0/report_response_time_distribution.png](/images/screenshots/changes/3.0/report_response_time_distribution.png) ### GraphiteBackendListener has a new Server Hits metric ### Summariser displays a more readable duration Now duration are display in the format `hours:minutes:seconds` ``` Generate Summary Results + 1 in 00:00:01 = 1.7/s Avg: 1 Min: 1 Max: 1 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0 Generate Summary Results + 138 in 00:00:09 = 16.2/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 9 Started: 9 Finished: 0 Generate Summary Results = 139 in 00:00:09 = 15.3/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 467 in 00:00:10 = 47.0/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 19 Started: 19 Finished: 0 Generate Summary Results = 606 in 00:00:19 = 31.9/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) ⋮ Generate Summary Results + 1662 in 00:00:10 = 166.1/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 28932 in 00:03:19 = 145.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 1664 in 00:00:10 = 166.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 30596 in 00:03:29 = 146.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 1661 in 00:00:10 = 166.1/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 32257 in 00:03:39 = 147.3/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) ``` ### BackendListener now allows you to define sampler list as a regular expression You can now use a regular expression to select the samplers you want to filter. Use parameter: `useRegexpForSamplersList=true` and put a regex in parameter `samplersList` ![changes/3.0/graphite_backend_listener_regex.png](/images/screenshots/changes/3.0/graphite_backend_listener_regex.png) ## Protocols and Load Testing improvements ### Migration to HttpClient 4.5.2 has been started. Although not completely finished, it improves many areas in JMeter Migration to HttpClient 4.5.2 improves the following fields of JMeter: - Support of recent RFC like [HTTP State Management Mechanism RFC-6265 for Cookies](https://tools.ietf.org/html/rfc6265), you should use now `HC4CookieHandler` in HTTP Cookie Manager component and select `standard` Cookie policy - [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) support for HttpClient4 implementation - Improved and better performing validation mechanism for Stale connections and Keep-Alive management, see properties `httpclient4.validate_after_inactivity` and `httpclient4.time_to_live` - Many bug fixes since previous version 4.2.6 used in JMeter 2.13, see [HttpClient 4.5.X release notes](http://www.apache.org/dist/httpcomponents/httpclient/RELEASE_NOTES-4.5.x.txt) - Better support of HTTP RFC 2616 / RFC 7230 and fixes to issues with `deflate` compression management ### Parallel Downloads is now realistic and scales much better: - Parsing of CSS imported files (through `@import`) or embedded resources (background, images, …) - Lazy initialization of SSL context: For 15 Threads 138% more sampling in 5 minutes for HTTP only tests. Gain increases as number of threads increases - Rework of Connection management for Parallel Download: This better simulates current browser behaviour and improves throughput. For 15 Threads 135% extra samples in 5 minutes. - Reuse of Threads used for Parallel downloads through a ThreadPool: This improves throughput and increases JMeter scalability for such tests - Total of 750% more throughput found on test with 15 threads, the more threads you have the more the gain - You can now compute and store just the MD5 of embedded resources instead of storing the entire response, this can be done by setting the property `httpsampler.embedded_resources_use_md5=true` ### Introduction of Sample Timeout feature This new [Sample Timeout](/user-manual/component-reference/#Sample_Timeout) Pre-Processor allows you to apply a Timeout on the elements that are in its scope. In the screenshot below the 10 second timeout applies to the `Debug Sampler` and `HTTP Request` elements. ![changes/3.0/sample_timeout.png](/images/screenshots/changes/3.0/sample_timeout.png) ### JDBC request now uses DBCP2 pool JDBC Request and JDBC Connection Configuration have been updated to replace old Excalibur Pool by Apache Commons DBCP2 pool. As a consequence properties have been migrated to equivalent when available and UI has been updated. Note that unlike Excalibur, Commons DBCP uses the validation query when creating the pool. So make sure the query is valid. The default query suits many databases, but not all - for example Oracle requires '`SELECT 1 FROM DUAL`' or similar. ![changes/3.0/jdbc_connection_configuration.png](/images/screenshots/changes/3.0/jdbc_connection_configuration.png) ## UX Improvements: ### Better display in HiDPI screens See [JMeter with a HiDPI screen on Linux or Windows](/usermanual/hints-and-tips/#hidpi) in Hints and Tips section in user manual ### New Icon look and Logo JMeter has a new Logo created by Felix Schumacher. Icons have also been refreshed to give a more modern style and make them more meaningful ### Lots of fixes of annoying little bugs Around 40 UI fixes have been made to either fix buggy, confusing behaviour or simplify usage by not allowing incompatible options to be selected ### Improved Thread Group UI and related actions (`Start`, `Start No Timers`, `Validate`) Creating and testing a Test Plan before Load Test has been much simplified by allowing you to only start a selection of Thread Group, start them without applying Timers (thus gaining time) or start them using a new Validation mode. This validation mode allows you to start a Thread Group (without modifying it) with 1 thread, 1 iteration and without applying timers. This validation mode can be customized. ![changes/3.0/thread_group_starters.png](/images/screenshots/changes/3.0/thread_group_starters.png) ### New shortcuts - Add most used elements (`Ctrl + 0` … `Ctrl + 9`), configurable through `gui.quick__XXX_` properties - Shortcuts to expand nodes ## Core improvements ### Configuration simplification with better defaults Default values for many properties have been modified to make JMeter configuration optimal Out of the box. Read "Incompatible changes" section for more details. ### Apache Groovy bundled with JMeter [Apache Groovy](http://www.groovy-lang.org/), the well-known JVM scripting language, is now bundled with Apache JMeter in lib folder. This allows you to use it immediately through JSR223 Elements by selecting the Groovy language. ### Superfluous and old properties removed Old properties that existed to maintain backward compatibility or to offer some superfluous customization have been removed. Read "Incompatible changes" section to see which properties have been removed. ### Code and documentation improvements - Migration to Java7 source code and use of its syntactic sugar - Major code cleanups - Full review of documentation and improvement both in content and presentation ### Improvements to unit tests - Migration of many tests to JUnit 4 - Better management of Headless tests - More Unit Tests ### Dependencies refresh Deprecated Libraries dropped or replaced by up to date ones: - Excalibur replaced by commons-dbcp - htmllexer, htmlparser removed - soap removed - jdom removed ### Slf4j can now be used within Plugins and core code You can now use [SLF4J](http://www.slf4j.org/) logging wrapper in your custom plugins or `org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient` subclasses. ## Incompatible changes - Since version 3.0, Groovy-2.4.6 is bundled with JMeter (`lib` folder), ensure you remove old version or referenced versions through properties `search_paths` or `user.classpath` - Since version 3.0, `jmeter.save.saveservice.assertion_results_failure_message` property value is true, meaning CSV file for results will contain an additional column containing assertion result response message, see [Bug 58978](https://bz.apache.org/bugzilla/show_bug.cgi?id=58978) - Since version 3.0, `jmeter.save.saveservice.print_field_names` property value is true, meaning CSV file for results will contain field names as first line in CSV, see [Bug 58991](https://bz.apache.org/bugzilla/show_bug.cgi?id=58991) - Since version 3.0, `jmeter.save.saveservice.idle_time` property value is true, meaning CSV/XML result files will contain an additional column containing idle time between samplers, see [Bug 57182](https://bz.apache.org/bugzilla/show_bug.cgi?id=57182) - In RandomTimer class, protected instance `timer` field has been replaced by `getTimer()` protected method, this is related to [Bug 58100](https://bz.apache.org/bugzilla/show_bug.cgi?id=58100). This may impact 3rd party plugins. - Since version 3.0, you can use Nashorn Engine (default javascript engine is Rhino) under Java8 for Elements that use Javascript Engine (`__javaScript`, `IfController`). If you want to use it, use property `javascript.use_rhino=false`, see [Bug 58406](https://bz.apache.org/bugzilla/show_bug.cgi?id=58406). :::note Note: in a future version, we will switch to Nashorn by default. Users are encouraged to report any issue related to using Nashorn instead of Rhino. ::: - Since version 3.0, JMS Publisher will reload contents of file if Message source is "`From File`" and the "`Filename`" field changes (e.g. if it uses a variable that has changed) - `org.apache.jmeter.gui.util.ButtonPanel` has been removed, if you use it in your 3rd party plugin or custom development ensure you update your code. See [Bug 58687](https://bz.apache.org/bugzilla/show_bug.cgi?id=58687) - Property `jmeterthread.startearlier` has been removed. See [Bug 58726](https://bz.apache.org/bugzilla/show_bug.cgi?id=58726) - Property `jmeterengine.startlistenerslater` has been removed. See [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728) - Property `jmeterthread.reversePostProcessors` has been removed. See [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728) - Property `jmeter.toolbar.display` has been removed, the toolbar is now always displayed. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Property `jmeter.errorscounter.display` has been removed, the errors/warnings counter is now always displayed. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Property `xml.parser` has been removed, it is not used anymore as `org.apache.jmeter.util.JMeterUtils#getXMLParser` has been deprecated and is not used either. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Summariser listener now shows the duration in the format `HH:mm:ss` (Hour:Minute:Second), it previously showed the duration in seconds. See [Bug 58776](https://bz.apache.org/bugzilla/show_bug.cgi?id=58776) - `org.apache.jmeter.protocol.http.visualizers.RequestViewHTTP.getQueryMap` signature has changed, if you use it ensure you update your code. See [Bug 58845](https://bz.apache.org/bugzilla/show_bug.cgi?id=58845) - JMS Subscriber will consider a sample to be an error if the number of received messages is not equal to expected number of messages. It previously considered a sample OK if at least 1 message was received. See [Bug 58980](https://bz.apache.org/bugzilla/show_bug.cgi?id=58980) - Since version 3.0, HTTP(S) Test Script recorder defaults to using port `8888` (as configured when using Recording Template). See [Bug 59006](https://bz.apache.org/bugzilla/show_bug.cgi?id=59006) - Since version 3.0, the parser for embedded resources (replaced since 2.10 by Lagarto based implementation) which relied on the htmlparser library (HtmlParserHTMLParser) has been dropped along with its dependencies. - Since version 3.0, support for reading old Avalon format JTL (result) files has been removed, see [Bug 59064](https://bz.apache.org/bugzilla/show_bug.cgi?id=59064) - Since version 3.0, the default property value for `http.java.sampler.retries` has been changed to `0` (no retry by default) to align it with the behaviour of HttpClient4. :::note Note also that its meaning has changed: before 3.0, `http.java.sampler.retries=1` meant `No Retry` (i.e. total tries = 1), since 3.0 `http.java.sampler.retries=1` means `1` retry. (Note: this only applies to the Java HTTP Sampler) ::: See [Bug 59103](https://bz.apache.org/bugzilla/show_bug.cgi?id=59103) - Since 3.0, the following deprecated classes have been dropped - org.apache.jmeter.protocol.http.modifier.UserParameterXMLContentHandler - org.apache.jmeter.protocol.http.modifier.UserParameterXMLErrorHandler - org.apache.jmeter.protocol.http.modifier.UserParameterXMLParser - `httpsampler.await_termination_timeout` has been replaced by `httpsampler.parallel_download_thread_keepalive_inseconds` which is now the keep alive time for the parallel download threads (in seconds). - JDBC Request has been updated to use commons-dbcp2, since then the behaviour is slightly different, ensure you have a correct "Validation Query" for your database. See [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786) - The following jars have been removed: - excalibur-datasource-2.1.jar (see [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)) - excalibur-instrument-1.0.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-api-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-impl-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-instrumented-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - htmllexer-2.1.jar (see [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)) - htmlparser-2.1.jar (see [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)) - soap-2.3.1.jar - jdom-1.1.3.jar (see [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)) - Maximum number of redirects allowed by JMeter is now 20, it was previously 5. This can be changed with the property `httpsampler.max_redirects`. See [Bug 59382](https://bz.apache.org/bugzilla/show_bug.cgi?id=59382) #### Deprecated and removed elements - MongoDB elements (MongoDB Source Config, MongoDB Script) have been deprecated and will be removed in the next version of JMeter. They do not appear anymore in the menu, if you need them modify `not_in_menu` property. The JMeter team advises not to use them anymore. See [Bug 58772](https://bz.apache.org/bugzilla/show_bug.cgi?id=58772) - WebService(SOAP) Request and HTML Parameter Mask which were deprecated in 2.13 version, have now been removed following our [deprecation strategy](/./usermanual/best-practices/#deprecation). Classes and properties which were only used by those elements have been dropped: - `org.apache.jmeter.protocol.http.util.DOMPool` - `org.apache.jmeter.protocol.http.util.WSDLException` - `org.apache.jmeter.protocol.http.util.WSDLHelper` - Property `soap.document_cache` - JAR soap-2.3.1 has been also removed - `__jexl` function (i.e. JEXL 1) has been deprecated and will be removed in next version. See [Bug 58903](https://bz.apache.org/bugzilla/show_bug.cgi?id=58903) - Spline Visualizer listener and Distribution Graph listener have been deprecated and will be removed in the next version of JMeter. They do not appear anymore in the menu, if you need them modify `not_in_menu` property. JMeter team advises not to use them anymore. See [Bug 58791](https://bz.apache.org/bugzilla/show_bug.cgi?id=58791) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 57696](https://bz.apache.org/bugzilla/show_bug.cgi?id=57696)HTTP Request : Improve responseMessage when resource download fails. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57995](https://bz.apache.org/bugzilla/show_bug.cgi?id=57995)Use FileServer for HTTP Request files. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 58843](https://bz.apache.org/bugzilla/show_bug.cgi?id=58843)Improve the usable space in the HTTP sampler GUI. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58852](https://bz.apache.org/bugzilla/show_bug.cgi?id=58852)Use less memory for `PUT` requests. The uploaded data will no longer be stored in the Sampler. This is the same behaviour as with `POST` requests. - [Bug 58860](https://bz.apache.org/bugzilla/show_bug.cgi?id=58860)HTTP Request : Add automatic variable generation in HTTP parameters table by right click. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58923](https://bz.apache.org/bugzilla/show_bug.cgi?id=58923)normalize URIs when downloading embedded resources. - [Bug 59005](https://bz.apache.org/bugzilla/show_bug.cgi?id=59005)HTTP Sampler : Added WebDAV verb (`SEARCH`). - [Bug 59006](https://bz.apache.org/bugzilla/show_bug.cgi?id=59006)Change Default proxy recording port to `8888` to align it with Recording Template. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58099](https://bz.apache.org/bugzilla/show_bug.cgi?id=58099)Performance : Lazily initialize HttpClient SSL Context to avoid its initialization even for HTTP only scenarios - [Bug 57577](https://bz.apache.org/bugzilla/show_bug.cgi?id=57577)HttpSampler : Retrieve All Embedded Resources, add property "`httpsampler.embedded_resources_use_md5`" to only compute md5 and not keep response data. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59023](https://bz.apache.org/bugzilla/show_bug.cgi?id=59023)HttpSampler UI : rework the embedded resources labels and change default number of parallel downloads to `6`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59028](https://bz.apache.org/bugzilla/show_bug.cgi?id=59028)Use `SystemDefaultDnsResolver` singleton. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59036](https://bz.apache.org/bugzilla/show_bug.cgi?id=59036)FormCharSetFinder : Use JSoup instead of deprecated HTMLParser - [Bug 59034](https://bz.apache.org/bugzilla/show_bug.cgi?id=59034)Parallel downloads connection management is not realistic. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) and Philippe Mouawad - [Bug 59060](https://bz.apache.org/bugzilla/show_bug.cgi?id=59060)HTTP Request GUI : Move File Upload to a new Tab to have more space for parameters and prevent incompatible configuration. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59103](https://bz.apache.org/bugzilla/show_bug.cgi?id=59103)HTTP Request Java Implementation: Change default "`http.java.sampler.retries`" to align it on HttpClient behaviour and make the name meaningful - [Bug 59083](https://bz.apache.org/bugzilla/show_bug.cgi?id=59083)HTTP Request : Make Method field editable so that additional methods (WebDAV) can be added easily - [Bug 59118](https://bz.apache.org/bugzilla/show_bug.cgi?id=59118)Add comment in recorded think time by proxy recorder. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59116](https://bz.apache.org/bugzilla/show_bug.cgi?id=59116)Add the possibility to setup a prefix to sampler name recorded by proxy. Partly based on a patch by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59129](https://bz.apache.org/bugzilla/show_bug.cgi?id=59129)HTTP Request : Simplify GUI with simple/advanced Tabs - [Bug 59033](https://bz.apache.org/bugzilla/show_bug.cgi?id=59033)Parallel Download : Rework Parser classes hierarchy to allow plug-in parsers for different mime types - [Bug 52073](https://bz.apache.org/bugzilla/show_bug.cgi?id=52073)Embedded Resources Parallel download : Improve performances by avoiding shutdown of ThreadPoolExecutor at each sample. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59190](https://bz.apache.org/bugzilla/show_bug.cgi?id=59190)HTTP(S) Test Script Recorder : Suggested excludes should ignore case. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59140](https://bz.apache.org/bugzilla/show_bug.cgi?id=59140)Parallel Download : Add CSS Parsing to extract links from CSS files - [Bug 59249](https://bz.apache.org/bugzilla/show_bug.cgi?id=59249)Http Request Defaults : Add "`Source address`" and "`Save responses as MD5`" - [Bug 59382](https://bz.apache.org/bugzilla/show_bug.cgi?id=59382)More realistic default value for `httpsampler.max_redirects` #### Other samplers - [Bug 57928](https://bz.apache.org/bugzilla/show_bug.cgi?id=57928)Add ability to define protocol (http/https) to AccessLogSampler GUI. Contributed by Jérémie Lesage (jeremie.lesage at jeci.fr) - [Bug 58300](https://bz.apache.org/bugzilla/show_bug.cgi?id=58300)Make existing Java Samplers implement Interruptible - [Bug 58160](https://bz.apache.org/bugzilla/show_bug.cgi?id=58160)JMS Publisher : reload file content if file name changes. Based partly on a patch contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)JDBC Sampler : Replace Excalibur DataSource by more up to date library commons-dbcp2 - [Bug 59205](https://bz.apache.org/bugzilla/show_bug.cgi?id=59205)TCP Sampler: Set connect time in sampler when connection is established. - [Bug 59381](https://bz.apache.org/bugzilla/show_bug.cgi?id=59381)JMSPublisher : FileChooserDialog filter does not work for browser buttons. Based partly on a patch contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### Controllers - [Bug 58406](https://bz.apache.org/bugzilla/show_bug.cgi?id=58406)IfController : Allow use of Nashorn Engine if available for JavaScript evaluation - [Bug 58281](https://bz.apache.org/bugzilla/show_bug.cgi?id=58281)RandomOrderController : Improve randomization algorithm performance. Contributed by Graham Russell (jmeter at ham1.co.uk) - [Bug 58675](https://bz.apache.org/bugzilla/show_bug.cgi?id=58675)Module controller : error message can easily be missed. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58673](https://bz.apache.org/bugzilla/show_bug.cgi?id=58673)Module controller : when the target element is disabled the default jtree icons are displayed. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58674](https://bz.apache.org/bugzilla/show_bug.cgi?id=58674)Module controller : it should not be possible to select more than one node in the tree. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58680](https://bz.apache.org/bugzilla/show_bug.cgi?id=58680)Module Controller : ui enhancement. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58989](https://bz.apache.org/bugzilla/show_bug.cgi?id=58989)Record controller gui : add a button to clear all the recorded samples. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Listeners - [Bug 58041](https://bz.apache.org/bugzilla/show_bug.cgi?id=58041)Tree View Listener should show sample data type - [Bug 58122](https://bz.apache.org/bugzilla/show_bug.cgi?id=58122)GraphiteBackendListener : Add Server Hits metric. Partly based on a patch from Amol Moye (amol.moye at thomsonreuters.com) - [Bug 58681](https://bz.apache.org/bugzilla/show_bug.cgi?id=58681)GraphiteBackendListener : Don't send data if no sampling occurred - [Bug 58776](https://bz.apache.org/bugzilla/show_bug.cgi?id=58776)Summariser should display a more readable duration - [Bug 58791](https://bz.apache.org/bugzilla/show_bug.cgi?id=58791)Deprecate listeners: Distribution Graph (alpha) and Spline Visualizer - [Bug 58849](https://bz.apache.org/bugzilla/show_bug.cgi?id=58849)View Results Tree : Add a search panel to the request http view to be able to search in the parameters table. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58857](https://bz.apache.org/bugzilla/show_bug.cgi?id=58857)View Results Tree : the request view http does not allow to resize the parameters table first column. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58955](https://bz.apache.org/bugzilla/show_bug.cgi?id=58955)Request view http does not correctly display http parameters in multipart/form-data. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 55597](https://bz.apache.org/bugzilla/show_bug.cgi?id=55597)View Results Tree: Add a search feature to search in recorded samplers - [Bug 59102](https://bz.apache.org/bugzilla/show_bug.cgi?id=59102)View Results Tree: Better default value for "`view.results.tree.max_size`" - [Bug 59099](https://bz.apache.org/bugzilla/show_bug.cgi?id=59099)Backend listener : Add the possibility to consider samplersList as a Regular Expression. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59424](https://bz.apache.org/bugzilla/show_bug.cgi?id=59424)Visualizer : Add "Clear" in popup menu #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58303](https://bz.apache.org/bugzilla/show_bug.cgi?id=58303)Change usage of bouncycastle api in SMIMEAssertion to get rid of deprecation warnings. - [Bug 58515](https://bz.apache.org/bugzilla/show_bug.cgi?id=58515)New JSON related components : JSON-PATH Extractor and JSON-PATH Renderer in View Results Tree. Donated by Ubik Load Pack (support at ubikloadpack.com). - [Bug 58698](https://bz.apache.org/bugzilla/show_bug.cgi?id=58698)Correct parsing of auth-files in HTTP Authorization Manager. - [Bug 58756](https://bz.apache.org/bugzilla/show_bug.cgi?id=58756)CookieManager : Cookie Policy select box content must depend on Cookie implementation. - [Bug 56358](https://bz.apache.org/bugzilla/show_bug.cgi?id=56358)Cookie manager supports cross port cookies and RFC6265. Thanks to Oleg Kalnichevski (olegk at apache.org) - [Bug 58773](https://bz.apache.org/bugzilla/show_bug.cgi?id=58773)TestCacheManager : Add tests for CacheManager that use HttpClient 4 - [Bug 58742](https://bz.apache.org/bugzilla/show_bug.cgi?id=58742)CompareAssertion : Reset data in TableEditor when switching between different CompareAssertions in gui. Based on a patch by Vincent Herilier (vherilier at gmail.com) - [Bug 59108](https://bz.apache.org/bugzilla/show_bug.cgi?id=59108)TableEditor: Allow rows to be moved up and down. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 58848](https://bz.apache.org/bugzilla/show_bug.cgi?id=58848)Argument Panel : when adding an argument (add button or from clipboard) scroll the table to the new line. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58865](https://bz.apache.org/bugzilla/show_bug.cgi?id=58865)Allow empty default value in the Regular Expression Extractor. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)XMLAssertion : drop jdom dependency by using XMLReader - [Bug 59328](https://bz.apache.org/bugzilla/show_bug.cgi?id=59328)Better tooltip for Variable Names in CSVDataSet. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### Functions - [Bug 58477](https://bz.apache.org/bugzilla/show_bug.cgi?id=58477) __javaScript function : Allow use of Nashorn engine for Java8 and later versions - [Bug 58903](https://bz.apache.org/bugzilla/show_bug.cgi?id=58903)Provide __jexl3 function that uses commons-jexl3 and deprecated __jexl (1.1) function #### I18N #### General - [Bug 58736](https://bz.apache.org/bugzilla/show_bug.cgi?id=58736)Add Sample Timeout support - [Bug 57913](https://bz.apache.org/bugzilla/show_bug.cgi?id=57913)Automated backups of last saved JMX files. Contributed by Benoit Vatan (benoit.vatan at gmail.com) - [Bug 57988](https://bz.apache.org/bugzilla/show_bug.cgi?id=57988)Shortcuts (`Ctrl + 1` … `Ctrl + 9`) to quickly add elements into test plan. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 58100](https://bz.apache.org/bugzilla/show_bug.cgi?id=58100)Performance enhancements : Replace Random by ThreadLocalRandom. - [Bug 58677](https://bz.apache.org/bugzilla/show_bug.cgi?id=58677)`TestSaveService#testLoadAndSave` use the wrong set of files. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58689](https://bz.apache.org/bugzilla/show_bug.cgi?id=58689)Add shortcuts to expand / collapse a part of the tree. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58696](https://bz.apache.org/bugzilla/show_bug.cgi?id=58696)Create Ant task to setup Eclipse project - [Bug 58653](https://bz.apache.org/bugzilla/show_bug.cgi?id=58653)New JMeter Dashboard/Report with Dynamic Graphs, Tables to help analyzing load test results. Developed by Ubik-Ingenierie and contributed by Decathlon S.A. and Ubik-Ingenierie / UbikLoadPack - [Bug 58699](https://bz.apache.org/bugzilla/show_bug.cgi?id=58699)Workbench changes neither saved nor prompted for saving upon close. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728)Drop old behavioural properties - [Bug 57319](https://bz.apache.org/bugzilla/show_bug.cgi?id=57319)Upgrade to HttpClient 4.5.2. With the big help from Oleg Kalnichevski (olegk at apache.org) and Gary Gregory (ggregory at apache.org). - [Bug 58772](https://bz.apache.org/bugzilla/show_bug.cgi?id=58772)Deprecate MongoDB related elements - [Bug 58782](https://bz.apache.org/bugzilla/show_bug.cgi?id=58782)ThreadGroup : Improve ergonomy - [Bug 58165](https://bz.apache.org/bugzilla/show_bug.cgi?id=58165)Show the time elapsed since the start of the load test in GUI mode. Partly based on a contribution from Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 58814](https://bz.apache.org/bugzilla/show_bug.cgi?id=58814)JVM no longer recognizes option `MaxLiveObjectEvacuationRatio`; remove from comments - [Bug 58810](https://bz.apache.org/bugzilla/show_bug.cgi?id=58810)Config Element Counter (and others): Check Boxes Toggle Area Too Big - [Bug 56554](https://bz.apache.org/bugzilla/show_bug.cgi?id=56554)JSR223 Test Element : Generate compilation cache key automatically. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58911](https://bz.apache.org/bugzilla/show_bug.cgi?id=58911)Header Manager : it should be possible to copy/paste between Header Managers. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58864](https://bz.apache.org/bugzilla/show_bug.cgi?id=58864)Arguments Panel : when moving parameter with up / down, ensure that the selection remains visible. Based on a contribution by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58968](https://bz.apache.org/bugzilla/show_bug.cgi?id=58968)Add a new template to allow to record script with think time included. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58978](https://bz.apache.org/bugzilla/show_bug.cgi?id=58978)Settings defaults : Switch "`jmeter.save.saveservice.assertion_results_failure_message`" to true (after 2.13) - [Bug 58991](https://bz.apache.org/bugzilla/show_bug.cgi?id=58991)Settings defaults : Switch "`jmeter.save.saveservice.print_field_names`" to true (after 2.13) - [Bug 57182](https://bz.apache.org/bugzilla/show_bug.cgi?id=57182)Settings defaults : Switch "`jmeter.save.saveservice.idle_time`" to true (after 2.13) - [Bug 58870](https://bz.apache.org/bugzilla/show_bug.cgi?id=58870)TableEditor: minimum size is too small. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 58933](https://bz.apache.org/bugzilla/show_bug.cgi?id=58933)JSyntaxTextArea : Ability to set font. Contributed by Denis Kirpichenkov (denis.kirpichenkov at gmail.com) - [Bug 58793](https://bz.apache.org/bugzilla/show_bug.cgi?id=58793)Create developers page explaining how to build and contribute - [Bug 59046](https://bz.apache.org/bugzilla/show_bug.cgi?id=59046)JMeter Gui Replace controller should keep the name and the selection. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59038](https://bz.apache.org/bugzilla/show_bug.cgi?id=59038)Deprecate HTTPClient 3.1 related elements - [Bug 59094](https://bz.apache.org/bugzilla/show_bug.cgi?id=59094)Drop support of old JMX file format - [Bug 59082](https://bz.apache.org/bugzilla/show_bug.cgi?id=59082)Remove the "`TestCompiler.useStaticSet`" parameter. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59093](https://bz.apache.org/bugzilla/show_bug.cgi?id=59093)Option parsing error message can be '_lost_' - [Bug 58715](https://bz.apache.org/bugzilla/show_bug.cgi?id=58715)Feature request: Bundle `groovy-all` with JMeter - [Bug 58426](https://bz.apache.org/bugzilla/show_bug.cgi?id=58426)Improve display of JMeter on high resolution devices (HiDPI) (part 1 of enhancement) - [Bug 59105](https://bz.apache.org/bugzilla/show_bug.cgi?id=59105)TableEditor : Add ability to paste rows from clipboard and delete multiple selection. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 59197](https://bz.apache.org/bugzilla/show_bug.cgi?id=59197)Thread Group : it should be possible to only run a single threadgroup or a selection of threadgroups with a popup menu. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59207](https://bz.apache.org/bugzilla/show_bug.cgi?id=59207)Change the font color of `errorsOrFatalsLabel` to red when an error occurs. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58941](https://bz.apache.org/bugzilla/show_bug.cgi?id=58941)Create a new Starter that runs thread groups in validation mode (`1` thread only, `1` iteration, no pause all customizable) - [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236)JMeter Properties : Make some cleanup - [Bug 59240](https://bz.apache.org/bugzilla/show_bug.cgi?id=59240)Introduce a slf4j adapter for Logkit (this allows using slf4j within plugins and core code) - [Bug 59153](https://bz.apache.org/bugzilla/show_bug.cgi?id=59153)Stop test if CSVDataSet is accessing non-existing file. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59320](https://bz.apache.org/bugzilla/show_bug.cgi?id=59320)Better tooltip in GUI with GenericTestBeanCustomizer (CSV Data Set Config, JDBC Connection Configuration, Keystore Configuration, …) . Based on a patch by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59171](https://bz.apache.org/bugzilla/show_bug.cgi?id=59171)Sample Result SaveConfig Dialog is generated in random order - [Bug 59425](https://bz.apache.org/bugzilla/show_bug.cgi?id=59425)Display error about missing help page inside the help pane ## Non-functional changes - Updated to httpclient, httpmime 4.5.2 (from 4.2.6) - Updated to tika-core and tika-parsers 1.12 (from 1.7) - Updated to commons-math3 3.6.1 (from 3.4.1) - Updated to commons-pool2 2.4.2 (from 2.3) - Updated to commons-lang 3.4 (from 3.3.2) - Updated to rhino-1.7.7.1 (from 1.7R5) - Updated to jodd-3.6.7.jar (from 3.6.4) - Updated to jsoup-1.8.3 (from 1.8.1) - Updated to rsyntaxtextarea-2.5.8 (from 2.5.6) - Updated to slf4j-1.7.12 (from 1.7.10) - Updated to xmlgraphics-commons-2.0.1 (from 1.5) - Updated to commons-collections-3.2.2 (from 3.2.1) - Updated to commons-net 3.4 (from 3.3) - Updated to slf4j 1.7.13 (from 1.7.12) - [Bug 57981](https://bz.apache.org/bugzilla/show_bug.cgi?id=57981)Require a minimum of Java 7. Partly contributed by Graham Russell (jmeter at ham1.co.uk) - [Bug 58684](https://bz.apache.org/bugzilla/show_bug.cgi?id=58684)JMeterColor does not need to extend `java.awt.Color`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58687](https://bz.apache.org/bugzilla/show_bug.cgi?id=58687)ButtonPanel should die. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58705](https://bz.apache.org/bugzilla/show_bug.cgi?id=58705)Make `org.apache.jmeter.testelement.property.MultiProperty` iterable. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58729](https://bz.apache.org/bugzilla/show_bug.cgi?id=58729)Cleanup extras folder for maintainability - [Bug 57110](https://bz.apache.org/bugzilla/show_bug.cgi?id=57110)Fixed spelling+grammar, formatting, removed commented out code etc. Contributed by Graham Russell (jmeter at ham1.co.uk) - Correct instructions on running JMeter in `help.txt`. Contributed by Pascal Schumacher (pascalschumacher at gmx.net) - [Bug 58704](https://bz.apache.org/bugzilla/show_bug.cgi?id=58704)Non regression testing : Ant task batchtest fails if tests and run in a non `en_EN` locale and use a JMX file that uses a CSV DataSet - [Bug 58897](https://bz.apache.org/bugzilla/show_bug.cgi?id=58897)Improve JUnit Test code. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58949](https://bz.apache.org/bugzilla/show_bug.cgi?id=58949)Cleanup of LDAP code. Based on a patch by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58897](https://bz.apache.org/bugzilla/show_bug.cgi?id=58897)Improve JUnit Test code. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58967](https://bz.apache.org/bugzilla/show_bug.cgi?id=58967)Use JUnit categories to exclude tests that need a gui. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59003](https://bz.apache.org/bugzilla/show_bug.cgi?id=59003)`ClutilTestCase` `testSingleArg8` and `testSingleArg9` are identical - [Bug 59064](https://bz.apache.org/bugzilla/show_bug.cgi?id=59064)Remove OldSaveService which supported very old Avalon format JTL (result) files - [Bug 59165](https://bz.apache.org/bugzilla/show_bug.cgi?id=59165)RSyntaxTextArea not compatible with headless testing - [Bug 59021](https://bz.apache.org/bugzilla/show_bug.cgi?id=59021)Use `Double#compare` instead of reimplementing it in `NumberProperty#compareTo` - [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)Drop HtmlParserHTMLParser and dependencies on htmlparser and htmllexer - [Bug 58465](https://bz.apache.org/bugzilla/show_bug.cgi?id=58465)JMS Read response field is badly named and documented - [Bug 58601](https://bz.apache.org/bugzilla/show_bug.cgi?id=58601)Change check for modification of `saveservice.properties` from `SVN Revision ID` to sha1 sum of the file itself. - [Bug 58726](https://bz.apache.org/bugzilla/show_bug.cgi?id=58726)Remove the `jmeterthread.startearlier` parameter. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58784](https://bz.apache.org/bugzilla/show_bug.cgi?id=58784)Make `JMeterUtils#runSafe` sync/async awt invocation configurable and change the visualizers to use the async version. - [Bug 58790](https://bz.apache.org/bugzilla/show_bug.cgi?id=58790)Issue in CheckDirty and its relation to ActionRouter - [Bug 59095](https://bz.apache.org/bugzilla/show_bug.cgi?id=59095)Remove UserParameterXMLParser that was deprecated eight years ago. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59262](https://bz.apache.org/bugzilla/show_bug.cgi?id=59262)Add list of binary jars to LICENSE; use that for unit tests - [Bug 59353](https://bz.apache.org/bugzilla/show_bug.cgi?id=59353)Add "Deprecated and removed elements" in "Incompatible changes" part in changes.xml. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 57806](https://bz.apache.org/bugzilla/show_bug.cgi?id=57806)"`audio/x-mpegurl`" mime type is erroneously considered as binary by ViewResultsTree. Contributed by Ubik Load Pack (support at ubikloadpack.com). - [Bug 57858](https://bz.apache.org/bugzilla/show_bug.cgi?id=57858)Don't call `sampleEnd` twice in HTTPHC4Impl when a `RuntimeException` or an `IOException` occurs in the sample method. - [Bug 57921](https://bz.apache.org/bugzilla/show_bug.cgi?id=57921)HTTP/1.1 without keep-alive "`Connection`" response header no longer uses infinite keep-alive. - [Bug 57956](https://bz.apache.org/bugzilla/show_bug.cgi?id=57956)The `hc.parameters` reference in `jmeter.properties` doesn't work when JMeter is not started in `bin`. - [Bug 58137](https://bz.apache.org/bugzilla/show_bug.cgi?id=58137)JMeter fails to download embedded URLs that contain illegal characters in URL (it does not escape them). - [Bug 58201](https://bz.apache.org/bugzilla/show_bug.cgi?id=58201)Make usage of port in the host header more consistent across the different http samplers. - [Bug 58453](https://bz.apache.org/bugzilla/show_bug.cgi?id=58453)HTTP Test Script Recorder : `NullPointerException` when disabling Capture HTTP Headers - [Bug 57804](https://bz.apache.org/bugzilla/show_bug.cgi?id=57804)HTTP Request doesn't reuse cached SSL context when using Client Certificates in HTTPS (only fixed for HttpClient4 implementation) - [Bug 58800](https://bz.apache.org/bugzilla/show_bug.cgi?id=58800)`proxy.pause` default value: fix documentation - [Bug 58844](https://bz.apache.org/bugzilla/show_bug.cgi?id=58844)Buttons enable / disable is broken in the arguments panel. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58861](https://bz.apache.org/bugzilla/show_bug.cgi?id=58861)When clicking on up, down or detail while in a cell of the argument panel, newly added content is lost. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 57935](https://bz.apache.org/bugzilla/show_bug.cgi?id=57935)SSL SNI extension not supported by HttpClient 4.2.6 - [Bug 59044](https://bz.apache.org/bugzilla/show_bug.cgi?id=59044)Http Sampler : It should not be possible to select the multipart encoding if the method is not `POST`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59008](https://bz.apache.org/bugzilla/show_bug.cgi?id=59008)Http Sampler: Infinite recursion SampleResult on frame depth limit reached - [Bug 58881](https://bz.apache.org/bugzilla/show_bug.cgi?id=58881)HTTP Request : HTTPHC4Impl shows exception when server uses "`deflate`" compression - [Bug 58583](https://bz.apache.org/bugzilla/show_bug.cgi?id=58583)HTTP client fails to close connection if server misbehaves by not sending "`connection: close`", violating HTTP RFC 2616 / RFC 7230 - [Bug 58950](https://bz.apache.org/bugzilla/show_bug.cgi?id=58950)`NoHttpResponseException` when Pause between samplers exceeds keepalive sent by server - [Bug 59085](https://bz.apache.org/bugzilla/show_bug.cgi?id=59085)Http file panel : data lost on browse cancellation. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 56141](https://bz.apache.org/bugzilla/show_bug.cgi?id=56141)Application does not behave correctly when using HTTP Recorder. With the help of Dan (java.junkee at yahoo.com) - [Bug 59079](https://bz.apache.org/bugzilla/show_bug.cgi?id=59079)"`httpsampler.max_redirects`" property is not enforced when "`Redirect Automatically`" is used - [Bug 58811](https://bz.apache.org/bugzilla/show_bug.cgi?id=58811)When pasting arguments between http samplers the column "Encode" and "Include Equals" are lost. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Other Samplers - [Bug 58013](https://bz.apache.org/bugzilla/show_bug.cgi?id=58013)Enable all protocols that are enabled on the default SSLContext for usage with the SMTP Sampler. - [Bug 58209](https://bz.apache.org/bugzilla/show_bug.cgi?id=58209)JMeter hang when testing javasampler because `HashMap.put()` is called from multiple threads without sync. - [Bug 58301](https://bz.apache.org/bugzilla/show_bug.cgi?id=58301)Use typed methods such as `setInt`, `setDouble`, `setDate`, … for prepared statement #27 - [Bug 58851](https://bz.apache.org/bugzilla/show_bug.cgi?id=58851)Add a dependency on hamcrest-core to allow JUnit tests with annotations to work - [Bug 58947](https://bz.apache.org/bugzilla/show_bug.cgi?id=58947)Connect metric is wrong when `ConnectException` occurs - [Bug 58980](https://bz.apache.org/bugzilla/show_bug.cgi?id=58980)JMS Subscriber will return successful as long as 1 message is received. Contributed by Harrison Termotto (harrison dot termotto at stonybrook.edu) - [Bug 59075](https://bz.apache.org/bugzilla/show_bug.cgi?id=59075)JMS Publisher: `NumberFormatException` is thrown if priority or expiration field is empty - [Bug 59345](https://bz.apache.org/bugzilla/show_bug.cgi?id=59345)SMTPSampler connection leak. Based on a patch by Luca Maragnani (luca dot maragnani at gmail dot com) #### Controllers - [Bug 58600](https://bz.apache.org/bugzilla/show_bug.cgi?id=58600)Display correct filenames, when they are searched by IncludeController - [Bug 58678](https://bz.apache.org/bugzilla/show_bug.cgi?id=58678)Module Controller : limit target element selection. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58714](https://bz.apache.org/bugzilla/show_bug.cgi?id=58714)Module controller : it should not be possible to add a timer as child. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59067](https://bz.apache.org/bugzilla/show_bug.cgi?id=59067)JMeter fails to iterate over Controllers that are children of a TransactionController having "`Generate parent sample`" checked after an assertion error occurs on a Thread Group with "`Start Next Thread Loop`". Contributed by Benoit Wiart(benoit dot wiart at gmail.com) - [Bug 59076](https://bz.apache.org/bugzilla/show_bug.cgi?id=59076)Test should fail if a module controller cannot find its replacement subtree #### Listeners - [Bug 58033](https://bz.apache.org/bugzilla/show_bug.cgi?id=58033)SampleResultConverter should note that it cannot record non-TEXT data - [Bug 58845](https://bz.apache.org/bugzilla/show_bug.cgi?id=58845)Request http view doesn't display all the parameters. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58413](https://bz.apache.org/bugzilla/show_bug.cgi?id=58413)ViewResultsTree : Request HTTP Renderer does not show correctly parameters that contain ampersand (&). Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59172](https://bz.apache.org/bugzilla/show_bug.cgi?id=59172)SampleResult SaveConfig does not allow some fields to be disabled - [Bug 58329](https://bz.apache.org/bugzilla/show_bug.cgi?id=58329)Response Time Graph and Aggregate Graph : Save graph to file does not take into account the settings changed since last click on Graph. Contributed by David Coppens (d.l.coppens at gmail.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58079](https://bz.apache.org/bugzilla/show_bug.cgi?id=58079)Do not cache HTTP samples that have a `Vary` header when using a HTTP CacheManager. - [Bug 58912](https://bz.apache.org/bugzilla/show_bug.cgi?id=58912)Response assertion gui : Deleting more than 1 selected row deletes only one row. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Functions - [Bug 57825](https://bz.apache.org/bugzilla/show_bug.cgi?id=57825)__Random function fails if `min` value is equal to `max` value (regression related to [Bug 54453](https://bz.apache.org/bugzilla/show_bug.cgi?id=54453)) #### I18N #### General - [Bug 54826](https://bz.apache.org/bugzilla/show_bug.cgi?id=54826)Don't fail on long strings in JSON responses when displaying them as JSON in View Results Tree. - [Bug 57734](https://bz.apache.org/bugzilla/show_bug.cgi?id=57734)Maven transient dependencies are incorrect for 2.13 (Fixed group ids for Commons Pool and Math) - [Bug 57731](https://bz.apache.org/bugzilla/show_bug.cgi?id=57731)`TESTSTART.MS` has always the value of the first Test started in Server mode in NON GUI Distributed testing - [Bug 58016](https://bz.apache.org/bugzilla/show_bug.cgi?id=58016) Error type casting using external SSL Provider. Contributed by Kirill Yankov (myworkpostbox at gmail.com) - [Bug 58293](https://bz.apache.org/bugzilla/show_bug.cgi?id=58293)SOAP/XML-RPC Sampler file browser generates NullPointerException - [Bug 58685](https://bz.apache.org/bugzilla/show_bug.cgi?id=58685)JDatefield : Make the modification of the date with up/down arrow work. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58693](https://bz.apache.org/bugzilla/show_bug.cgi?id=58693)Fix "Cannot nest output folder 'jmeter/build/components' inside output folder 'jmeter/build'" when setting up eclipse - [Bug 58781](https://bz.apache.org/bugzilla/show_bug.cgi?id=58781)Command line option "`-?`" shows Unknown option - [Bug 57821](https://bz.apache.org/bugzilla/show_bug.cgi?id=57821)Command-line option "`-X --remoteexit`" doesn't work since 2.13 (regression related to [Bug 57500](https://bz.apache.org/bugzilla/show_bug.cgi?id=57500)) - [Bug 58795](https://bz.apache.org/bugzilla/show_bug.cgi?id=58795)NPE may occur in `GuiPackage#getTestElementCheckSum` with some 3rd party plugins - [Bug 58913](https://bz.apache.org/bugzilla/show_bug.cgi?id=58913)When closing JMeter should not interpret cancel as "_destroy my test plan_". Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59096](https://bz.apache.org/bugzilla/show_bug.cgi?id=59096)Search Feature : Case insensitive search is not really case insensitive - [Bug 59193](https://bz.apache.org/bugzilla/show_bug.cgi?id=59193)`ant run_gui` fails with `ClassNotFoundException` or `IllegalAccessError` when accessing classes from dependencies not loaded through `Thread.currentThread().getContextClassLoader()` - [Bug 59225](https://bz.apache.org/bugzilla/show_bug.cgi?id=59225)Bad display of running indicator icon. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 56927](https://bz.apache.org/bugzilla/show_bug.cgi?id=56927)Disable language change during a test - [Bug 59391](https://bz.apache.org/bugzilla/show_bug.cgi?id=59391)In Distributed mode, the client exits abnormally at the end of test - [Bug 59397](https://bz.apache.org/bugzilla/show_bug.cgi?id=59397)`build.xml` does not make dist.executables executable on Unix systems ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](http://ubikloadpack.com) - Benoit Vatan (benoit.vatan at gmail.com) - Jérémie Lesage (jeremie.lesage at jeci.fr) - Kirill Yankov (myworkpostbox at gmail.com) - Amol Moye (amol.moye at thomsonreuters.com) - Samoht-fr (https://github.com/Samoht-fr) - Graham Russell (jmeter at ham1.co.uk) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - Benoit Wiart (benoit.wiart at gmail.com) - [Decathlon S.A.](http://www.decathlon.com) - [Ubik-Ingenierie S.A.S.](http://www.ubik-ingenierie.com) - Oleg Kalnichevski (olegk at apache.org) - Pascal Schumacher (pascalschumacher at gmx.net) - Vincent Herilier (vherilier at gmail.com) - Florent Sabbe (f dot sabbe at ubik-ingenierie.com) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - Harrison Termotto (harrison dot termotto at stonybrook.edu - Denis Kirpichenkov (denis.kirpichenkov at gmail.com) - Gary Gregory (ggregory at apache.org) - David Coppens (d.l.coppens at gmail.com) - Luca Maragnani (luca dot maragnani at gmail dot com) - Philip Helger (http://www.helger.com) for his [CSS Parser](https://github.com/phax) and for taking into account our bug reports very rapidly - Irek Pastusiak (the.automatic.tester at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - purnasatyap at gmail dot com for the tests and reports on nightly build - Sergey Batalin (sergey_batalin at mail dot ru) for the tests and reports on nightly build - Vincent Daburon (vdaburon at gmail dot com) for the tests and reports on nightly build Apologies if we have omitted anyone else. ## Known problems and workarounds - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show `0` (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ```json [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: ``` java.security.cert.CertificateException: Certificates does not conform to algorithm constraints ``` if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java `jdk.certpath.disabledAlgorithms` property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. - Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers. This is due to a known Java bug, see Bug [JDK-8065373](https://bugs.openjdk.java.net/browse/JDK-8065373) The fix is to use JDK7_u79, JDK8_u45 or later. - View Results Tree may fail to display some HTML code under HTML renderer, see [Bug 54586](https://bz.apache.org/bugzilla/show_bug.cgi?id=54586). This is due to a known Java bug which fails to parse "`px`" units in row/col attributes. See Bug [JDK-8031109](https://bugs.openjdk.java.net/browse/JDK-8031109) The fix is to use JDK9 b65 or later. - JTable selection with keyboard (`SHIFT + up/down`) is totally unusable with JAVA 7 on Mac OSX. This is due to a known Java bug [JDK-8025126](https://bugs.openjdk.java.net/browse/JDK-8025126) The fix is to use JDK 8 b132 or later. ## Version 2.13 Summary - [New and Noteworthy](#New and Noteworthy) - [Known bugs](#Known bugs) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Thanks](#Thanks) ## New and Noteworthy ## New Elements ### New Async BackendListener with Graphite implementation A new Async BackendListener has been added to allow sending result data to a backend listener. JMeter ships with a GraphiteBackendListenerClient that allows sending results to a [Graphite](http://graphite.wikidot.com/) server using Pickle or Plaintext protocols. You can implement your own backend by extending [AbstractBackendListenerClient](/./api/org/apache/jmeter/visualizers/backend/AbstractBackendListenerClient/). This backend could be a database (JDBC), a Message Oriented Middleware (JMS), a Webservice or anything you want. ![changes/2.13/backend_listener_graphite.png](/images/screenshots/changes/2.13/backend_listener_graphite.png) This is the kind of Live Dashboard you can obtain using [Grafana](http://grafana.org/) and [InfluxDB](http://influxdb.com/) Read [this](/./usermanual/realtime-results/) for more details. ![Grafana dashboard](/images/screenshots/grafana_dashboard.png) _Grafana dashboard_ ## Core Improvements ### New connect time metric Starting with this version a new metric called connectTime has been added. It represents the time to establish connection. By default it is not saved to CSV or XML, to have it saved add to user.properties: ` jmeter.save.saveservice.connect_time=true ` ![changes/2.13/connect_time_table.png](/images/screenshots/changes/2.13/connect_time_table.png) ![changes/2.13/connect_time_tree.png](/images/screenshots/changes/2.13/connect_time_tree.png) ### Aggregate Graph and Report The listeners Aggregate Graph and Aggregate Report previously showed only the 90 percentile (historical behavior), the 95 percentile and the 99 percentile have been added and are customizable. To setup the percentiles value you want, add to user.properties: ` aggregate_rpt_pct1=90 aggregate_rpt_pct2=95 aggregate_rpt_pct3=99 ` ![changes/2.13/aggregate_graph_new_percentile.png](/images/screenshots/changes/2.13/aggregate_graph_new_percentile.png) ### HTTP(S) Test Script Recorder Now component is able to detect authentication schemes and automatically adds a pre-configured HTTP Authorization Manager with the correct Mechanism. ### HTTP Request The CalDAV verbs (Calendar extensions to WebDAV) REPORT and MKCALENDAR have been added in the HTTP Request sampler. ![changes/2.13/new_methods_caldav.png](/images/screenshots/changes/2.13/new_methods_caldav.png) ### JDBC Request The ResultSet can be get as a object, this allows to handle more easily the results after in BeanShell, JSR223 scripts, … ![changes/2.13/jdbc_resultset_handler.png](/images/screenshots/changes/2.13/jdbc_resultset_handler.png) ### Distributed Testing To allow better usage of Distributed Testing in the cloud, retry behaviour has been added when starting test on servers. Read [this](/./usermanual/remote-test/#retries) for more details. ![changes/2.13/distributed_retry.png](/images/screenshots/changes/2.13/distributed_retry.png) ### Distributed Testing performance Since JMeter 2.13, Stripping modes (StrippingBatch being the default mode) now also strip responses from SubResults improving consumed network bandwidth. ### Documentation refresh A new style for website (responsive and more up to date) has been created by Felix Schumacher. Documentations have been refreshed particularly: - [Building a Webservice Test Plan](/./usermanual/build-ws-test-plan/) - [Best Practices](/./usermanual/best-practices/) - [Help! My boss wants me to load test our application!](/./usermanual/boss/) ## GUI Improvements ### Module Controller The Module Controller now shows the target controller in a tree view (instead of combo list). ![changes/2.13/module_controller_tree_view.png](/images/screenshots/changes/2.13/module_controller_tree_view.png) ### Toolbar JMeter's toolbar has been refreshed for some icons (start, toggle, etc.). Three sizes are now available for the icons: 22x22, 32x32 and 48x48. The toolbar with 22x22 pixels icons ![changes/2.13/toolbar_22x22.png](/images/screenshots/changes/2.13/toolbar_22x22.png) The toolbar with 32x32 pixels icons ![changes/2.13/toolbar_32x32.png](/images/screenshots/changes/2.13/toolbar_32x32.png) The toolbar with 48x48 pixels icons ![changes/2.13/toolbar_48x48.png](/images/screenshots/changes/2.13/toolbar_48x48.png) ### HTTP(S) Test Script Recorder If your Test Plan does not contains a Recording Controller, a new warning message will appear if the HTTP(S) Test Script Recorder is configured to send the samples into a Recording Controller. ![changes/2.13/warning_message_proxy.png](/images/screenshots/changes/2.13/warning_message_proxy.png) ## Incompatible changes - Since 2.13, Aggregate Graph, Summary Report and Aggregate Report now export percentages to %, before they exported the decimal value which differed from what was shown in GUI - Third party plugins may be impacted by fix of [Bug 57586](https://bz.apache.org/bugzilla/show_bug.cgi?id=57586), ensure that your subclass of HttpTestSampleGui implements ItemListener if you relied on parent class doing so. - Report package has been removed, `ApacheJMeter_report.jar` is not generated anymore as a consequence, see [Bug 57269](https://bz.apache.org/bugzilla/show_bug.cgi?id=57269) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 25430](https://bz.apache.org/bugzilla/show_bug.cgi?id=25430)HTTP(S) Test Script Recorder : Make it populate HTTP Authorization Manager. Partly based on a patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [Bug 57381](https://bz.apache.org/bugzilla/show_bug.cgi?id=57381)HTTP(S) Test Script Recorder should display an error if Target Controller references a Recording Controller and no Recording Controller exists. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57488](https://bz.apache.org/bugzilla/show_bug.cgi?id=57488)Performance : Improve SSLContext reset for Two-way SSL Authentication - [Bug 57565](https://bz.apache.org/bugzilla/show_bug.cgi?id=57565)SamplerCreator : Add method to allow implementations to add children to created sampler - [Bug 57606](https://bz.apache.org/bugzilla/show_bug.cgi?id=57606)HTTPSamplerBase#errorResult changes the sample label on exception - [Bug 57613](https://bz.apache.org/bugzilla/show_bug.cgi?id=57613)HTTP Sampler : Added CalDAV verbs (REPORT, MKCALENDAR). Contributed by Richard Brigham (richard.brigham at teamaol.com) - [Bug 48799](https://bz.apache.org/bugzilla/show_bug.cgi?id=48799)Add time to establish connection to available sample metrics. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. and Pieter Ennes (apache.org at spam.ennes.nl) - [Bug 57500](https://bz.apache.org/bugzilla/show_bug.cgi?id=57500)Introduce retry behavior for distributed testing. Implemented by Andrey Pokhilko and Dzimitry Kashlach and contributed by BlazeMeter Ltd. #### Other samplers - [Bug 57322](https://bz.apache.org/bugzilla/show_bug.cgi?id=57322)JDBC Test elements: add ResultHandler to deal with ResultSets(cursors) returned by callable statements. Contributed by Yngvi Þór Sigurjónsson (blitzkopf at gmail.com) #### Controllers - [Bug 57561](https://bz.apache.org/bugzilla/show_bug.cgi?id=57561)Module controller UI : Replace combobox by tree. Contributed by Maciej Franek (maciej.franek at gmail.com) - [Bug 57648](https://bz.apache.org/bugzilla/show_bug.cgi?id=57648)TestFragment should be disabled when created. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Listeners - [Bug 55932](https://bz.apache.org/bugzilla/show_bug.cgi?id=55932)Create a Async BackendListener to allow easy plug of new listener (Graphite, JDBC, Console, …) - [Bug 57246](https://bz.apache.org/bugzilla/show_bug.cgi?id=57246)BackendListener : Create a Graphite implementation - [Bug 57217](https://bz.apache.org/bugzilla/show_bug.cgi?id=57217)Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57537](https://bz.apache.org/bugzilla/show_bug.cgi?id=57537)BackendListener : Allow implementations to drop samples #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions - [Bug 54453](https://bz.apache.org/bugzilla/show_bug.cgi?id=54453)Performance enhancements : Replace Random by ThreadLocalRandom in __Random function #### I18N #### General - [Bug 57518](https://bz.apache.org/bugzilla/show_bug.cgi?id=57518)Icons for toolbar with several sizes - [Bug 57605](https://bz.apache.org/bugzilla/show_bug.cgi?id=57605)When there is an error loading Test Plan, `SaveService.loadTree` returns `null` leading to NPE in callers - [Bug 57269](https://bz.apache.org/bugzilla/show_bug.cgi?id=57269)Drop `org.apache.jmeter.reports` package - [Bug 53764](https://bz.apache.org/bugzilla/show_bug.cgi?id=53764)Website : Create a new style for website ## Non-functional changes - Updated to jsoup-1.8.1.jar (from 1.7.3) - Updated to tika-core and tika-parsers 1.7 (from 1.6) - Updated to commons-codec-1.10.jar (from 1.9) - Updated to dnsjava-2.1.7.jar (from 2.1.6) - Updated to jodd-3.6.4.jar (from 3.6.1) - Updated to junit-4.12.jar (from 4.11) - Updated to rhino-1.7R5 (from 1.7R4) - Updated to rsyntaxtextarea-2.5.6 (from 2.5.3) - Updated to slf4j-1.7.10 (from 1.7.5) - [Bug 57276](https://bz.apache.org/bugzilla/show_bug.cgi?id=57276)RMIC no longer needed since Java 5 - [Bug 57310](https://bz.apache.org/bugzilla/show_bug.cgi?id=57310)Replace `System.getProperty("file.separator")` with `File.separator` throughout (Also "`path.separator"` with `File.pathSeparator`) - [Bug 57389](https://bz.apache.org/bugzilla/show_bug.cgi?id=57389)Fix potential NPE in converters - [Bug 57417](https://bz.apache.org/bugzilla/show_bug.cgi?id=57417)Remove unused method `isTemporary` from `NullProperty`. This was a leftover from a refactoring done in 2003. - [Bug 57418](https://bz.apache.org/bugzilla/show_bug.cgi?id=57418)Remove unused constructor from Workbench - [Bug 57419](https://bz.apache.org/bugzilla/show_bug.cgi?id=57419)Remove unused interface ModelListener. - [Bug 57466](https://bz.apache.org/bugzilla/show_bug.cgi?id=57466)IncludeController : Remove an unneeded set creation. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - Added property `loggerpanel.usejsyntaxtext` to disable the use of JSyntaxTextArea for the Console Logger (in case of memory or other issues) - [Bug 57586](https://bz.apache.org/bugzilla/show_bug.cgi?id=57586)HttpTestSampleGui: Remove interface ItemListener implementation ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 57385](https://bz.apache.org/bugzilla/show_bug.cgi?id=57385)Getting empty thread name in xml result for HTTP requests with "Follow Redirects" set. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57579](https://bz.apache.org/bugzilla/show_bug.cgi?id=57579)NullPointerException error is raised on main sample if "RETURN_NO_SAMPLE" is used (default) and "Use Cache-Control / Expires header…" is checked in HTTP Cache Manager #### Other Samplers #### Controllers - [Bug 57447](https://bz.apache.org/bugzilla/show_bug.cgi?id=57447)Use only the user listed DNS Servers, when "use custom DNS resolver" option is enabled. #### Listeners - [Bug 57262](https://bz.apache.org/bugzilla/show_bug.cgi?id=57262)Aggregate Report, Aggregate Graph and Summary Report export : headers use keys instead of labels - [Bug 57346](https://bz.apache.org/bugzilla/show_bug.cgi?id=57346)Summariser : The + (difference) reports show wrong elapsed time and throughput - [Bug 57449](https://bz.apache.org/bugzilla/show_bug.cgi?id=57449)Distributed Testing: Stripped modes do not strip responses from SubResults (affects load tests that use Download of embedded resources). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57562](https://bz.apache.org/bugzilla/show_bug.cgi?id=57562)View Results Tree CSS/JQuery Tester : Nothing happens when there is an error in syntax and an exception occurs in jmeter.log - [Bug 57514](https://bz.apache.org/bugzilla/show_bug.cgi?id=57514)Aggregate Graph, Summary Report and Aggregate Report show wrong percentage reporting in saved file #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 57607](https://bz.apache.org/bugzilla/show_bug.cgi?id=57607)Constant Throughput Timer : Wrong throughput computed in shared modes due to rounding error #### General - [Bug 57365](https://bz.apache.org/bugzilla/show_bug.cgi?id=57365)Selected LAF is not correctly setup due to call of `UIManager.setLookAndFeel` too late. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57364](https://bz.apache.org/bugzilla/show_bug.cgi?id=57364)Options < Look And Feel does not update all windows LAF. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57394](https://bz.apache.org/bugzilla/show_bug.cgi?id=57394)When constructing an instance with ClassTools#construct(String, int) the integer was ignored and the default constructor was used instead. - [Bug 57440](https://bz.apache.org/bugzilla/show_bug.cgi?id=57440)OutOfMemoryError after introduction of JSyntaxTextArea in LoggerPanel due to disableUndo not being taken into account. - [Bug 57569](https://bz.apache.org/bugzilla/show_bug.cgi?id=57569)FileServer.reserveFile - inconsistent behaviour when hasHeader is true - [Bug 57555](https://bz.apache.org/bugzilla/show_bug.cgi?id=57555)Cannot use JMeter 2.12 as a maven dependency. Contributed by Pascal Schumacher (pascal.schumacher at t-systems.com) - [Bug 57608](https://bz.apache.org/bugzilla/show_bug.cgi?id=57608)Fix start script compatibility with old Unix shells, e.g. on Solaris ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](http://ubikloadpack.com) - Yngvi Þór Sigurjónsson (blitzkopf at gmail.com) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [BlazeMeter Ltd.](http://blazemeter.com) - Benoit Wiart (benoit.wiart at gmail.com) - Pascal Schumacher (pascal.schumacher at t-systems.com) - Maciej Franek (maciej.franek at gmail.com) - Richard Brigham (richard.brigham at teamaol.com) - Pieter Ennes (apache.org at spam.ennes.nl) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Chaitanya Bhatt (bhatt.chaitanya at gmail.com) for his thorough testing of new BackendListener and Graphite Client implementation. - Marcelo Jara (marcelojara at hotmail.com) for his clear report on [Bug 57607](https://bz.apache.org/bugzilla/show_bug.cgi?id=57607). Apologies if we have omitted anyone else. ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: _java.security.cert.CertificateException: Certificates does not conform to algorithm constraints_ if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java **jdk.certpath.disabledAlgorithms** property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. ## Version 2.12 Summary - [New and Noteworthy](#New and Noteworthy) - [Known bugs](#Known bugs) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Thanks](#Thanks) ## New and Noteworthy ### Java 8 support Now, JMeter 2.12 is compliant with Java 8. ## New Elements ### Critical Section Controller The Critical Section Controller allow to serialize the execution of a section in your tree. Only one instance of the section will be executed at the same time during the test. ![changes/2.12/01_critical_section_controller.png](/images/screenshots/changes/2.12/01_critical_section_controller.png) ### DNS Cache Manager The new configuration element **DNS Cache Manager**(see [Bug 56841](https://bz.apache.org/bugzilla/show_bug.cgi?id=56841)) improves the testing of: - CDN (Content Delivery Network) - DNS load balancing. - Load Balancers like Amazon Elastic Load Balancer ![changes/2.12/02_dns_cache_manager.png](/images/screenshots/changes/2.12/02_dns_cache_manager.png) ## Core Improvements ### Smarter Recording of Http Test Plans Test Script Recorder has been improved in many ways - Better matching of Variables in Requests, making Test Script Recorder variabilize your sampler during recording more versatile - Ability to filter from View Results Tree the Samples that are excluded from recording, this lets you concentrate on recorded Samplers analysis and not bother with useless Sample Results ![changes/2.12/14_recorder_filter.png](/images/screenshots/changes/2.12/14_recorder_filter.png) - Better defaults for recording, since this version Recorder will number created Samplers letting you find them much easily in View Results Tree. Grouping of Samplers under Transaction Controller will be smarter making all requests emitted by a web page be children as new Transaction Controller ### Support of Webdav requests You can now test against WebDav server using HttpClient4 Implementation of Http Request ![changes/2.12/13_webdav.png](/images/screenshots/changes/2.12/13_webdav.png) ### Better handling of embedded resources When download embedded resources is checked, JMeter now uses User Agent header to download or not resources embedded within conditional comments as per [About conditional comments](http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx). ### Ability to customize Cache Manager (Browser cache simulation) handling of cached resources You can now configure the behaviour of JMeter when a resource is found in Cache, this can be controlled with _cache_manager.cached_resource_mode_ property ![changes/2.12/12_cache_resource_mode.png](/images/screenshots/changes/2.12/12_cache_resource_mode.png) ### JMS Publisher / JMS Point-to-Point Add JMSPriority and JMSExpiration fields for these samplers. ![changes/2.12/04_jms_publisher.png](/images/screenshots/changes/2.12/04_jms_publisher.png) ![changes/2.12/05_jms_point_to_point.png](/images/screenshots/changes/2.12/05_jms_point_to_point.png) ### Mail Reader Sampler You can now specify the number of messages that want you retrieve (before all messages were retrieved). In addition, you can fetch only the message header now. ![changes/2.12/03_mail_reader_sampler.png](/images/screenshots/changes/2.12/03_mail_reader_sampler.png) ### SMTP Sampler Adding the Connection timeout and the Read timeout to the **SMTP Sampler.** ![changes/2.12/06_smtp_sampler.png](/images/screenshots/changes/2.12/06_smtp_sampler.png) ### Synchronizing Timer Adding a timeout to define the maximum time to waiting of the group of virtual users. ![changes/2.12/09_synchronizing_timer.png](/images/screenshots/changes/2.12/09_synchronizing_timer.png) ### Performance improvements A big improvement in performances of Functions has been made by lifting useless synchronization. It concerns all functions except __StringFromFile, __XPath and __BeanShell, see [Bug 57114](https://bz.apache.org/bugzilla/show_bug.cgi?id=57114) __jexl2 performances have been improved to avoid contention point, see [Bug 56708](https://bz.apache.org/bugzilla/show_bug.cgi?id=56708) ## GUI Improvements ### Undo/Redo support Undo / Redo has been introduced and allows user to undo/redo changes made on Test Plan Tree. This feature (ALPHA MODE) is disabled by default, to enable it set property **undo.history.size=25** ![changes/2.12/10_undo_redo.png](/images/screenshots/changes/2.12/10_undo_redo.png) ### View Results Tree Improve the ergonomics of View Results Tree by changing placement of Renderers and allowing custom ordering (with the property _view.results.tree.renderers_order_). ![changes/2.12/07_view_results_tree.png](/images/screenshots/changes/2.12/07_view_results_tree.png) ### Response Time Graph Adding the ability for the **Response Time Graph** listener to save/restore format its settings in/from the jmx file. ![changes/2.12/08_response_time_graph.png](/images/screenshots/changes/2.12/08_response_time_graph.png) ### Log Viewer Starting with this version, the last lines of JMeter's log file (jmeter.log) can be viewed directly in GUI by clicking on Warning icon in the upper right corner. This will unfold the Log Viewer panel and show logs. ![changes/2.12/11_log_viewer.png](/images/screenshots/changes/2.12/11_log_viewer.png) ### File Opening Now, "Open File dialog" uses last opened file folder as start folder, see [Bug 52707](https://bz.apache.org/bugzilla/show_bug.cgi?id=52707) ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: _java.security.cert.CertificateException: Certificates does not conform to algorithm constraints_ if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java **jdk.certpath.disabledAlgorithms** property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. ## Incompatible changes - Since JMeter 2.12, active threads in all thread groups and active threads in current thread group are saved by default to CSV or XML results, see [Bug 57025](https://bz.apache.org/bugzilla/show_bug.cgi?id=57025). This is usually the expected behaviour as you want to have the number of running threads during the test. But if you want to revert to previous behaviour, set property **jmeter.save.saveservice.thread_counts=false** - Since JMeter 2.12, Mail Reader Sampler will show 1 for number of samples instead of number of messages retrieved, see [Bug 56539](https://bz.apache.org/bugzilla/show_bug.cgi?id=56539) - Since JMeter 2.12, when using Cache Manager, if resource is found in cache no SampleResult will be created, in previous version a SampleResult with empty content and 204 return code was returned, see [Bug 54778](https://bz.apache.org/bugzilla/show_bug.cgi?id=54778). You can choose between different ways to handle this case, see `cache_manager.cached_resource_mode` in `jmeter.properties`. - Since JMeter 2.12, Log Viewer will no more clear logs when closed and will have logs available even if closed. See [Bug 56920](https://bz.apache.org/bugzilla/show_bug.cgi?id=56920). Read [Hints and Tips > Enabling Debug logging](/./usermanual/hints-and-tips/#debug_logging) for details on configuring this component. ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 55998](https://bz.apache.org/bugzilla/show_bug.cgi?id=55998) - HTTP recording – Replacing port value by user defined variable does not work - [Bug 56178](https://bz.apache.org/bugzilla/show_bug.cgi?id=56178) - keytool error: Invalid escaped character in AVA: - some characters must be escaped - [Bug 56222](https://bz.apache.org/bugzilla/show_bug.cgi?id=56222) - NPE if jmeter.httpclient.strict_rfc2616=true and location is not absolute - [Bug 56263](https://bz.apache.org/bugzilla/show_bug.cgi?id=56263) - DefaultSamplerCreator should set BrowserCompatible Multipart true - [Bug 56231](https://bz.apache.org/bugzilla/show_bug.cgi?id=56231) - Move redirect location processing from HC3/HC4 samplers to HTTPSamplerBase#followRedirects() - [Bug 56207](https://bz.apache.org/bugzilla/show_bug.cgi?id=56207) - URLs get encoded on redirects in HC3.1 & HC4 samplers - [Bug 56303](https://bz.apache.org/bugzilla/show_bug.cgi?id=56303) - The width of target controller's combo list should be set to the current panel size, not on label size of the controllers - [Bug 54778](https://bz.apache.org/bugzilla/show_bug.cgi?id=54778) - HTTP Sampler should not return 204 when resource is found in Cache, make it configurable with new property cache_manager.cached_resource_mode #### Other Samplers - [Bug 55977](https://bz.apache.org/bugzilla/show_bug.cgi?id=55977) - JDBC pool keepalive flooding - [Bug 55999](https://bz.apache.org/bugzilla/show_bug.cgi?id=55999) - Scroll bar on jms point-to-point sampler does not work when content exceeds display - [Bug 56198](https://bz.apache.org/bugzilla/show_bug.cgi?id=56198) - JMSSampler : NullPointerException is thrown when JNDI underlying implementation of JMS provider does not comply with `Context.getEnvironment` contract - [Bug 56428](https://bz.apache.org/bugzilla/show_bug.cgi?id=56428) - MailReaderSampler - should it use mail.pop3s.* properties? - [Bug 46932](https://bz.apache.org/bugzilla/show_bug.cgi?id=46932) - Alias given in select statement is not used as column header in response data for a JDBC request. Based on report and analysis of Nicola Ambrosetti - [Bug 56539](https://bz.apache.org/bugzilla/show_bug.cgi?id=56539) - Mail reader sampler: When Number of messages to retrieve is superior to 1, Number of samples should only show 1 not the number of messages retrieved - [Bug 56809](https://bz.apache.org/bugzilla/show_bug.cgi?id=56809) - JMSSampler closes InitialContext too early. Contributed by Bradford Hovinen (hovinen at gmail.com) - [Bug 56761](https://bz.apache.org/bugzilla/show_bug.cgi?id=56761) - JMeter tries to stop already stopped JMS connection and displays "The connection is closed" - [Bug 57068](https://bz.apache.org/bugzilla/show_bug.cgi?id=57068) - No error thrown when negative duration is entered in Test Action - [Bug 57078](https://bz.apache.org/bugzilla/show_bug.cgi?id=57078) - LagartoBasedHTMLParser fails to parse page that contains input with no type - [Bug 57183](https://bz.apache.org/bugzilla/show_bug.cgi?id=57183) - JMSSampler: For input string: "" java.lang.NumberFormatException (for Expiration or Priority fields) #### Controllers - [Bug 56243](https://bz.apache.org/bugzilla/show_bug.cgi?id=56243) - Foreach works incorrectly with indexes on subsequent iterations - [Bug 56276](https://bz.apache.org/bugzilla/show_bug.cgi?id=56276) - Loop controller becomes broken once loop count evaluates to zero - [Bug 56160](https://bz.apache.org/bugzilla/show_bug.cgi?id=56160) - StackOverflowError when using WhileController within IfController - [Bug 56811](https://bz.apache.org/bugzilla/show_bug.cgi?id=56811) - "Start Next Thread Loop" in Result Status Action Handler or on Thread Group and "Go to next Loop iteration" in Test Action behave incorrectly with TransactionController that has "Generate Parent Sampler" checked #### Listeners - [Bug 56706](https://bz.apache.org/bugzilla/show_bug.cgi?id=56706) - SampleResult#getResponseDataAsString() does not use encoding in response body impacting PostProcessors and ViewResultsTree. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57052](https://bz.apache.org/bugzilla/show_bug.cgi?id=57052) - ArithmeticException: / by zero when sampleCount is equal to 0 #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 56162](https://bz.apache.org/bugzilla/show_bug.cgi?id=56162) - HTTP Cache Manager should not cache PUT/POST etc. - [Bug 56227](https://bz.apache.org/bugzilla/show_bug.cgi?id=56227) - AssertionGUI : NPE in assertion on mouse selection - [Bug 41319](https://bz.apache.org/bugzilla/show_bug.cgi?id=41319) - URLRewritingModifier : Allow Parameter value to be url encoded #### Functions #### I18N - [Bug 56111](https://bz.apache.org/bugzilla/show_bug.cgi?id=56111) - "comments" in german translation is not correct #### General - [Bug 56059](https://bz.apache.org/bugzilla/show_bug.cgi?id=56059) - Older TestBeans incompatible with 2.11 when using TextAreaEditor - [Bug 56080](https://bz.apache.org/bugzilla/show_bug.cgi?id=56080) - Conversion error com.thoughtworks.xstream.converters.ConversionException with Java 8 Early Access Build - [Bug 56182](https://bz.apache.org/bugzilla/show_bug.cgi?id=56182) - Can't trigger bsh script using bshclient.jar; socket is closed unexpectedly - [Bug 56360](https://bz.apache.org/bugzilla/show_bug.cgi?id=56360) - HashTree and ListedHashTree fail to compile with Java 8 - [Bug 56419](https://bz.apache.org/bugzilla/show_bug.cgi?id=56419) - JMeter silently fails to save results - [Bug 56662](https://bz.apache.org/bugzilla/show_bug.cgi?id=56662) - Save as xml in a listener is not remembered - [Bug 56367](https://bz.apache.org/bugzilla/show_bug.cgi?id=56367) - JMeter 2.11 on maven central triggers a not existing dependency rsyntaxtextarea 2.5.1, upgrade to 2.5.3 - [Bug 56743](https://bz.apache.org/bugzilla/show_bug.cgi?id=56743) - Wrong mailing list archives on mail2.xml. Contributed by Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 56763](https://bz.apache.org/bugzilla/show_bug.cgi?id=56763) - Removing the Oracle icons, not used by JMeter (and missing license) - [Bug 54100](https://bz.apache.org/bugzilla/show_bug.cgi?id=54100) - Switching languages fails to preserve toolbar button states (enabled/disabled) - [Bug 54648](https://bz.apache.org/bugzilla/show_bug.cgi?id=54648) - JMeter GUI on OS X crashes when using CMD+C (keyboard shortcut or UI menu entry) on an element from the tree - [Bug 56962](https://bz.apache.org/bugzilla/show_bug.cgi?id=56962) - JMS GUIs should disable all fields affected by jndi.properties checkbox - [Bug 57061](https://bz.apache.org/bugzilla/show_bug.cgi?id=57061) - Save as Test Fragment fails to clone deeply selected node. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57075](https://bz.apache.org/bugzilla/show_bug.cgi?id=57075) - BeanInfoSupport.MULTILINE attribute is not processed - [Bug 57076](https://bz.apache.org/bugzilla/show_bug.cgi?id=57076) - BooleanPropertyEditor#getAsText() must return a value that is in getTags() - [Bug 57088](https://bz.apache.org/bugzilla/show_bug.cgi?id=57088) - NPE in ResultCollector.testEnded ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 55959](https://bz.apache.org/bugzilla/show_bug.cgi?id=55959) - Improve error message when Test Script Recorder fails due to I/O problem - [Bug 52013](https://bz.apache.org/bugzilla/show_bug.cgi?id=52013) - Test Script Recorder's Child View Results Tree does not take into account Test Script Recorder excluded/included URLs. Based on report and analysis of James Liang - [Bug 56119](https://bz.apache.org/bugzilla/show_bug.cgi?id=56119) - File uploads fail every other attempt using timers. Enable idle timeouts for servers that don't send Keep-Alive headers. - [Bug 56272](https://bz.apache.org/bugzilla/show_bug.cgi?id=56272) - MirrorServer should support query parameters for status and redirects - [Bug 56772](https://bz.apache.org/bugzilla/show_bug.cgi?id=56772) - Handle IE Conditional comments when parsing embedded resources - [Bug 57026](https://bz.apache.org/bugzilla/show_bug.cgi?id=57026) - HTTP(S) Test Script Recorder : Better default settings. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57107](https://bz.apache.org/bugzilla/show_bug.cgi?id=57107) - Patch proposal: Add DAV verbs to HTTP Sampler. Contributed by Philippe Jung (apache at famille-jung.fr) - [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) - Certificates does not conform to algorithm constraints: Adding a note to indicate how to remove of the Java installation these new security constraints #### Other samplers - [Bug 56033](https://bz.apache.org/bugzilla/show_bug.cgi?id=56033) - Add Connection timeout and Read timeout to SMTP Sampler - [Bug 56429](https://bz.apache.org/bugzilla/show_bug.cgi?id=56429) - MailReaderSampler - no need to fetch all Messages if not all wanted - [Bug 56427](https://bz.apache.org/bugzilla/show_bug.cgi?id=56427) - MailReaderSampler enhancement: read message header only - [Bug 56510](https://bz.apache.org/bugzilla/show_bug.cgi?id=56510) - JMS Publisher/Point to Point: Add JMSPriority and JMSExpiration #### Controllers - [Bug 56728](https://bz.apache.org/bugzilla/show_bug.cgi?id=56728) - New Critical Section Controller to serialize blocks of a Test. Based partly on a patch contributed by Mikhail Epikhin(epihin-m at yandex.ru) - [Bug 57145](https://bz.apache.org/bugzilla/show_bug.cgi?id=57145) - RandomController : Use ThreadLocalRandom instead of Random for better performances #### Listeners - [Bug 56228](https://bz.apache.org/bugzilla/show_bug.cgi?id=56228) - View Results Tree : Improve ergonomy by changing placement of Renderers and allowing custom ordering - [Bug 56349](https://bz.apache.org/bugzilla/show_bug.cgi?id=56349) - "summary" is a bad name for a Generate Summary Results component, documentation clarified - [Bug 56769](https://bz.apache.org/bugzilla/show_bug.cgi?id=56769) - Adds the ability for the Response Time Graph listener to save/restore format settings in/from the jmx file - [Bug 57025](https://bz.apache.org/bugzilla/show_bug.cgi?id=57025) - SaveService : Better defaults, save thread counts by default #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 56691](https://bz.apache.org/bugzilla/show_bug.cgi?id=56691) - Synchronizing Timer : Add timeout on waiting - [Bug 56701](https://bz.apache.org/bugzilla/show_bug.cgi?id=56701) - HTTP Authorization Manager/ Kerberos Authentication: add port to SPN when server port is neither 80 nor 443. Based on patches from Dan Haughey (dan.haughey at swinton.co.uk) and Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 56841](https://bz.apache.org/bugzilla/show_bug.cgi?id=56841) - New configuration element: DNS Cache Manager to improve the testing of CDN. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. - [Bug 52061](https://bz.apache.org/bugzilla/show_bug.cgi?id=52061) - Allow access to Request Headers in Regex Extractor. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. #### Functions - [Bug 56708](https://bz.apache.org/bugzilla/show_bug.cgi?id=56708) - __jexl2 doesn't scale with multiple CPU cores. Based on analysis and patch contributed by Mikhail Epikhin(epihin-m at yandex.ru) - [Bug 57114](https://bz.apache.org/bugzilla/show_bug.cgi?id=57114) - Performance : Functions that only have values as instance variable should not synchronize execute. Based on analysis by Ubik Load Pack support and Vladimir Sitnikov, patch contributed by Vladimir Sitnikov (sitnikov.vladimir at gmail.com) #### I18N #### General - [Bug 21695](https://bz.apache.org/bugzilla/show_bug.cgi?id=21695) - Unix jmeter start script assumes it is on PATH, not a link - [Bug 56292](https://bz.apache.org/bugzilla/show_bug.cgi?id=56292) - Add the check of the Java's version in startup files and disable some options when is Java v8 engine - [Bug 56298](https://bz.apache.org/bugzilla/show_bug.cgi?id=56298) - JSR223 language display does not show which engine will be used - [Bug 56455](https://bz.apache.org/bugzilla/show_bug.cgi?id=56455) - Batch files: drop support for non-NT Windows shell scripts - [Bug 52707](https://bz.apache.org/bugzilla/show_bug.cgi?id=52707) - Make Open File dialog use last opened file folder as start folder. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. - [Bug 56807](https://bz.apache.org/bugzilla/show_bug.cgi?id=56807) - Ability to force flush of ResultCollector file. Contributed by Andrey Pohilko (apc4 at ya.ru) - [Bug 56921](https://bz.apache.org/bugzilla/show_bug.cgi?id=56921) - Templates : Improve Recording template to ignore embedded resources case and URL parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 42248](https://bz.apache.org/bugzilla/show_bug.cgi?id=42248) - Undo-redo support on Test Plan tree modification. Developed by Andrey Pohilko (apc4 at ya.ru) and contributed by BlazeMeter Ltd. Additional contribution by Ubik Load Pack (support at ubikloadpack.com) - [Bug 56920](https://bz.apache.org/bugzilla/show_bug.cgi?id=56920) - LogViewer : Make it receive all log events even when it is closed. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57083](https://bz.apache.org/bugzilla/show_bug.cgi?id=57083) - simplified the CachedResourceMode enum. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57082](https://bz.apache.org/bugzilla/show_bug.cgi?id=57082) - ComboStringEditor : Added hashCode to an inner class which overwrote equals. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57081](https://bz.apache.org/bugzilla/show_bug.cgi?id=57081) - Updating checkstyle to only check for tabs in java, xml, xsd, dtd, htm, html and txt files (not images!). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 56178](https://bz.apache.org/bugzilla/show_bug.cgi?id=56178) - Really replace backslashes in user name before generating proxy certificate. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57084](https://bz.apache.org/bugzilla/show_bug.cgi?id=57084) - Close socket after usage in BeanShellClient. Contributed by Graham Russel (graham at ham1.co.uk) ## Non-functional changes - [Bug 57117](https://bz.apache.org/bugzilla/show_bug.cgi?id=57117) - Increase the default cipher for HTTPS Test Script Recorder from SSLv3 to TLS - Updated to commons-lang3 3.3.2 (from 3.1) - Updated to commons-codec 1.9 (from 1.8) - Updated to commons-logging 1.2 (from 1.1.3) - Updated to tika 1.6 (from 1.4) - Updated to xercesImpl 2.11.0 (from 2.9.1) - Updated to xml-apis 1.4.01 (from 1.3.04) - Updated to xstream 1.4.8 (from 1.4.4) - Updated to jodd 3.6.1 (from 3.4.10) - Updated to rsyntaxtextarea 2.5.3 (from 2.5.1) - Updated xalan and serializer to 2.7.2 (from 2.7.1) - Updated to jsoup-1.8.1.jar (from 1.7.3) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - James Liang (jliang at andera.com) - Emmanuel Bourg (ebourg at apache.org) - Nicola Ambrosetti (ambrosetti.nicola at gmail.com) - [Ubik Load Pack](http://ubikloadpack.com) - Mikhail Epikhin (epihin-m at yandex.ru) - Dan Haughey (dan.haughey at swinton.co.uk) - Felix Schumacher (felix.schumacher at internetallee.de) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - Andrey Pohilko (apc4 at ya.ru) - Bradford Hovinen (hovinen at gmail.com) - [BlazeMeter Ltd.](http://blazemeter.com) - Graham Russell (graham at ham1.co.uk) - Philippe Jung (apache at famille-jung.fr) - Vladimir Sitnikov (sitnikov.vladimir at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Oliver LLoyd (email at oliverlloyd.com) for his help on [Bug 56119](https://bz.apache.org/bugzilla/show_bug.cgi?id=56119) - Vladimir Ryabtsev (greatvovan at gmail.com) for his help on [Bug 56243](https://bz.apache.org/bugzilla/show_bug.cgi?id=56243) and [Bug 56276](https://bz.apache.org/bugzilla/show_bug.cgi?id=56276) - Adrian Speteanu (asp.adieu at gmail.com) and Matt Kilbride (matt.kilbride at gmail.com) for their feedback and tests on [Bug 54648](https://bz.apache.org/bugzilla/show_bug.cgi?id=54648) - Shmuel Krakower (shmulikk at gmail.com) for his tests and reports on Undo/Redo feature Apologies if we have omitted anyone else. ## Version 2.11 Summary - [New and Noteworthy](#New and Noteworthy) - [Known bugs](#Known bugs) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Thanks](#Thanks) ## New and Noteworthy ### HTTP(S) Test Script Recorder improvements Following improvements have been made since major changes introduced in JMeter 2.10 on HTTP(S) Test Script Recorder: - Better detection of missing or invalid configuration of keytool utility - New system property `keytool.directory` (see `system.properties`) lets you configure directory containing keytool in case on non-standard installation ### JMS Publisher/Point to Point : Add ability to set typed values in JMS header properties In the samplers JMS Publisher and JMS Point-to-Point, you can now set up the class of values for the JMS header properties. Previously only String was possible. ![changes/2.11/01_jms_properties_typed_values.png](/images/screenshots/changes/2.11/01_jms_properties_typed_values.png) ### View Results Tree : Add an XPath Tester In View Results Tree listener, a new XPath tester can be used to test XPATH expressions. ![changes/2.11/03_xpath_tester.png](/images/screenshots/changes/2.11/03_xpath_tester.png) ### Ability to choose the client alias for the cert key in JsseSslManager such that Mutual SSL auth testing can be made more flexible When testing client based certificate authentications you have now better control on certificate you use through a new field "Variable name holding certificate alias", this field lets you select the certificate you want to send to server to authenticate. You can use a CSV Data Set as a holder for the variable value. ![changes/2.11/07_keystore_config.png](/images/screenshots/changes/2.11/07_keystore_config.png) ### Add a "Save as Test Fragment" option In the file menu, a new option allow to save a group of elements as a Test fragment. ![changes/2.11/05_save_as_fragement.png](/images/screenshots/changes/2.11/05_save_as_fragement.png) ### Summariser is be enabled by default in Non GUI mode When you run JMeter from command line, now JMeter displays some statistics from the Summariser mode. ![changes/2.11/06_summariser.png](/images/screenshots/changes/2.11/06_summariser.png) ### Transaction Controller:Change default property "Include duration of timer…" for newly created element Starting from 2.11, Transaction Controller is configured by default to exclude processing time of pre/post processors as long as timers pause. ![changes/2.11/02_transaction_controller.png](/images/screenshots/changes/2.11/02_transaction_controller.png) ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. ## Incompatible changes - When creating a new Transaction Controller, property "Include duration of timer and pre-post processors in generated sample" will be unchecked starting from version 2.11 - In Non GUI mode, since 2.11 summariser is enabled with a 30 seconds frequency - JMeter is more lenient with redirect handling and relaxes on RFC2616 by allowing relative locations. See property "`jmeter.httpclient.strict_rfc2616`" in `jmeter.properties` to change this behaviour, see [Bug 55717](https://bz.apache.org/bugzilla/show_bug.cgi?id=55717) - When creating a new Response Assertion, property "Pattern Matching Rules" now defaults to Substring starting from version 2.11 ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 55815](https://bz.apache.org/bugzilla/show_bug.cgi?id=55815) - Proxy#getDomainMatch does not handle wildcards correctly - [Bug 55717](https://bz.apache.org/bugzilla/show_bug.cgi?id=55717) - Bad handling of Redirect when URLs are in relative format by HttpClient4 and HttpClient3.1 #### Other Samplers - [Bug 55685](https://bz.apache.org/bugzilla/show_bug.cgi?id=55685) - OS Sampler: timeout option don't save and restore correctly value and don't init correctly timeout #### Controllers - [Bug 55816](https://bz.apache.org/bugzilla/show_bug.cgi?id=55816) - Transaction Controller with "Include duration of timer…" unchecked does not ignore processing time of last child sampler #### Listeners - [Bug 55826](https://bz.apache.org/bugzilla/show_bug.cgi?id=55826) - Unsynchronised concurrent accesses to list in field RespTimeGraphVisualizer.internalList #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 55694](https://bz.apache.org/bugzilla/show_bug.cgi?id=55694) - Assertions and Extractors : Avoid NullPointerException when scope is variable and variable is missing - [Bug 55721](https://bz.apache.org/bugzilla/show_bug.cgi?id=55721) - HTTP Cache Manager - no-store directive is wrongly interpreted #### Functions - [Bug 55871](https://bz.apache.org/bugzilla/show_bug.cgi?id=55871) - Wrong result with intSum() function when a space character is present before/after the number. Contributed by Milamber based on a proposal by James Liang. #### I18N #### General - [Bug 55739](https://bz.apache.org/bugzilla/show_bug.cgi?id=55739) - Remote Test : Total threads in GUI mode shows invalid total number of threads ## Improvements #### HTTP Samplers and Proxy #### Other samplers - [Bug 55589](https://bz.apache.org/bugzilla/show_bug.cgi?id=55589) - JMS Publisher/Point to Point : Add ability to set typed values in JMS header properties. #### Controllers - [Bug 55854](https://bz.apache.org/bugzilla/show_bug.cgi?id=55854) - Transaction Controller:Change default property "Include duration of timer…" for newly created element #### Listeners - [Bug 55610](https://bz.apache.org/bugzilla/show_bug.cgi?id=55610) - View Results Tree : Add an XPath Tester #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 55908](https://bz.apache.org/bugzilla/show_bug.cgi?id=55908) - Response assertion : Change Pattern Matching Rules default to Substring on creation for better performances - [Bug 54977](https://bz.apache.org/bugzilla/show_bug.cgi?id=54977) - Ability to choose the client alias for the cert key in JsseSslManager such that Mutual SSL auth testing can be made more flexible. Contributed by UBIK Load Pack (support at ubikloadpack.com) #### Functions #### I18N #### General - [Bug 55693](https://bz.apache.org/bugzilla/show_bug.cgi?id=55693) - Add a "Save as Test Fragment" option - [Bug 55753](https://bz.apache.org/bugzilla/show_bug.cgi?id=55753) - Improve FilePanel behaviour to start from the value set in Filename field if any. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55756](https://bz.apache.org/bugzilla/show_bug.cgi?id=55756) - HTTP Mirror Server : Add ability to set Headers - [Bug 55852](https://bz.apache.org/bugzilla/show_bug.cgi?id=55852) - Be more lenient in parsing when charset value is surrounded with single quotes - [Bug 55857](https://bz.apache.org/bugzilla/show_bug.cgi?id=55857) - Performance : AbstractProperty should test for emptiness to avoid Exception throwing - [Bug 55858](https://bz.apache.org/bugzilla/show_bug.cgi?id=55858) - Startup Performance : On Startup, BeanInfoSupport should test for key availability instead of throwing - [Bug 55865](https://bz.apache.org/bugzilla/show_bug.cgi?id=55865) - Performance :Disable stale check by default in HttpClient 4 and 3.1 - [Bug 55512](https://bz.apache.org/bugzilla/show_bug.cgi?id=55512) - Summariser should be enabled by default in Non GUI mode ## Non-functional changes - Updated to rsyntaxtextarea-2.5.1.jar (from 2.5.0) - Updated to jodd-core-3.4.9.jar from (3.4.8) and jodd-lagarto-3.4.9.jar (from 3.4.9) - Updated to jsoup-1.7.3.jar (from 1.7.2) - Updated to mail-1.5.0-b01 (from 1.4.4) - Updated to mongo-java-driver-2.11.3 (from 2.11.2) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - James Liang (jliang at andera.com) - UBIK Load Pack (support at ubikloadpack.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - John Natsioulas (john_natsioulas at yahoo.com.au) - Antonio Gomes Rodrigues (ra0077 at gmail.com) Apologies if we have omitted anyone else. ## Version 2.10 Summary - [New and Noteworthy](#New and Noteworthy) - [Known bugs](#Known bugs) - [Incompatible changes](#Incompatible changes) - [Bug fixes](#Bug fixes) - [Improvements](#Improvements) - [Non-functional changes](#Non-functional changes) - [Thanks](#Thanks) ## New and Noteworthy ## Core Improvements ### New Performance improvements - A Huge performance improvement has been made on High Throughput Tests (no pause), see [Bug 54777](https://bz.apache.org/bugzilla/show_bug.cgi?id=54777) - An issue with unnecessary SSL Context reset has been fixed which improves performances of pure HTTP tests, see [Bug 55023](https://bz.apache.org/bugzilla/show_bug.cgi?id=55023) - Important performance improvement in parsing of Embedded resource in HTML pages thanks to a switch to JODD/Lagarto HTML Parser, see [Bug 55632](https://bz.apache.org/bugzilla/show_bug.cgi?id=55632) ### New CSS/JQuery Tester in View Tree Results A new CSS/JQuery Tester in View Tree Results that makes CSS/JQuery Extractor a first class citizen in JMeter, you can now test your expressions very easily ![changes/2.10/01_css_jquery_tester.png](/images/screenshots/changes/2.10/01_css_jquery_tester.png) ### Many improvements in HTTP(S) Recording have been made ![changes/2.10/18_https_test_script_recorder.png](/images/screenshots/changes/2.10/18_https_test_script_recorder.png) :::note The "HTTP Proxy Server" test element has been renamed as "HTTP(S) Test Script Recorder". ::: - Better recording of HTTPS sites, embedded resources using subdomains will more easily be recorded when using JDK 7. See [Bug 55507](https://bz.apache.org/bugzilla/show_bug.cgi?id=55507). See updated documentation: [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder) - Redirection are now more smartly detected by HTTP Proxy Server, see [Bug 55531](https://bz.apache.org/bugzilla/show_bug.cgi?id=55531) - Many fixes on edge cases with HTTPS have been made, see [Bug 55502](https://bz.apache.org/bugzilla/show_bug.cgi?id=55502), [Bug 55504](https://bz.apache.org/bugzilla/show_bug.cgi?id=55504), [Bug 55506](https://bz.apache.org/bugzilla/show_bug.cgi?id=55506) - Many encoding fixes have been made, see [Bug 54482](https://bz.apache.org/bugzilla/show_bug.cgi?id=54482), [Bug 54142](https://bz.apache.org/bugzilla/show_bug.cgi?id=54142), [Bug 54293](https://bz.apache.org/bugzilla/show_bug.cgi?id=54293) ### You can now load test MongoDB through new MongoDB Source Config ![changes/2.10/02_mongodb_source_config.png](/images/screenshots/changes/2.10/02_mongodb_source_config.png) ![changes/2.10/14_mongodb_jsr223.png](/images/screenshots/changes/2.10/14_mongodb_jsr223.png) ### Kerberos authentication has been added to Auth Manager ![changes/2.10/15_kerberos.png](/images/screenshots/changes/2.10/15_kerberos.png) ### Device can now be used in addition to source IP address ![changes/2.10/16_device.png](/images/screenshots/changes/2.10/16_device.png) ### You can now do functional testing of MongoDB scripts through new MongoDB Script ![changes/2.10/03_mongodb_script_alpha.png](/images/screenshots/changes/2.10/03_mongodb_script_alpha.png) ### Timeout has been added to OS Process Sampler ![changes/2.10/17_os_process_timeout.png](/images/screenshots/changes/2.10/17_os_process_timeout.png) ### Query timeout has been added to JDBC Request ![changes/2.10/04_jdbc_request_timeout.png](/images/screenshots/changes/2.10/04_jdbc_request_timeout.png) ### New functions (__urlencode and __urldecode) are now available to encode/decode URL encoded chars ![changes/2.10/05_urlencode_function.png](/images/screenshots/changes/2.10/05_urlencode_function.png) ### Continuous Integration is now eased by addition of a new flag that forces NON-GUI JVM to exit after test end See jmeter property: `jmeterengine.force.system.exit` ### HttpSampler now allows DELETE Http Method to have a body (works for HC4 and HC31 implementations). This allows for example to test Elastic Search APIs ![changes/2.10/06_http_request_delete_method.png](/images/screenshots/changes/2.10/06_http_request_delete_method.png) ### 2 implementations of HtmlParser have been added to improve Embedded resources parsing You can choose the implementation to use for parsing Embedded resources in HTML pages: See jmeter.properties and look at property "htmlParser.className". - org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser for optimal performances - org.apache.jmeter.protocol.http.parser.JSoupBasedHtmlParser for most accurate parsing and functional testing ### Distributed testing has been improved - Number of threads on each node are now reported to controller. ![changes/2.10/17_threads_summariser.png](/images/screenshots/changes/2.10/17_threads_summariser.png) ![changes/2.10/17_threads_gui.png](/images/screenshots/changes/2.10/17_threads_gui.png) - Performance improvement on BatchSampleSender([Bug 55423](https://bz.apache.org/bugzilla/show_bug.cgi?id=55423)) - Addition of 2 SampleSender modes (StrippedAsynch and StrippedDiskStore), see jmeter.properties ### ModuleController has been improved to better handle changes to referenced controllers ### Improved class loader configuration, see [Bug 55503](https://bz.apache.org/bugzilla/show_bug.cgi?id=55503) - New property "plugin_dependency_paths" for plugin dependencies - Properties "search_paths", "user.classpath" and "plugin_dependency_paths" now automatically add all jars from configured directories ### Best-practices section has been improved, ensure you read it to get the most out of JMeter See [Best Practices](/usermanual/best-practices/) ## GUI and ergonomy Improvements ### New Templates feature that allows you to create test plan from existing template or merge template into your Test Plan ![changes/2.10/07_jmeter_templates_icon.png](/images/screenshots/changes/2.10/07_jmeter_templates_icon.png) ![changes/2.10/08_jmeter_templates_box.png](/images/screenshots/changes/2.10/08_jmeter_templates_box.png) ### Workbench can now be saved ![changes/2.10/09_save_workbench.png](/images/screenshots/changes/2.10/09_save_workbench.png) ### Syntax color has been added to scripts elements (BeanShell, BSF, and JSR223), MongoDB and JDBC elements making code much more readable and allowing UNDO/REDO through CTRL+Z/CTRL+Y BSF Sampler with syntax color ![changes/2.10/10_color_syntax_bsf_sampler.png](/images/screenshots/changes/2.10/10_color_syntax_bsf_sampler.png) JSR223 Pre Processor with syntax color ![changes/2.10/11_color_syntax_jsr223_preprocessor.png](/images/screenshots/changes/2.10/11_color_syntax_jsr223_preprocessor.png) ### Better editors are now available for Test Elements with large text content, like HTTP Sampler, and JMS related Test Element providing line numbering and allowing UNDO/REDO through CTRL+Z/CTRL+Y ### JMeter GUI can now be fully Internationalized, all remaining issues have been fixed ###### Currently French has all its labels translated. Other languages are partly translated, feel free to contribute translations by reading [Localisation (Translator's Guide)](/localising/index/) ### Moving elements in Test plan has been improved in many ways ###### Drag and drop of elements in Test Plan tree is now much easier and possible on multiple nodes ![changes/2.10/12_drap_n-drop_multiple.png](/images/screenshots/changes/2.10/12_drap_n-drop_multiple.png) Note that due to this [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6560955), you cannot drop a node after last node. The workaround is to drop it before this last node and then Drag and Drop the last node before the one you just dropped. ###### New shortcuts have been added to move elements in the tree. (alt + Arrow Up) and (alt + Arrow Down) move the element within the parent node (alt + Arrow Left) and (alt + Arrow Right) move the element up and down in the tree depth ### Response Time Graph Y axis can now be scaled ![changes/2.10/13_response_time_graph_y_scale.png](/images/screenshots/changes/2.10/13_response_time_graph_y_scale.png) ### JUnit Sampler gives now more details on configuration errors ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). - Webservice sampler does not consider the HTTP response status to compute the status of a response, thus a response 500 containing a non empty body will be considered as successful, see [Bug 54006](https://bz.apache.org/bugzilla/show_bug.cgi?id=54006). To workaround this issue, ensure you always read the response and add a Response Assertion checking text inside the response. - The numbers that appear to the left of the green box are the number of active threads / total number of threads, these only apply to a locally run test; they do not include any threads started on remote systems when using client-server mode, (see [Bug 54152](https://bz.apache.org/bugzilla/show_bug.cgi?id=54152)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. ## Incompatible changes - **SMTP Sampler** now uses eml file subject if subject field is empty - With this version autoFlush has been turned off on PrintWriter in charge of writing test results. This results in improved throughput for intensive tests but can result in more test data loss in case of JMeter crash (extremely rare). To revert to previous behaviour set `jmeter.save.saveservice.autoflush` property to `true`. - Shortcut for **Function Helper Dialog** is now _CTRL+SHIFT+F1 (CMD + SHIFT + F1 for Mac OS)_. The original key sequence _(Ctrl+F1)_ did not work in some locations (it is consumed by the Java Swing ToolTipManager). It was therefore necessary to change the shortcut. - **Webservice (SOAP) Request** has been removed by default from GUI as Element is deprecated. (Use **HTTP Request** with _Body Data_, see also the Template _Building a SOAP Webservice Test Plan_), if you need to show it, see property `not_in_menu` in _jmeter.properties_ - **Transaction Controller** now sets _Response Code_ of _Generated Parent Sampler_ (if _Generated Parent Sampler_ is checked) to response code of first failing child in case of failure of one of the children, in previous versions _Response Code_ was empty. - In previous versions, **IncludeController** could run Test Elements located inside a **Thread Group**, this behaviour (_which was not documented_) could result in weird behaviour, it has been removed in this version (see [Bug 55464](https://bz.apache.org/bugzilla/show_bug.cgi?id=55464)). The correct way to include Test Elements is to use **Test Fragment** as stated in documentation of **Include Controller**. - The retry count for the HttpClient 3.1 and HttpClient 4.x samplers has been changed to **0**. Previously the default was 1, which could cause unexpected additional traffic. - Starting with this version, the **HTTP(S) Test Script Recorder** tries to detect when a sample is the result of a previous redirect. If the current response is a redirect, JMeter will save the redirect URL. When the next request is received, it is compared with the saved redirect URL and if there is a match, JMeter will disable the generated sample. To revert to previous behaviour, set the property `proxy.redirect.disabling=false` - Starting with this version, in **HTTP(S) Test Script Recorder** if Grouping is set to _Put each group in a new Transaction Controller_, the Recorder will create **Transaction Controller** instances with _Include duration of timer and pre-post processors in generated sample_ set to false. This default value reflect more accurately response time. - `__escapeOroRegexpChars` function (which escapes ORO reserved characters) no longer trims the value (see [Bug 55328](https://bz.apache.org/bugzilla/show_bug.cgi?id=55328)) - The _commons-lang-2.6.jar_ has been removed from embedded libraries in `jmeter/lib` folder as it is not needed by JMeter at run-time (it is only used by Apache Velocity for generating documentation). If you use any plugin or third-party code that depends on it, you need to add it in `jmeter/lib` folder ## Bug fixes #### HTTP Samplers and Proxy - [Bug 54627](https://bz.apache.org/bugzilla/show_bug.cgi?id=54627) - JMeter Proxy GUI: Type of sampler setting takes the whole screen when there are samplers with long names. - [Bug 54629](https://bz.apache.org/bugzilla/show_bug.cgi?id=54629) - HTMLParser does not extract <object> tag urls. - [Bug 55023](https://bz.apache.org/bugzilla/show_bug.cgi?id=55023) - SSL Context reuse feature (51380) adversely affects non-ssl request performance/throughput. based on analysis by Brent Cromarty (brent.cromarty at yahoo.ca) - [Bug 55092](https://bz.apache.org/bugzilla/show_bug.cgi?id=55092) - Log message "WARN - jmeter.protocol.http.sampler.HTTPSamplerBase: Null URL detected (should not happen)" displayed when embedded resource URL is malformed. - [Bug 55161](https://bz.apache.org/bugzilla/show_bug.cgi?id=55161) - Useless processing in SoapSampler.setPostHeaders. Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 54482](https://bz.apache.org/bugzilla/show_bug.cgi?id=54482) - HC fails to follow redirects with non-encoded chars. - [Bug 54142](https://bz.apache.org/bugzilla/show_bug.cgi?id=54142) - HTTP Proxy Server throws an exception when path contains "|" character. - [Bug 55388](https://bz.apache.org/bugzilla/show_bug.cgi?id=55388) - HC3 does not allow IP Source field to override httpclient.localaddress. - [Bug 55450](https://bz.apache.org/bugzilla/show_bug.cgi?id=55450) - HEAD redirects should remain as HEAD - [Bug 55455](https://bz.apache.org/bugzilla/show_bug.cgi?id=55455) - HTTPS with HTTPClient4 ignores cps setting - [Bug 55502](https://bz.apache.org/bugzilla/show_bug.cgi?id=55502) - Proxy generates empty http:/ entries when recording - [Bug 55504](https://bz.apache.org/bugzilla/show_bug.cgi?id=55504) - Proxy incorrectly issues CONNECT requests when browser prompts for certificate override - [Bug 55506](https://bz.apache.org/bugzilla/show_bug.cgi?id=55506) - Proxy should deliver failed requests to any configured Listeners - [Bug 55545](https://bz.apache.org/bugzilla/show_bug.cgi?id=55545) - HTTP Proxy Server GUI should not allow both Follow and Auto redirect to be selected #### Other Samplers - [Bug 54913](https://bz.apache.org/bugzilla/show_bug.cgi?id=54913) - JMSPublisherGui incorrectly restores its state. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55027](https://bz.apache.org/bugzilla/show_bug.cgi?id=55027) - Test Action regression, duration value is not recorded (nightly build). - [Bug 55163](https://bz.apache.org/bugzilla/show_bug.cgi?id=55163) - BeanShellTestElement fails to quote string when calling testStarted(String)/testEnded(String). - [Bug 55349](https://bz.apache.org/bugzilla/show_bug.cgi?id=55349) - NativeCommand hangs if no input file is specified and the application requests input. - [Bug 55462](https://bz.apache.org/bugzilla/show_bug.cgi?id=55462) - System Sampler should not change the sampler label if a sample fails #### Controllers - [Bug 54467](https://bz.apache.org/bugzilla/show_bug.cgi?id=54467) - Loop Controller: compute loop value only once per parent iteration. - [Bug 54985](https://bz.apache.org/bugzilla/show_bug.cgi?id=54985) - Make Transaction Controller set Response Code of Generated Parent Sampler to response code of first failing child in case of failure of one of its children. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 54950](https://bz.apache.org/bugzilla/show_bug.cgi?id=54950) - ModuleController : Changes to referenced Module are not taken into account if changes occur after first run and referenced node is disabled. - [Bug 55201](https://bz.apache.org/bugzilla/show_bug.cgi?id=55201) - ForEach controller excludes start index and includes end index (clarified documentation). - [Bug 55334](https://bz.apache.org/bugzilla/show_bug.cgi?id=55334) - Adding Include Controller to test plan (made of Include Controllers) without saving TestPlan leads to included code not being taken into account until save. - [Bug 55375](https://bz.apache.org/bugzilla/show_bug.cgi?id=55375) - StackOverflowError with ModuleController in Non-GUI mode if its name is the same as the target node. - [Bug 55464](https://bz.apache.org/bugzilla/show_bug.cgi?id=55464) - Include Controller running included thread group #### Listeners - [Bug 54589](https://bz.apache.org/bugzilla/show_bug.cgi?id=54589) - View Results Tree have a lot of Garbage characters if html page uses double-byte charset. - [Bug 54753](https://bz.apache.org/bugzilla/show_bug.cgi?id=54753) - StringIndexOutOfBoundsException at SampleResult.getSampleLabel() if key_on_threadname=false when using Statistical mode. - [Bug 54685](https://bz.apache.org/bugzilla/show_bug.cgi?id=54685) - ArrayIndexOutOfBoundsException if "sample_variable" is set in client but not server. - [Bug 55111](https://bz.apache.org/bugzilla/show_bug.cgi?id=55111) - ViewResultsTree: text not refitted if vertical scrollbar is required. Contributed by Milamber #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54540](https://bz.apache.org/bugzilla/show_bug.cgi?id=54540) - "HTML Parameter Mask" are not marked deprecated in the IHM. - [Bug 54575](https://bz.apache.org/bugzilla/show_bug.cgi?id=54575) - CSS/JQuery Extractor : Choosing JODD Implementation always uses JSOUP. - [Bug 54901](https://bz.apache.org/bugzilla/show_bug.cgi?id=54901) - Response Assertion GUI behaves weirdly. - [Bug 54924](https://bz.apache.org/bugzilla/show_bug.cgi?id=54924) - XMLAssertion uses JMeter JVM file.encoding instead of response encoding and does not clean threadlocal variable. - [Bug 53679](https://bz.apache.org/bugzilla/show_bug.cgi?id=53679) - Constant Throughput Timer bug with localization. Reported by Ludovic Garcia #### Functions - [Bug 55328](https://bz.apache.org/bugzilla/show_bug.cgi?id=55328) - __escapeOroRegexpChars trims spaces. #### I18N - [Bug 55437](https://bz.apache.org/bugzilla/show_bug.cgi?id=55437) - ComboStringEditor does not translate EDIT and UNDEFINED strings on language change - [Bug 55501](https://bz.apache.org/bugzilla/show_bug.cgi?id=55501) - Incorrect encoding for French description of __char function. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### General - [Bug 54504](https://bz.apache.org/bugzilla/show_bug.cgi?id=54504) - Resource string not found: [clipboard_node_read_error]. - [Bug 54538](https://bz.apache.org/bugzilla/show_bug.cgi?id=54538) - GUI: context menu is too big. - [Bug 54847](https://bz.apache.org/bugzilla/show_bug.cgi?id=54847) - Cut & Paste is broken with tree multi-selection. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54870](https://bz.apache.org/bugzilla/show_bug.cgi?id=54870) - Tree drag and drop may lose leaf nodes (affected nightly build). Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55056](https://bz.apache.org/bugzilla/show_bug.cgi?id=55056) - wasted work in Data.append(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55129](https://bz.apache.org/bugzilla/show_bug.cgi?id=55129) - Change Javadoc generation per CVE-2013-1571, VU#225657. - [Bug 55187](https://bz.apache.org/bugzilla/show_bug.cgi?id=55187) - Integer overflow when computing ONE_YEAR_MS in HTTP CacheManager. - [Bug 55208](https://bz.apache.org/bugzilla/show_bug.cgi?id=55208) - JSR223 language entries are duplicated; fold to lower case. - [Bug 55203](https://bz.apache.org/bugzilla/show_bug.cgi?id=55203) - TestBeanGUI - wrong language settings found. - [Bug 55065](https://bz.apache.org/bugzilla/show_bug.cgi?id=55065) - Useless processing in Spline3.converge(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55064](https://bz.apache.org/bugzilla/show_bug.cgi?id=55064) - Useless processing in ReportTreeListener.isValidDragAction(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55242](https://bz.apache.org/bugzilla/show_bug.cgi?id=55242) - BeanShell Client jar throws exceptions after upgrading to 2.8. - [Bug 55288](https://bz.apache.org/bugzilla/show_bug.cgi?id=55288) - JMeter should default to 0 retries for HTTP requests. - [Bug 55405](https://bz.apache.org/bugzilla/show_bug.cgi?id=55405) - ant download_jars task fails if lib/api or lib/doc are missing. Contributed by Antonio Gomes Rodrigues. - [Bug 55427](https://bz.apache.org/bugzilla/show_bug.cgi?id=55427) - TestBeanHelper should ignore properties not supported by GenericTestBeanCustomizer - [Bug 55459](https://bz.apache.org/bugzilla/show_bug.cgi?id=55459) - Elements using ComboStringEditor lose the input value if user selects another Test Element - [Bug 54152](https://bz.apache.org/bugzilla/show_bug.cgi?id=54152) - In distributed testing : activeThreads always show 0 in GUI and Summariser - [Bug 55509](https://bz.apache.org/bugzilla/show_bug.cgi?id=55509) - Allow Plugins to be notified of remote thread number progression - [Bug 55572](https://bz.apache.org/bugzilla/show_bug.cgi?id=55572) - Detail popup of parameter does not show a Scrollbar when content exceeds display - [Bug 55580](https://bz.apache.org/bugzilla/show_bug.cgi?id=55580) - Help pane does not scroll to start for <a href="#"> links - [Bug 55600](https://bz.apache.org/bugzilla/show_bug.cgi?id=55600) - JSyntaxTextArea : Strange behaviour on first undo - [Bug 55655](https://bz.apache.org/bugzilla/show_bug.cgi?id=55655) - NullPointerException when Remote stopping /shutdown all if one engine did not start correctly. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55657](https://bz.apache.org/bugzilla/show_bug.cgi?id=55657) - Remote and Local Stop/Shutdown buttons state does not take into account local / remote status ## Improvements #### HTTP Samplers and Proxy - HTTP Request: Small user interaction improvements in Row parameter Detail Box. Contributed by Milamber - [Bug 55255](https://bz.apache.org/bugzilla/show_bug.cgi?id=55255) - Allow Body in HTTP DELETE method to support API that use it (like ElasticSearch). - [Bug 53480](https://bz.apache.org/bugzilla/show_bug.cgi?id=53480) - Add Kerberos support to Http Sampler (HttpClient4). Based on patch by Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 54874](https://bz.apache.org/bugzilla/show_bug.cgi?id=54874) - Support device in addition to source IP address. Based on patch by Dan Fruehauf (malkodan at gmail.com) - [Bug 55488](https://bz.apache.org/bugzilla/show_bug.cgi?id=55488) - Add .ico and .woff file extension to default suggested exclusions in proxy recorder. Contributed by Antonio Gomes Rodrigues - [Bug 55525](https://bz.apache.org/bugzilla/show_bug.cgi?id=55525) - Proxy should support alias for keyserver entry - [Bug 55531](https://bz.apache.org/bugzilla/show_bug.cgi?id=55531) - Proxy recording and redirects. Added code to disable redirected samples. - [Bug 55507](https://bz.apache.org/bugzilla/show_bug.cgi?id=55507) - Proxy SSL recording does not handle external embedded resources well - [Bug 55632](https://bz.apache.org/bugzilla/show_bug.cgi?id=55632) - Have a new implementation of htmlParser for embedded resources parsing with better performances - [Bug 55653](https://bz.apache.org/bugzilla/show_bug.cgi?id=55653) - HTTP(S) Test Script Recorder should set TransactionController property "Include duration of timer and pre-post processors in generated sample" to false #### Other samplers - [Bug 54788](https://bz.apache.org/bugzilla/show_bug.cgi?id=54788) - JMS Point-to-Point Sampler - GUI enhancements to increase readability and ease of use. Contributed by Bruno Antunes (b.m.antunes at gmail.com) - [Bug 54798](https://bz.apache.org/bugzilla/show_bug.cgi?id=54798) - Using subject from EML-file for SMTP Sampler. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 54759](https://bz.apache.org/bugzilla/show_bug.cgi?id=54759) - SSLPeerUnverifiedException using HTTPS , property documented. - [Bug 54896](https://bz.apache.org/bugzilla/show_bug.cgi?id=54896) - JUnit sampler gives only "failed to create an instance of the class" message with constructor problems. - [Bug 55084](https://bz.apache.org/bugzilla/show_bug.cgi?id=55084) - Add timeout support for JDBC Request. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 55403](https://bz.apache.org/bugzilla/show_bug.cgi?id=55403) - Enhancement to OS sampler: Support for timeout - [Bug 55518](https://bz.apache.org/bugzilla/show_bug.cgi?id=55518) - Add ability to limit number of cached PreparedStatements per connection when "Prepared Select Statement", "Prepared Update Statement" or "Callable Statement" query type is selected #### Controllers - [Bug 54271](https://bz.apache.org/bugzilla/show_bug.cgi?id=54271) - Module Controller breaks if test plan is renamed. #### Listeners - [Bug 54532](https://bz.apache.org/bugzilla/show_bug.cgi?id=54532) - Improve Response Time Graph Y axis scale with huge values or small values (< 1000ms). Add a new field to define increment scale. Contributed by Milamber based on patch by Luca Maragnani (luca.maragnani at gmail.com) - [Bug 54576](https://bz.apache.org/bugzilla/show_bug.cgi?id=54576) - View Results Tree : Add a CSS/JQuery Tester. - [Bug 54777](https://bz.apache.org/bugzilla/show_bug.cgi?id=54777) - Improve Performance of default ResultCollector. Based on patch by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 55389](https://bz.apache.org/bugzilla/show_bug.cgi?id=55389) - Show IP source address in request data #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54789](https://bz.apache.org/bugzilla/show_bug.cgi?id=54789) - XPath Assertion - GUI enhancements to increase readability and ease of use. #### Functions - [Bug 54991](https://bz.apache.org/bugzilla/show_bug.cgi?id=54991) - Add functions to encode/decode URL encoded chars (__urlencode and __urldecode). Contributed by Milamber. #### I18N - [Bug 55241](https://bz.apache.org/bugzilla/show_bug.cgi?id=55241) - Need GUI Editor to process fields which are based on Enums with localised display strings - [Bug 55440](https://bz.apache.org/bugzilla/show_bug.cgi?id=55440) - ComboStringEditor should allow tags to be language dependent - [Bug 55432](https://bz.apache.org/bugzilla/show_bug.cgi?id=55432) - CSV Dataset Config loses sharing mode when switching languages #### General - [Bug 54584](https://bz.apache.org/bugzilla/show_bug.cgi?id=54584) - MongoDB plugin. Based on patch by Jan Paul Ettles (janpaulettles at gmail.com) - [Bug 54669](https://bz.apache.org/bugzilla/show_bug.cgi?id=54669) - Add flag forcing non-GUI JVM to exit after test. Contributed by Scott Emmons - [Bug 42428](https://bz.apache.org/bugzilla/show_bug.cgi?id=42428) - Workbench not saved with Test Plan. Contributed by Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [Bug 54825](https://bz.apache.org/bugzilla/show_bug.cgi?id=54825) - Add shortcuts to move elements in the tree. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54834](https://bz.apache.org/bugzilla/show_bug.cgi?id=54834) - Improve Drag & Drop in the jmeter tree. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54839](https://bz.apache.org/bugzilla/show_bug.cgi?id=54839) - Set the application name on Mac. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54841](https://bz.apache.org/bugzilla/show_bug.cgi?id=54841) - Correctly handle the quit shortcut on Mac Os (CMD-Q). Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54844](https://bz.apache.org/bugzilla/show_bug.cgi?id=54844) - Set the application icon on Mac Os. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54864](https://bz.apache.org/bugzilla/show_bug.cgi?id=54864) - Enable multi selection drag & drop in the tree without having to start dragging before releasing Shift or Control. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54945](https://bz.apache.org/bugzilla/show_bug.cgi?id=54945) - Add Shutdown Hook to enable trapping kill or CTRL+C signals. - [Bug 54990](https://bz.apache.org/bugzilla/show_bug.cgi?id=54990) - Download large files avoiding outOfMemory. - [Bug 55085](https://bz.apache.org/bugzilla/show_bug.cgi?id=55085) - UX Improvement : Ability to create New Test Plan from Templates. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55172](https://bz.apache.org/bugzilla/show_bug.cgi?id=55172) - Provide plugins a way to add Top Menu and menu items. - [Bug 55202](https://bz.apache.org/bugzilla/show_bug.cgi?id=55202) - Add syntax color for scripts elements (BeanShell, BSF, and JSR223) and JDBC elements with RSyntaxTextArea. Contributed by Milamber based on patch by Marko Vlahovic (vlahovic74 at gmail.com) - [Bug 55175](https://bz.apache.org/bugzilla/show_bug.cgi?id=55175) - HTTPHC4Impl refactoring to allow better inheritance. - [Bug 55236](https://bz.apache.org/bugzilla/show_bug.cgi?id=55236) - Templates - provide button to reload template details. - [Bug 55237](https://bz.apache.org/bugzilla/show_bug.cgi?id=55237) - Template system should support relative fileName entries. - [Bug 55423](https://bz.apache.org/bugzilla/show_bug.cgi?id=55423) - BatchSampleSender: Reduce locking granularity by moving listener.processBatch outside of synchronized block - [Bug 55424](https://bz.apache.org/bugzilla/show_bug.cgi?id=55424) - Add Stripping to existing SampleSenders - [Bug 55451](https://bz.apache.org/bugzilla/show_bug.cgi?id=55451) - Test Element GUI with JSyntaxTextArea scroll down when text content is long enough to add a Scrollbar - [Bug 55513](https://bz.apache.org/bugzilla/show_bug.cgi?id=55513) - StreamCopier cannot be used with System.err or System.out as it closes the output stream - [Bug 55514](https://bz.apache.org/bugzilla/show_bug.cgi?id=55514) - SystemCommand should support arbitrary input and output streams - [Bug 55515](https://bz.apache.org/bugzilla/show_bug.cgi?id=55515) - SystemCommand should support chaining of commands - [Bug 55606](https://bz.apache.org/bugzilla/show_bug.cgi?id=55606) - Use JSyntaxtTextArea for Http Request, JMS Test Elements - [Bug 55651](https://bz.apache.org/bugzilla/show_bug.cgi?id=55651) - Change JMeter application icon to Apache plume icon ## Non-functional changes - Updated to jsoup-1.7.2 - [Bug 54776](https://bz.apache.org/bugzilla/show_bug.cgi?id=54776) - Update the dependency on Bouncy Castle to 1.48. Contributed by Emmanuel Bourg (ebourg at apache.org) - Updated to HttpComponents Client 4.2.6 (from 4.2.3) - Updated to HttpComponents Core 4.2.5 (from 4.2.3) - Updated to commons-codec 1.8 (from 1.6) - Updated to commons-io 2.4 (from 2.2) - Updated to commons-logging 1.1.3 (from 1.1.1) - Updated to commons-net 3.3 (from 3.1) - Updated to jdom-1.1.3 (from 1.1.2) - Updated to jodd-lagarto and jodd-core 3.4.8 (from 3.4.1) - Updated to junit 4.11 (from 4.10) - Updated to slf4j-api 1.7.5 (from 1.7.2) - Updated to tika 1.4 (from 1.3) - Updated to xmlgraphics-commons 1.5 (from 1.3.1) - Updated to xstream 1.4.4 (from 1.4.2) - Updated to BouncyCastle 1.49 (from 1.48) - [Bug 54912](https://bz.apache.org/bugzilla/show_bug.cgi?id=54912) - JMeterTreeListener should use constants. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54903](https://bz.apache.org/bugzilla/show_bug.cgi?id=54903) - Remove the dependency on the Activation Framework. Contributed by Emmanuel Bourg (ebourg at apache.org) - Moved commons-lang (2.6) to lib/doc as it's only needed by Velocity. - Re-organised and simplified NOTICE and LICENSE files. - [Bug 55411](https://bz.apache.org/bugzilla/show_bug.cgi?id=55411) - NativeCommand could be useful elsewhere. Copied code to o.a.jorphan.exec. - [Bug 55435](https://bz.apache.org/bugzilla/show_bug.cgi?id=55435) - ComboStringEditor could be simplified to make most settings final - [Bug 55436](https://bz.apache.org/bugzilla/show_bug.cgi?id=55436) - ComboStringEditor should implement ClearGui - [Bug 55463](https://bz.apache.org/bugzilla/show_bug.cgi?id=55463) - Component.requestFocus() is discouraged; use requestFocusInWindow() instead - [Bug 55486](https://bz.apache.org/bugzilla/show_bug.cgi?id=55486) - New JMeter Logo. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55548](https://bz.apache.org/bugzilla/show_bug.cgi?id=55548) - Tidy up use of TestElement.ENABLED; use TestElement.isEnabled()/setEnabled() throughout - [Bug 55617](https://bz.apache.org/bugzilla/show_bug.cgi?id=55617) - Improvements to jorphan collection. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55623](https://bz.apache.org/bugzilla/show_bug.cgi?id=55623) - Invalid/unexpected configuration values should not be silently ignored - [Bug 55626](https://bz.apache.org/bugzilla/show_bug.cgi?id=55626) - Rename HTTP Proxy Server as HTTP(S) Test Script Recorder ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Bruno Antunes (b.m.antunes at gmail.com) - Emmanuel Bourg (ebourg at apache.org) - Scott Emmons - Mikhail Epikhin (epihin-m at yandex.ru) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - Luca Maragnani (luca.maragnani at gmail.com) - Milamber - Adrian Nistor (nistor1 at illinois.edu) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - UBIK Load Pack (support at ubikloadpack.com) - Benoit Wiart (benoit.wiart at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Immanuel Hayden (immanuel.hayden at gmail.com) - Danny Lade (dlade at web.de) - Brent Cromarty (brent.cromarty at yahoo.ca) - Wolfgang Heider (wolfgang.heider at racon.at) - Shmuel Krakower (shmulikk at gmail.com) Apologies if we have omitted anyone else. ## Version 2.9 ### New and Noteworthy #### Core Improvements: ##### * A new Extractor that uses CSS or jquery-like selector syntax has been introduced, it allows using either JODD or JSOUP implementations ![changes/2.9/01_css_jquery_extractor.png](/images/screenshots/changes/2.9/01_css_jquery_extractor.png) Result: the title of the page in a JMeter variable ![changes/2.9/01_css_jquery_extractor_resul.png](/images/screenshots/changes/2.9/01_css_jquery_extractor_resul.png) ##### * JMeter can now handle different types of documents (PDF, MsOffice files, Apache OpenOffice's files, …) within different elements - Regular Expression Extractor, extract text from documents - Assertion Response, check text in documents - View Results Tree, view as a text the documents ![changes/2.9/02_document_render_view_results_tree.png](/images/screenshots/changes/2.9/02_document_render_view_results_tree.png) ##### * A new Regex User Parameters Pre-Processor that enables injecting input parameter names and values using a reference extracted by Regular Expression Extractor from a previous response ![changes/2.9/13_regex_user_params.png](/images/screenshots/changes/2.9/13_regex_user_params.png) ##### * TCP Sampler: new options TCP Sampler has been enhanced with new options to allow setting **Close Connection**, **SO_LINGER** and **End of line(EOL) byte value** ![changes/2.9/03_new_options_tcp_sampler.png](/images/screenshots/changes/2.9/03_new_options_tcp_sampler.png) ##### * A new function ___escapeOroRegexpChars(,)_ has been introduced quote ORO regexp meta characters ##### * ForEach Controller: new fields ForEach Controller has now 2 new fields to control start and end of loop ![changes/2.9/04_for_each_new_fields.png](/images/screenshots/changes/2.9/04_for_each_new_fields.png) ##### * Result Status Action Handler now has a new option to "Start next thread loop" ![changes/2.9/05_result_status_action_handler.png](/images/screenshots/changes/2.9/05_result_status_action_handler.png) ##### * JMS Publisher: new option JMS Publisher can now send Bytes Messages ![changes/2.9/11_jms_publisher_bytes.png](/images/screenshots/changes/2.9/11_jms_publisher_bytes.png) ##### * Memory and performance improvements Significant improvements have been done in this version on memory usage per Thread and CPU when more than one Post Processor is used as child of a Sampler JSR223 Elements (enable using Groovy, Scala, … as scripting languages) have been improved to enable caching of Compilation results when scripts are passed in Text area ![changes/2.9/12_jsr223_sampler.png](/images/screenshots/changes/2.9/12_jsr223_sampler.png) Some configuration defaults have changed to improve performances by default(see [Bug 54412](https://bz.apache.org/bugzilla/show_bug.cgi?id=54412)), see description in New and Noteworthy section. - Distributed testing now uses MODE_STRIPPED_BATCH, which returns samples in batch mode (every 100 samples or every minute by default). Note also that MODE_STRIPPED_BATCH strips response data from SampleResult, so if you need it change to another mode (mode property in jmeter.properties) - Result data are now saved to CSV by default (jmeter.save.saveservice.output_format in jmeter.properties) ##### * XPath Assertion now enables using a JMeter variable as input ![changes/2.9/14_xpath_assertion.png](/images/screenshots/changes/2.9/14_xpath_assertion.png) #### GUI and ergonomy Improvements: ##### * Search feature has been improved to search within more internal fields of elements and expand search results ##### * Copy/paste is now possible between 2 JMeter instances >= 2.9 version Copy element(s) from one JMeter instance: ![changes/2.9/06_copy_paste_between_2_jmeter1.png](/images/screenshots/changes/2.9/06_copy_paste_between_2_jmeter1.png) Paste element(s) into a second JMeter instance: ![changes/2.9/06_copy_paste_between_2_jmeter2.png](/images/screenshots/changes/2.9/06_copy_paste_between_2_jmeter2.png) ##### * HTTP Header Manager Allow copy from clipboard to HeaderPanel, headers are supposed to be separated by new line and have the following form _name:value_ ![changes/2.9/07_header_panel_add_from_clipboard.png](/images/screenshots/changes/2.9/07_header_panel_add_from_clipboard.png) ##### * Module Controller Module Controller has been improved to better render referenced controller and expand it by clicking on a new button ![changes/2.9/08_module_controller_improvements.png](/images/screenshots/changes/2.9/08_module_controller_improvements.png) ##### * HTTP Proxy Server HTTP Proxy Server now has a button to add a set of default exclusions for URL patterns, this list can be configured through property : _proxy.excludes.suggested_ ![changes/2.9/09_proxy_excludes_suggested.png](/images/screenshots/changes/2.9/09_proxy_excludes_suggested.png) ##### * Rendering of target controller has been improved in HTTP Proxy Server #### HTTP Proxy Server recording: * HTTP Proxy Server now automatically uses HTTP Request with Raw Post Body mode for samples that only have one unnamed argument (JSON, XML, GWT, …) * HTTP Proxy Server does not force user to select the type of Sampler in HTTP Sampler Settings, this allows easier switch between implementations as Sampler do not have this information set anymore ![changes/2.9/10_http_proxy_dont_force_http_type.png](/images/screenshots/changes/2.9/10_http_proxy_dont_force_http_type.png) * SamplerCreator interface has been enriched to meet new requirements for plug-in providers * It is now possible to create binary sampler for x-www-form-urlencoded POST request by modifying _proxy.binary.types_ property to add application/x-www-form-urlencoded * Improved timestamp format auto-detection when reading CSV files ### Known bugs The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). Webservice sampler does not consider the HTTP response status to compute the status of a response, thus a response 500 containing a non empty body will be considered as successful, see [Bug 54006](https://bz.apache.org/bugzilla/show_bug.cgi?id=54006). To workaround this issue, ensure you always read the response and add a Response Assertion checking text inside the response. Changing language can break part of the configuration of the following elements (see [Bug 53679](https://bz.apache.org/bugzilla/show_bug.cgi?id=53679)): - CSV Data Set Config (sharing mode will be lost) - Constant Throughput Timer (Calculate throughput based on will be lost) The numbers that appear to the left of the green box are the number of active threads / total number of threads, these only apply to a locally run test; they do not include any threads started on remote systems when using client-server mode, (see [Bug 54152](https://bz.apache.org/bugzilla/show_bug.cgi?id=54152)). Note that there is a bug in Java on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. ### Incompatible changes **JMeter requires now a Java 6 runtime or higher.** Some configuration defaults have changed to improve performances by default (see [Bug 54412](https://bz.apache.org/bugzilla/show_bug.cgi?id=54412)), see description in New and Noteworthy section. Webservice sampler now adds to request the headers that are set through Header Manager, these were previously ignored _jdbcsampler.cachesize_ property has been removed, it previously limited the size of a per connection cache of Map < String, PreparedStatement > , it also limited the size of this map which held the PreparedStatement for SQL queries. This limitation provoked a bug [Bug 53995](https://bz.apache.org/bugzilla/show_bug.cgi?id=53995). It has been removed so now size of these 2 maps is not limited anymore. This change changes behaviour as starting from this version no PreparedStatement will be closed during the test. Starting with this version, there are some important changes on JSR223 Test Elements: - JSR223 Test Elements that have an invalid filename (not existing or unreadable) will make test fail instead of making the element silently work - In JSR223 Test Elements: responseCodeOk, responseMessageOK and successful are set before script is executed, if responseData is set it will not be overridden anymore by a toString() on script return value View Results Tree now considers response with missing content type as text. In remote Test mode, JMeter now exits in error if one of the remote engines cannot be configured, previously it started the test with available engines. ### Bug fixes #### HTTP Samplers and Proxy - Don't log spurious warning messages when using concurrent pool embedded downloads with Cache Manager or CookieManager - [Bug 54057](https://bz.apache.org/bugzilla/show_bug.cgi?id=54057)- Proxy option to set user and password at startup (-u and -a) not working with HTTPClient 4 - [Bug 54187](https://bz.apache.org/bugzilla/show_bug.cgi?id=54187) - Request tab does not show headers if request fails - [Bug 53840](https://bz.apache.org/bugzilla/show_bug.cgi?id=53840) - Proxy Recording : Response message: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "" " - [Bug 54351](https://bz.apache.org/bugzilla/show_bug.cgi?id=54351) - HC4 and URI fragments is failing #### Other Samplers - [Bug 53997](https://bz.apache.org/bugzilla/show_bug.cgi?id=53997) - LDAP Extended Request: Escape ampersand (&), left angle bracket (<) and right angle bracket (>) in search filter tag in XML response data - [Bug 53995](https://bz.apache.org/bugzilla/show_bug.cgi?id=53995) - AbstractJDBCTestElement shares PreparedStatement between multi-threads - [Bug 54119](https://bz.apache.org/bugzilla/show_bug.cgi?id=54119) - HTTP 307 response is not redirected - [Bug 54326](https://bz.apache.org/bugzilla/show_bug.cgi?id=54326) - AjpSampler send file in post throws FileNotFoundException - [Bug 54331](https://bz.apache.org/bugzilla/show_bug.cgi?id=54331) - AjpSampler throws null pointer on GET request that are protected #### Controllers #### Listeners - [Bug 54088](https://bz.apache.org/bugzilla/show_bug.cgi?id=54088) - The type video/f4m is text, not binary - [Bug 54166](https://bz.apache.org/bugzilla/show_bug.cgi?id=54166) - ViewResultsTree could not render the HTML response: handle failure to parse HTML - [Bug 54287](https://bz.apache.org/bugzilla/show_bug.cgi?id=54287) - Incorrect Timestamp in Response Time Graph when using a date with time in Date format field - [Bug 54451](https://bz.apache.org/bugzilla/show_bug.cgi?id=54451) - Response Time Graph reports wrong times when the are many samples for same time - [Bug 54459](https://bz.apache.org/bugzilla/show_bug.cgi?id=54459) - CSVSaveService does not handle date parsing very well #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54058](https://bz.apache.org/bugzilla/show_bug.cgi?id=54058) - In HTTP Request Defaults, the value of field "Embedded URLs must match: is not saved if the check box "Retrieve All Embedded Resources" is not checked. - [Bug 54375](https://bz.apache.org/bugzilla/show_bug.cgi?id=54375) - Regular Expression Extractor : When regex syntax is wrong, post processing is stopped #### Functions #### I18N #### General - [Bug 53975](https://bz.apache.org/bugzilla/show_bug.cgi?id=53975) - Variables replacement doesn't work with option "Delay thread creation until needed" - [Bug 54055](https://bz.apache.org/bugzilla/show_bug.cgi?id=54055) - View Results tree: = signs are stripped from parameter values at HTTP tab - [Bug 54129](https://bz.apache.org/bugzilla/show_bug.cgi?id=54129) - Search Feature does not find text although existing in elements - [Bug 54023](https://bz.apache.org/bugzilla/show_bug.cgi?id=54023) - Unable to start JMeter from a root directory and if the full path of JMeter installation contains one or more spaces (Unix/linux) - [Bug 54172](https://bz.apache.org/bugzilla/show_bug.cgi?id=54172) - Duplicate shortcut key not working and CTRL+C / CTRL+V / CTRL+V do not cancel default event - [Bug 54057](https://bz.apache.org/bugzilla/show_bug.cgi?id=54057) - Proxy option to set user and password at startup (-u and -a) not working with HTTPClient 4 - [Bug 54267](https://bz.apache.org/bugzilla/show_bug.cgi?id=54267) - Start Next Thread Loop setting doesn't work in custom thread groups - [Bug 54413](https://bz.apache.org/bugzilla/show_bug.cgi?id=54413) - DataStrippingSampleSender returns 0 for number of bytes of any response ### Improvements #### HTTP Samplers - [Bug 54185](https://bz.apache.org/bugzilla/show_bug.cgi?id=54185) - Allow query strings in paths that start with HTTP or HTTPS #### Other samplers - [Bug 54004](https://bz.apache.org/bugzilla/show_bug.cgi?id=54004) - Webservice Sampler : Allow adding headers to request with Header Manager - [Bug 54106](https://bz.apache.org/bugzilla/show_bug.cgi?id=54106) - JSR223TestElement should check for file existence when a filename is set instead of using Text Area content - [Bug 54107](https://bz.apache.org/bugzilla/show_bug.cgi?id=54107) - JSR223TestElement : Enable compilation and caching of Script Text - [Bug 54109](https://bz.apache.org/bugzilla/show_bug.cgi?id=54109) - JSR223TestElement : SampleResult properties should be set before entering script to allow user setting different code - [Bug 54230](https://bz.apache.org/bugzilla/show_bug.cgi?id=54230) - TCP Sampler, additions of "Close Connection", "SO_LINGER" and "End of line(EOL) byte value" options - [Bug 54182](https://bz.apache.org/bugzilla/show_bug.cgi?id=54182) - Support sending of ByteMessage for JMS Publisher. #### Controllers - [Bug 54131](https://bz.apache.org/bugzilla/show_bug.cgi?id=54131) - ForEach Controller : Add start and end index for looping over variables - [Bug 54132](https://bz.apache.org/bugzilla/show_bug.cgi?id=54132) - Module Controller GUI : Improve rendering of referenced controller - [Bug 54155](https://bz.apache.org/bugzilla/show_bug.cgi?id=54155) - ModuleController : Add a shortcut button to unfold the tree up to referenced controller and highlight it #### Listeners - [Bug 54200](https://bz.apache.org/bugzilla/show_bug.cgi?id=54200) - Add support of several document types (like Apache OpenOffice's files, MS Office's files, PDF's files, etc.) to the elements View Results Tree, Assertion Response and Regular Expression Extractor (using Apache Tika) - [Bug 54226](https://bz.apache.org/bugzilla/show_bug.cgi?id=54226) - View Results Tree : Show response even when server does not return ContentType header #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54259](https://bz.apache.org/bugzilla/show_bug.cgi?id=54259) - Introduce a new Extractor that uses CSS or jquery-like selector syntax - [Bug 45772](https://bz.apache.org/bugzilla/show_bug.cgi?id=45772) - RegEx User Parameters Post Processor - [Bug 54160](https://bz.apache.org/bugzilla/show_bug.cgi?id=54160) - Add support for xpath assertion to apply to a JMeter variable. #### Functions - [Bug 54189](https://bz.apache.org/bugzilla/show_bug.cgi?id=54189) - Add a function to quote ORO regexp meta characters - [Bug 54418](https://bz.apache.org/bugzilla/show_bug.cgi?id=54418) - UUID Function #### I18N #### General - [Bug 54005](https://bz.apache.org/bugzilla/show_bug.cgi?id=54005) - HTTP Mirror Server : Add special headers "X-" to control Response status and response content - [Bug 53875](https://bz.apache.org/bugzilla/show_bug.cgi?id=53875) - Include suggested defaults for URL filters on HTTP Proxy - [Bug 54031](https://bz.apache.org/bugzilla/show_bug.cgi?id=54031) - Add tooltip to running/total threads indicator - Webservice (SOAP) Request has been deprecated - [Bug 54161](https://bz.apache.org/bugzilla/show_bug.cgi?id=54161) - Proxy : be able to create binary sampler for x-www-form-urlencoded POST request - [Bug 54154](https://bz.apache.org/bugzilla/show_bug.cgi?id=54154) - HTTP Proxy Server should not force user to select the type of Sampler in HTTP Sampler Settings - [Bug 54165](https://bz.apache.org/bugzilla/show_bug.cgi?id=54165) - Proxy Server: Improve rendering of target controller - [Bug 46677](https://bz.apache.org/bugzilla/show_bug.cgi?id=46677) - Copying Test Elements between test plans - [Bug 54204](https://bz.apache.org/bugzilla/show_bug.cgi?id=54204) - Result Status Action Handler : Add start next thread loop option - [Bug 54232](https://bz.apache.org/bugzilla/show_bug.cgi?id=54232) - Search Feature : Add a button to search and expand results - [Bug 54251](https://bz.apache.org/bugzilla/show_bug.cgi?id=54251) - Add tristate checkbox implementation - [Bug 54257](https://bz.apache.org/bugzilla/show_bug.cgi?id=54257) - Enhance SamplerCreator interface to meet new requirements - [Bug 54258](https://bz.apache.org/bugzilla/show_bug.cgi?id=54258) - Proxy : Use Raw Post Body when Sampler has one unnamed argument, useful for Samplers using POST method by of type JSON, XML, GWT body - [Bug 54268](https://bz.apache.org/bugzilla/show_bug.cgi?id=54268) - Improve CPU and memory usage - [Bug 54376](https://bz.apache.org/bugzilla/show_bug.cgi?id=54376) - ScopePanel : Allow configuring more precisely scopes - [Bug 54412](https://bz.apache.org/bugzilla/show_bug.cgi?id=54412) - Changing JMeter defaults to ensure better performances by default - [Bug 54414](https://bz.apache.org/bugzilla/show_bug.cgi?id=54414) - Remote Test should not start if one of the engines fails to start correctly ### Non-functional changes - [Bug 53956](https://bz.apache.org/bugzilla/show_bug.cgi?id=53956) - Add ability to paste (a list of values) from clipboard for Header Manager - Updated to HttpComponents Client 4.2.3 (from 4.2.1) - Updated to HttpComponents Core 4.2.3 (from 4.2.2) - [Bug 54110](https://bz.apache.org/bugzilla/show_bug.cgi?id=54110) - BSFTestElement and JSR223TestElement should use shared super-class for common fields - [Bug 54199](https://bz.apache.org/bugzilla/show_bug.cgi?id=54199) - Move to Java 6 - Upgraded to rhino 1.7R4 ## Version 2.8 ### New and Noteworthy #### Core Improvements: ##### Thread Group: New Option _Delay thread creation until needed_ New Option "Delay thread creation until needed" that will create and start threads when needed instead of creating them on Test startup **This new feature allows running tests with a huge number of short lived threads.** ![changes/2.8/12_delay_thread_creation.png](/images/screenshots/changes/2.8/12_delay_thread_creation.png) ##### HTTP Cookie Manager (IPv6 support) Add HTTPClient 4 cookie implementation in JMeter. Cookie Manager has now the default HC3.1 implementation and a new choice HC4 implementation (compliant with IPv6 address) ![changes/2.8/11_hc4_cookie.png](/images/screenshots/changes/2.8/11_hc4_cookie.png) ##### Memory and performance improvements Significant improvements have been done in this version on memory usage of JMeterThread JSR223 Elements (enable using Groovy, scala, … as scripting languages) have been improved to enable: - usage of Compilable interface when available to boost CPU usage - caching of Compilation when scripts are used as Files See [JMeter Performances across versions](https://cwiki.apache.org/confluence/display/JMETER/JMeterPerformance) ##### OS Process Sampler Allow defining files for stdout/stderr/stdin. ![changes/2.8/06_os_sampler_stdout-err-in.png](/images/screenshots/changes/2.8/06_os_sampler_stdout-err-in.png) ##### HTTP Request: PATCH verb Add PATCH verb to HTTP sampler ![changes/2.8/01_http_patch_verb.png](/images/screenshots/changes/2.8/01_http_patch_verb.png) ##### HTTP Request: HTTPClient 4 is now the default implementation HTTPClient 4 is now the default HTTP Request implementation (and for Proxy element when generating HTTP requests). Previously the default was the HTTP Java implementation (i.e. the implementation provided by the JVM) ![changes/2.8/02_http_default_hc4.png](/images/screenshots/changes/2.8/02_http_default_hc4.png) ##### HTTP Request Add Embedded URL Filter to HTTP Request Defaults Control (it was already present for HTTP Requests) ![changes/2.8/05_http_defaults_url_filter.png](/images/screenshots/changes/2.8/05_http_defaults_url_filter.png) ##### Miscellaneous - CSV Dataset : Embedded new lines are now supported in quoted data - JMX files now contain the version of JMeter that created the file - JMeter Version is now available as property "jmeter.version" #### Reporting Improvements: ##### Response Time Graph Add a new visualizer Response Time Graph to draw a line graph showing the evolution of response time for a test ![changes/2.8/09_resp_time_graph.png](/images/screenshots/changes/2.8/09_resp_time_graph.png) Settings for Response Time Graph ![changes/2.8/08_resp_time_graph_settings.png](/images/screenshots/changes/2.8/08_resp_time_graph_settings.png) ##### View Results in Table Add latency to View Result in Table listener ![changes/2.8/10_latency_view_results_table.png](/images/screenshots/changes/2.8/10_latency_view_results_table.png) ##### Aggregate Graph Small improvements: legend at left or right is now on 1 column (instead of 1 large line), … ![changes/2.8/07_aggregate_graph_legend_left_right.png](/images/screenshots/changes/2.8/07_aggregate_graph_legend_left_right.png) #### GUI and ergonomy Improvements: ##### HTTP Proxy Server simplifications HTTPS Spoofing options have been removed from Proxy as HTTPS recording is directly available since JMeter 2.4. ![changes/2.8/03_remove_https_spoofing1.png](/images/screenshots/changes/2.8/03_remove_https_spoofing1.png) ##### HTTP Proxy Server Allow URL Filters to be pasted from clipboard ![changes/2.8/15_add_from_clipboard_filter.png](/images/screenshots/changes/2.8/15_add_from_clipboard_filter.png) ##### Find in JMeter CTRL + F for the new Find feature ![changes/2.8/14_ctrl_F_shortcut.png](/images/screenshots/changes/2.8/14_ctrl_F_shortcut.png) ESC key now closes popups. ##### User Interface in GNOME 3 Display 'Apache JMeter' title in app title bar in Gnome 3 ![changes/2.8/13_gnome3_title.png](/images/screenshots/changes/2.8/13_gnome3_title.png) ### Known bugs The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). Changing language can break part of the configuration of the following elements (see [Bug 53679](https://bz.apache.org/bugzilla/show_bug.cgi?id=53679)): - CSV Data Set Config (sharing mode will be lost) - Constant Throughput Timer (Calculate throughput based on will be lost) Note that there is a bug in Java on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. ### Incompatible changes When using CacheManager, JMeter now caches responses for GET queries provided header Cache-Control is different from "no-cache" as described in specification. Furthermore it doesn't put anymore in Cache deprecated entries for "no-cache" responses. See [Bug 53521](https://bz.apache.org/bugzilla/show_bug.cgi?id=53521) and [Bug 53522](https://bz.apache.org/bugzilla/show_bug.cgi?id=53522) A major change has occurred on JSR223 Test Elements, previously variables set up before script execution where stored in ScriptEngineManager which was created once per execution, now ScriptEngineManager is a singleton shared by all JSR223 elements and only ScriptEngine is created once per execution, variables set up before script execution are now stored in Bindings created on each execution, see [Bug 53365](https://bz.apache.org/bugzilla/show_bug.cgi?id=53365). JSR223 Test Elements using Script file are now Compiled if ScriptEngine supports this feature, see [Bug 53520](https://bz.apache.org/bugzilla/show_bug.cgi?id=53520). Shortcut for Function Helper Dialog is now CTRL+F1 (CMD + F1 for Mac OS), CTRL+F (CMD+F1 for Mac OS) now opens Search Dialog. By default, the TestCompiler now stores details of which pairs it has seen in Controller instances rather than in a static Set. [[Bug 53796](https://bz.apache.org/bugzilla/show_bug.cgi?id=53796)] This gives much better memory behaviour for delayed start test plans, as memory used is proportional to the number of concurrent threads. With the static Set memory usage was proportional to the total thread count. This change is very unlikely to cause a problem. The original behaviour can be restored by setting the property `TestCompiler.useStaticSet=true` HTTPS Spoofing options have been removed from Proxy as HTTPS recording is directly available since JMeter 2.4. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 53521](https://bz.apache.org/bugzilla/show_bug.cgi?id=53521) - Cache Manager should cache content with Cache-control=private - [Bug 53522](https://bz.apache.org/bugzilla/show_bug.cgi?id=53522) - Cache Manager should not store at all response with header "no-cache" and store other types of Cache-Control having max-age value - [Bug 53838](https://bz.apache.org/bugzilla/show_bug.cgi?id=53838) - Pressing "Stop" does not interrupt the TCP sampler - [Bug 53911](https://bz.apache.org/bugzilla/show_bug.cgi?id=53911) - JmeterKeystore does not allow for key down the list of certificate #### Other Samplers - [Bug 53348](https://bz.apache.org/bugzilla/show_bug.cgi?id=53348) - JMeter JMS Point-to-Point Request-Response sampler doesn't work when Request-queue and Receive-queue are different - [Bug 53357](https://bz.apache.org/bugzilla/show_bug.cgi?id=53357) - JMS Point to Point reports too high response times in Request Response Mode - [Bug 53440](https://bz.apache.org/bugzilla/show_bug.cgi?id=53440) - SSL connection leads to ArrayStoreException on JDK 6 with some KeyManagerFactory SPI - [Bug 53511](https://bz.apache.org/bugzilla/show_bug.cgi?id=53511) - access log sampler SessionFilter throws NullPointerException - cookie manager not initialized properly - [Bug 53715](https://bz.apache.org/bugzilla/show_bug.cgi?id=53715) - JMeter does not load WSDL #### Controllers #### Listeners - [Bug 53742](https://bz.apache.org/bugzilla/show_bug.cgi?id=53742) - When jmeter.save.saveservice.sample_count is set to true, elapsed time read by listener is always equal to 0 - [Bug 53774](https://bz.apache.org/bugzilla/show_bug.cgi?id=53774) - RequestViewRaw does not show headers unless samplerData is non-null - [Bug 53802](https://bz.apache.org/bugzilla/show_bug.cgi?id=53802) - IdleTime values are not saved to CSV log - [Bug 53874](https://bz.apache.org/bugzilla/show_bug.cgi?id=53874) - View Results Tree : If some parameter containing special characters like % is not encoded, RequestViewHTTP fails with java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern and Response is not displayed #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 51512](https://bz.apache.org/bugzilla/show_bug.cgi?id=51512) - Cookies aren't inserted into HTTP request with IPv6 Host header #### Functions #### I18N #### General - [Bug 53365](https://bz.apache.org/bugzilla/show_bug.cgi?id=53365) - JSR223TestElement should cache ScriptEngineManager - [Bug 53520](https://bz.apache.org/bugzilla/show_bug.cgi?id=53520) - JSR223 Elements : Use Compilable interface to improve performances on File scripts - [Bug 53501](https://bz.apache.org/bugzilla/show_bug.cgi?id=53501) - Synchronization timer blocks test end. - [Bug 53750](https://bz.apache.org/bugzilla/show_bug.cgi?id=53750) - TestCompiler saves unnecessary entries in pairing collection - [Bug 52266](https://bz.apache.org/bugzilla/show_bug.cgi?id=52266) - Code:Inconsistent synchronization - [Bug 53841](https://bz.apache.org/bugzilla/show_bug.cgi?id=53841) - CSVSaveService reads file using JVM default file encoding instead of using the one configured in saveservice.properties - [Bug 53953](https://bz.apache.org/bugzilla/show_bug.cgi?id=53953) New: Typo in monitor test plan documentation ### Improvements #### HTTP Samplers - [Bug 53675](https://bz.apache.org/bugzilla/show_bug.cgi?id=53675) - Add PATCH verb to HTTP sampler - [Bug 53931](https://bz.apache.org/bugzilla/show_bug.cgi?id=53931) - Define HTTPClient 4 for the default HTTP Request (and Proxy element to generate the HTTP requests). Before the default, it was the HTTP Java Sampler - [Bug 53934](https://bz.apache.org/bugzilla/show_bug.cgi?id=53934) - Removes HTTPS spoofing options in JMeter HTTP Proxy Server. Since JMeter 2.4, the HTTPS protocol is directly supported by the proxy #### Other samplers - [Bug 55310](https://bz.apache.org/bugzilla/show_bug.cgi?id=55310) - TestAction should implement Interruptible - [Bug 53318](https://bz.apache.org/bugzilla/show_bug.cgi?id=53318) - Add Embedded URL Filter to HTTP Request Defaults Control - [Bug 53782](https://bz.apache.org/bugzilla/show_bug.cgi?id=53782) - Enhance JavaSampler handling of JavaSamplerClient cleanup to use less memory - [Bug 53168](https://bz.apache.org/bugzilla/show_bug.cgi?id=53168) - OS Process - allow specification of stdout/stderr/stdin - [Bug 53844](https://bz.apache.org/bugzilla/show_bug.cgi?id=53844) - JDBC related elements should check class of Variable Name supposed to contain JDBC Connection Configuration to avoid ClassCastException #### Controllers - [Bug 53671](https://bz.apache.org/bugzilla/show_bug.cgi?id=53671) - tearDown thread group to run even if shutdown test happens #### Listeners - [Bug 53566](https://bz.apache.org/bugzilla/show_bug.cgi?id=53566) - Don't log partial responses to the jmeter log - [Bug 53716](https://bz.apache.org/bugzilla/show_bug.cgi?id=53716) - Small improvements in aggregate graph: legend at left or right is now on 1 column (instead of 1 large line), no border to the reference's square color, reduce width on some fields - [Bug 53718](https://bz.apache.org/bugzilla/show_bug.cgi?id=53718) - Add a new visualizer 'Response Time Graph' to draw a line graph showing the evolution of response time for a test - [Bug 53738](https://bz.apache.org/bugzilla/show_bug.cgi?id=53738) - Keep track of number of threads started and finished - [Bug 53753](https://bz.apache.org/bugzilla/show_bug.cgi?id=53753) - Summariser: no point displaying fractional time in most cases - [Bug 53749](https://bz.apache.org/bugzilla/show_bug.cgi?id=53749) - TestListener interface could perhaps be split up. This should reduce per-thread memory requirements and processing, as only test elements that actually use testIterationStart functionality now need to be handled. - [Bug 53941](https://bz.apache.org/bugzilla/show_bug.cgi?id=53941) - Add latency to View Result table listener #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 53755](https://bz.apache.org/bugzilla/show_bug.cgi?id=53755) - Adding a HttpClient 4 cookie implementation in JMeter. Cookie Manager has now the default HC3.1 implementation and a new choice HC4 implementation (compliant with IPv6 address) #### Functions - [Bug 51527](https://bz.apache.org/bugzilla/show_bug.cgi?id=51527) - __time() function : add another option to __time() to provide *seconds* since epoch #### I18N #### General - [Bug 53364](https://bz.apache.org/bugzilla/show_bug.cgi?id=53364) - Sort list of Functions in Function Helper Dialog - [Bug 53418](https://bz.apache.org/bugzilla/show_bug.cgi?id=53418) - New Option "Delay thread creation until needed" that will create and start threads when needed instead of creating them on Test startup - [Bug 42245](https://bz.apache.org/bugzilla/show_bug.cgi?id=42245) - Show clear passwords in HTTP Authorization Manager - [Bug 53616](https://bz.apache.org/bugzilla/show_bug.cgi?id=53616) - Display 'Apache JMeter' title in app title bar in Gnome 3 - [Bug 53759](https://bz.apache.org/bugzilla/show_bug.cgi?id=53759) - ClientJMeterEngine performs unnecessary traverse using SearchByClass(TestListener) - [Bug 52601](https://bz.apache.org/bugzilla/show_bug.cgi?id=52601) - CTRL + F for the new Find feature - [Bug 53796](https://bz.apache.org/bugzilla/show_bug.cgi?id=53796) - TestCompiler uses static Set which can grow huge - [Bug 53673](https://bz.apache.org/bugzilla/show_bug.cgi?id=53673) - Add JMeter version in the jmx file - Add support for HeapDump to the JMeter non-GUI and GUI client - [Bug 53862](https://bz.apache.org/bugzilla/show_bug.cgi?id=53862) - Would be nice to have the JMeter Version available as a property - [Bug 53806](https://bz.apache.org/bugzilla/show_bug.cgi?id=53806) - FileServer should provide thread-safe parsing - [Bug 53807](https://bz.apache.org/bugzilla/show_bug.cgi?id=53807) - CSV Dataset does not handle embedded new lines in quoted data - [Bug 53879](https://bz.apache.org/bugzilla/show_bug.cgi?id=53879) - GUI : Allow Popups to be closed with ESC key - [Bug 53876](https://bz.apache.org/bugzilla/show_bug.cgi?id=53876) - Allow URL Filters (HTTP Proxy) to be pasted from clipboard ### Non-functional changes - [Bug 53311](https://bz.apache.org/bugzilla/show_bug.cgi?id=53311) - JMeterUtils#runSafe should not throw Error when interrupted - Updated to commons-net-3.1 (from 3.0.1) - Updated to HttpComponents Core 4.2.2 (from 4.1.4) and HttpComponents Client 4.2.1 (from 4.1.3) - [Bug 53765](https://bz.apache.org/bugzilla/show_bug.cgi?id=53765) - Switch to commons-lang3-3.1 - [Bug 53884](https://bz.apache.org/bugzilla/show_bug.cgi?id=53884) - wrong Maven groupId for commons-lang ## Version 2.7 ### New and Noteworthy #### OS Process Sampler A new System Sampler that can be used to execute commands on the local machine. ![changes/2.7/01_os_process_sampler.png](/images/screenshots/changes/2.7/01_os_process_sampler.png) OS Process Sampler results example with DNS lookup command 'dig' ![changes/2.7/02_os_process_example_results.png](/images/screenshots/changes/2.7/02_os_process_example_results.png) #### JMS Samplers improvements Addition of a "Non Persistent Delivery" option to send "Non-Persistent" (Guaranteed to be delivered at most once. Message loss is not a concern.) JMS messages ![changes/2.7/11_jms_non_persistent_delivery_mode.png](/images/screenshots/changes/2.7/11_jms_non_persistent_delivery_mode.png) Support sending of JMS Object Messages to enable sending Objects unmarshalled from XML by XStream ![changes/2.7/12_jms_sending_objects.png](/images/screenshots/changes/2.7/12_jms_sending_objects.png) Enable setting JMS Properties through JMS Publisher sampler ![changes/2.7/13_jms_properties.png](/images/screenshots/changes/2.7/13_jms_properties.png) #### Test Action sampler Allow premature exit from a loop ![changes/2.7/07_test_action_next_iter.png](/images/screenshots/changes/2.7/07_test_action_next_iter.png) #### Webservice Sampler improvements Add a jmeter property soap.document_cache to control size of Document Cache ![changes/2.7/14_ws_document_cache.png](/images/screenshots/changes/2.7/14_ws_document_cache.png) Make Maintain HTTP Session configurable ![changes/2.7/15_ws_maintain_session.png](/images/screenshots/changes/2.7/15_ws_maintain_session.png) #### Aggregate graph: Clustered Bar char with average, median, 90% line, min and max columns Aggregate graph changes to Clustered Bar chart, add more columns (median, 90% line, min, max) and options, fixed some bugs ![changes/2.7/03_aggregate_graph_with_new_cols.png](/images/screenshots/changes/2.7/03_aggregate_graph_with_new_cols.png) New settings for aggregate graph ![changes/2.7/04_aggregate_graph_parameters.png](/images/screenshots/changes/2.7/04_aggregate_graph_parameters.png) #### Improvements of HTML report design generated by JMeter Ant task in extras folder HTML report example ![changes/2.7/05_jmeter_ant_task_report_success.png](/images/screenshots/changes/2.7/05_jmeter_ant_task_report_success.png) HTML report example with some assertion errors ![changes/2.7/06_jmeter_ant_task_report_errors.png](/images/screenshots/changes/2.7/06_jmeter_ant_task_report_errors.png) #### Mailer Visualizer - Enable authentication, and connection security with SSL or TLS - Improve GUI design - Add internationalisation (i18n) support ![changes/2.7/10_mailer_visualizer_gui.png](/images/screenshots/changes/2.7/10_mailer_visualizer_gui.png) #### New Visual Indicator of number of ERROR/FATAL messages in logs Indicator shows number of ERROR/FATAL messages in logs, it can be clicked to toggle Log Viewer panel ![changes/2.7/16_log_errors_counter.png](/images/screenshots/changes/2.7/16_log_errors_counter.png) #### Dialog box to show detail of a parameter row Add a detail button on parameters table to show detail of a Row ![changes/2.7/08_param_button_detail.png](/images/screenshots/changes/2.7/08_param_button_detail.png) Detail box example ![changes/2.7/09_detail_box.png](/images/screenshots/changes/2.7/09_detail_box.png) #### Plugin writers New interface org.apache.jmeter.engine.util.ConfigMergabilityIndicator has been introduced to tell whether a ConfigTestElement can be merged in Sampler (see [Bug 53042](https://bz.apache.org/bugzilla/show_bug.cgi?id=53042)): ``` public boolean applies(ConfigTestElement configElement); ``` New interface org.apache.jmeter.protocol.http.proxy.SamplerCreator to allow plugging HTTP based samplers that differ from default HTTP Samplers through Proxy during Recording Phase (see [Bug 52674](https://bz.apache.org/bugzilla/show_bug.cgi?id=52674)): ``` public String[] getManagedContentTypes(); ``` ``` public HTTPSamplerBase createSampler(HttpRequestHdr request, Map<String, String> pageEncodings, Map<String, String> formEncodings); ``` ``` public void populateSampler(HTTPSamplerBase sampler, HttpRequestHdr request, Map<String, String> pageEncodings, Map<String, String> formEncodings) throws Exception; ``` ### Known bugs The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). ### Incompatible changes When doing replacement of User Defined Variables, Proxy will not substitute partial values anymore when "Regexp matching" is used. It will use Perl 5 word matching ("\b") In User Defined Variables, Test Plan, HTTP Sampler Arguments Table, Java Request Defaults, JMS Sampler and Publisher, LDAP Request Defaults and LDAP Extended Request Defaults, rows with empty Name and Value are no more saved. JMeter now expands the Test Plan tree to the testplan level and no further and selects the root of the tree. Furthermore default value of onload.expandtree is false. Graph Full Results Listener has been removed. When calling "Clear All" command, if Log Viewer is displayed its content will be cleared. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 52613](https://bz.apache.org/bugzilla/show_bug.cgi?id=52613) - Using Raw Post Body option, text gets encoded - [Bug 52781](https://bz.apache.org/bugzilla/show_bug.cgi?id=52781) - Content-Disposition header garbled even if browser compatible headers is checked (HC4) - [Bug 52796](https://bz.apache.org/bugzilla/show_bug.cgi?id=52796) - MonitorHandler fails to clear variables when starting a new parse - [Bug 52871](https://bz.apache.org/bugzilla/show_bug.cgi?id=52871) - Multiple Certificates not working with HTTP Client 4 - [Bug 52885](https://bz.apache.org/bugzilla/show_bug.cgi?id=52885) - Proxy : Recording issues with HTTPS, cookies starting with secure are partly truncated - [Bug 52886](https://bz.apache.org/bugzilla/show_bug.cgi?id=52886) - Proxy : Recording issues with HTTPS when spoofing is on, secure cookies are not always changed - [Bug 52897](https://bz.apache.org/bugzilla/show_bug.cgi?id=52897) - HTTPSampler : Using PUT method with HTTPClient4 and empty Content Encoding and sending files leads to NullPointerException - [Bug 53145](https://bz.apache.org/bugzilla/show_bug.cgi?id=53145) - HTTP Sampler - function in path evaluated too early #### Other Samplers - [Bug 51737](https://bz.apache.org/bugzilla/show_bug.cgi?id=51737) - TCPSampler : Packet gets converted/corrupted - [Bug 52868](https://bz.apache.org/bugzilla/show_bug.cgi?id=52868) - BSF language list should be sorted - [Bug 52869](https://bz.apache.org/bugzilla/show_bug.cgi?id=52869) - JSR223 language list currently uses BSF list which is wrong - [Bug 52932](https://bz.apache.org/bugzilla/show_bug.cgi?id=52932) - JDBC Sampler : Sampler is not marked in error in an Exception which is not of class IOException, SQLException, IOException occurs - [Bug 52916](https://bz.apache.org/bugzilla/show_bug.cgi?id=52916) - JDBC Exception if there is an empty user defined variable - [Bug 52937](https://bz.apache.org/bugzilla/show_bug.cgi?id=52937) - Webservice Sampler : Clear Soap Documents Cache at end of Test - [Bug 53027](https://bz.apache.org/bugzilla/show_bug.cgi?id=53027) - JMeter starts throwing exceptions while using SMTP Sample in a test plan with HTTP Cookie Mngr or HTTP Request Defaults - [Bug 53072](https://bz.apache.org/bugzilla/show_bug.cgi?id=53072) - JDBC PREPARED SELECT statements should return results in variables like non prepared SELECT #### Controllers - [Bug 52968](https://bz.apache.org/bugzilla/show_bug.cgi?id=52968) - Option Start Next Loop in Thread Group does not mark parent Transaction Sampler in error when an error occurs - [Bug 50898](https://bz.apache.org/bugzilla/show_bug.cgi?id=50898) - IncludeController : NullPointerException loading script in non-GUI mode if Includers use same element name #### Listeners - [Bug 43450](https://bz.apache.org/bugzilla/show_bug.cgi?id=43450) - Listeners/Savers assume SampleResult count is always 1; fixed Generate Summary Results #### Assertions - [Bug 52848](https://bz.apache.org/bugzilla/show_bug.cgi?id=52848) - NullPointer in "XPath Assertion" #### Functions #### I18N - [Bug 52551](https://bz.apache.org/bugzilla/show_bug.cgi?id=52551) - Function Helper Dialog does not switch language correctly - [Bug 52552](https://bz.apache.org/bugzilla/show_bug.cgi?id=52552) - Help reference only works in English #### General - [Bug 52639](https://bz.apache.org/bugzilla/show_bug.cgi?id=52639) - JSplitPane divider for log panel should be hidden if log is not activated - [Bug 52672](https://bz.apache.org/bugzilla/show_bug.cgi?id=52672) - Change Controller action deletes all but one child samplers - [Bug 52694](https://bz.apache.org/bugzilla/show_bug.cgi?id=52694) - Deadlock in GUI related to non AWT Threads updating GUI - [Bug 52678](https://bz.apache.org/bugzilla/show_bug.cgi?id=52678) - Proxy : When doing replacement of UserDefinedVariables, partial values should not be substituted - [Bug 52728](https://bz.apache.org/bugzilla/show_bug.cgi?id=52728) - CSV Data Set Config element cannot coexist with BSF Sampler in same Thread Plan - [Bug 52762](https://bz.apache.org/bugzilla/show_bug.cgi?id=52762) - Problem with multiples certificates: first index not used until indexes are restarted - [Bug 52741](https://bz.apache.org/bugzilla/show_bug.cgi?id=52741) - TestBeanGUI default values do not work at second time or later - [Bug 52783](https://bz.apache.org/bugzilla/show_bug.cgi?id=52783) - oro.patterncache.size property never used due to early init - [Bug 52789](https://bz.apache.org/bugzilla/show_bug.cgi?id=52789) - Proxy with Regexp Matching can fail with NullPointerException in Value Replacement if value is null - [Bug 52645](https://bz.apache.org/bugzilla/show_bug.cgi?id=52645) - Recording with Proxy leads to OutOfMemory - [Bug 52679](https://bz.apache.org/bugzilla/show_bug.cgi?id=52679) - User Parameters columns narrow - [Bug 52843](https://bz.apache.org/bugzilla/show_bug.cgi?id=52843) - Sample headerSize and bodySize not being accumulated for subsamples - [Bug 52967](https://bz.apache.org/bugzilla/show_bug.cgi?id=52967) - The function __P() couldn't use default value when running with remote server in GUI mode. - [Bug 50799](https://bz.apache.org/bugzilla/show_bug.cgi?id=50799) - Having a non-HTTP sampler in a http test plan prevents multiple header managers from working - [Bug 52997](https://bz.apache.org/bugzilla/show_bug.cgi?id=52997) - JMeter should not exit without saving Test Plan if saving before exit fails - [Bug 53136](https://bz.apache.org/bugzilla/show_bug.cgi?id=53136) - Catching Throwable needs to be carefully handled ### Improvements #### HTTP Samplers #### Other samplers - [Bug 52775](https://bz.apache.org/bugzilla/show_bug.cgi?id=52775) - JMS Publisher : Add Non Persistent Delivery option - [Bug 52810](https://bz.apache.org/bugzilla/show_bug.cgi?id=52810) - Enable setting JMS Properties through JMS Publisher sampler - [Bug 52938](https://bz.apache.org/bugzilla/show_bug.cgi?id=52938) - Webservice Sampler : Add a jmeter property soap.document_cache to control size of Document Cache - [Bug 52939](https://bz.apache.org/bugzilla/show_bug.cgi?id=52939) - Webservice Sampler : Make MaintainSession configurable - [Bug 53073](https://bz.apache.org/bugzilla/show_bug.cgi?id=53073) - Allow to assign the OUT result of a JDBC CALLABLE to JMeter variables - [Bug 53164](https://bz.apache.org/bugzilla/show_bug.cgi?id=53164) - New System Sampler - [Bug 53172](https://bz.apache.org/bugzilla/show_bug.cgi?id=53172) - OS Process Sampler - allow specification of Environment Variables - [Bug 52936](https://bz.apache.org/bugzilla/show_bug.cgi?id=52936) - JMS Publisher : Support sending of JMS Object Messages #### Controllers #### Listeners - [Bug 52603](https://bz.apache.org/bugzilla/show_bug.cgi?id=52603) - MailerVisualizer : Enable SSL , TLS and Authentication - [Bug 52698](https://bz.apache.org/bugzilla/show_bug.cgi?id=52698) - Remove Graph Full Results Listener - [Bug 53070](https://bz.apache.org/bugzilla/show_bug.cgi?id=53070) - Change Aggregate graph to Clustered Bar chart, add more columns (median, 90% line, min, max) and options, fixed some bugs - [Bug 53246](https://bz.apache.org/bugzilla/show_bug.cgi?id=53246) - Mailer Visualizer: improve GUI design and I18N #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N - Mailer Visualizer has been internationalized. French translation added. (see [Bug 53246](https://bz.apache.org/bugzilla/show_bug.cgi?id=53246)) #### General - [Bug 45839](https://bz.apache.org/bugzilla/show_bug.cgi?id=45839) - Test Action : Allow premature exit from a loop - [Bug 52614](https://bz.apache.org/bugzilla/show_bug.cgi?id=52614) - MailerModel.sendMail has strange way to calculate debug setting - [Bug 52782](https://bz.apache.org/bugzilla/show_bug.cgi?id=52782) - Add a detail button on parameters table to show detail of a Row - [Bug 52674](https://bz.apache.org/bugzilla/show_bug.cgi?id=52674) - Proxy : Add a Sampler Creator to allow plugging HTTP based samplers using potentially non textual POST Body (AMF, Silverlight, …) and customizing them for others - [Bug 52934](https://bz.apache.org/bugzilla/show_bug.cgi?id=52934) - GUI : Open Test plan with the tree expanded to the testplan level and no further and select the root of the tree - [Bug 52941](https://bz.apache.org/bugzilla/show_bug.cgi?id=52941) - Improvements of HTML report design generated by JMeter Ant task extra - [Bug 53042](https://bz.apache.org/bugzilla/show_bug.cgi?id=53042) - Introduce a new method in Sampler interface to allow Sampler to decide whether a config element applies to Sampler - [Bug 52771](https://bz.apache.org/bugzilla/show_bug.cgi?id=52771) - Documentation : Added RSS feed on JMeter Home page under link "Subscribe to What's New" - [Bug 42784](https://bz.apache.org/bugzilla/show_bug.cgi?id=42784) - Show the number of errors logged in the GUI - [Bug 53256](https://bz.apache.org/bugzilla/show_bug.cgi?id=53256) - Make Clear All command clean LogViewer content - [Bug 53261](https://bz.apache.org/bugzilla/show_bug.cgi?id=53261) - Make "Error/fatal" counter added in [Bug 42784](https://bz.apache.org/bugzilla/show_bug.cgi?id=42784) open Log Viewer panel when Warn Indicator is clicked ### Non-functional changes - Upgraded to rhino 1.7R3 (was js-1.7R2.jar). Note: the Maven coordinates for the jar were changed from rhino:js to org.mozilla:rhino. This does not affect JMeter directly, but might cause problems if using JMeter in a Maven project with other code that depends on an earlier version of the Rhino Javascript jar. - [Bug 52675](https://bz.apache.org/bugzilla/show_bug.cgi?id=52675) - Refactor Proxy and HttpRequestHdr to allow Sampler Creation by Proxy - [Bug 52680](https://bz.apache.org/bugzilla/show_bug.cgi?id=52680) - Mention version in which function was introduced - [Bug 52788](https://bz.apache.org/bugzilla/show_bug.cgi?id=52788) - HttpRequestHdr : Optimize code to avoid useless work - JMeter Ant (ant-jmeter-1.1.1.jar) task was upgraded from 1.0.9 to 1.1.1 - Updated to commons-io 2.2 (from 2.1) - [Bug 53129](https://bz.apache.org/bugzilla/show_bug.cgi?id=53129) - Upgrade XStream from 1.3.1 to 1.4.2 - Updated to httpcomponents-client 4.1.3 (from 4.1.2) - Updated JMeter distributed testing guide (jmeter_distributed_testing_step_by_step.pdf). Changes source format to OpenOffice odt (from sxw) ## Version 2.6 ### New and Noteworthy #### Toolbar A new toolbar on JMeter's main window ![changes/2.6/01_toolbar.png](/images/screenshots/changes/2.6/01_toolbar.png) #### JMeter start test button A new menu option and button allow to start a test ignoring the Pause Timers ![changes/2.6/02_ignore_pause_timers.png](/images/screenshots/changes/2.6/02_ignore_pause_timers.png) #### JMeter GUI Look and Feel Allow System or CrossPlatform LAF to be set from options menu ![changes/2.6/03_look_and_feel.png](/images/screenshots/changes/2.6/03_look_and_feel.png) #### JMeter GUI - duplicate node Add "duplicate node" in context menu ![changes/2.6/04_duplicate_context_menu.png](/images/screenshots/changes/2.6/04_duplicate_context_menu.png) #### JMeter tree view - search facility Functionality to search by keyword in Samplers Tree View ![changes/2.6/05_search_tree.png](/images/screenshots/changes/2.6/05_search_tree.png) #### HTTP Request - raw request pane Improve HTTP Request GUI to better show parameters without name (GWT RPC request or SOAP request for example) ![changes/2.6/06_post_data.png](/images/screenshots/changes/2.6/06_post_data.png) #### HTTP Request - other changes - Allow multiple selection in arguments panel - Allow to add (paste) entries from the clipboard to an arguments list - Ability to move variables up or down in HTTP Request ![changes/2.6/07_multiple_selection_params.png](/images/screenshots/changes/2.6/07_multiple_selection_params.png) #### HTTP Request - file protocol Better support for file: protocol in HTTP sampler ![changes/2.6/08_file_protocol.png](/images/screenshots/changes/2.6/08_file_protocol.png) Retrieve embedded resources with file: protocol ![changes/2.6/09_file_protocol_embedded.png](/images/screenshots/changes/2.6/09_file_protocol_embedded.png) #### HTTP Request - Ignore embedded resources failed Enable "ignore failed" for embedded resources ![changes/2.6/26_ignore_child_failed.png](/images/screenshots/changes/2.6/26_ignore_child_failed.png) Parent success with a embedded resource failed ![changes/2.6/27_succes_with_child_failed.png](/images/screenshots/changes/2.6/27_succes_with_child_failed.png) #### View Results in Table - child sample display Add option to TableVisualiser to display child samples instead of parent ![changes/2.6/10_child_sampler.png](/images/screenshots/changes/2.6/10_child_sampler.png) #### Key Store - multiple certificates Allowing multiple certificates (JKS) ![changes/2.6/11_jks_keystore.png](/images/screenshots/changes/2.6/11_jks_keystore.png) #### Aggregate graph improvements Some improvements on Aggregate Graph Listener: - new GUI for settings - dynamic graph size - allow to change fonts for title graph and legend - allow to change bar color (background and text values) - allow to draw or not bars outlines - allow to select only some samplers by a regexp filter - allow to define Y axis maximum scale ![changes/2.6/12_aggregate_graph_settings.png](/images/screenshots/changes/2.6/12_aggregate_graph_settings.png) Aggregate Graph bar ![changes/2.6/13_aggregate_graph_bar.png](/images/screenshots/changes/2.6/13_aggregate_graph_bar.png) #### Counter - new reset option Add an option to reset counter on each Thread Group iteration ![changes/2.6/14_reset_counter.png](/images/screenshots/changes/2.6/14_reset_counter.png) #### Functions - Add a new function __RandomString to generate random Strings - Add a new function __TestPlanName returning the name of the current "Test Plan" - Add a new function __machineIP returning IP address - Add a new function __jexl2 to support Jexl2 ![changes/2.6/15_random_string.png](/images/screenshots/changes/2.6/15_random_string.png) #### User Defined Variable improvements - Add a comment field in User Defined Variables - Allow to add (paste) entries from the clipboard to an arguments list - Ability to move up or down variables in User Defined Variables ![changes/2.6/16_udv_comments.png](/images/screenshots/changes/2.6/16_udv_comments.png) #### View Results Tree In View Results Tree rather than showing just a message if the results are to big, show as much of the result as are configured ![changes/2.6/17_vrt_max_size_display.png](/images/screenshots/changes/2.6/17_vrt_max_size_display.png) #### Controllers - change elements Add ability to Change Controller elements ![changes/2.6/18_change_ctl_type.png](/images/screenshots/changes/2.6/18_change_ctl_type.png) #### JDBC pre- and post-processor Add JDBC pre- and post-processor ![changes/2.6/19_jdbc_pre_post_proc.png](/images/screenshots/changes/2.6/19_jdbc_pre_post_proc.png) #### JDBC transaction isolation option Allow to set the transaction isolation in the JDBC Connection Configuration ![changes/2.6/20_jdbc_trans_isolation.png](/images/screenshots/changes/2.6/20_jdbc_trans_isolation.png) #### Poisson Timer Add a Poisson based timer ![changes/2.6/21_poisson_timer.png](/images/screenshots/changes/2.6/21_poisson_timer.png) #### GUI and OS interaction Support for file Drag and Drop. ![changes/2.6/22_drag_and_drop.png](/images/screenshots/changes/2.6/22_drag_and_drop.png) #### Confirm Remove Dialog box Add a dialog box to confirm removing the element(s) when Remove action is called ![changes/2.6/23_confirm_remove.png](/images/screenshots/changes/2.6/23_confirm_remove.png) The dialogue can be skipped by setting the JMeter property `confirm.delete.skip=true` #### Remote batching support Use external store to hold samples during distributed testing, Added DiskStore remote sample sender: like Hold, but saves samples to disk until end of test ![changes/2.6/24_diskstore.png](/images/screenshots/changes/2.6/24_diskstore.png) #### JMS Subscriber sampler With JMS Subscriber, ability to use Selectors ![changes/2.6/25_selector.png](/images/screenshots/changes/2.6/25_selector.png) #### New Logger Panel A new Log Viewer has been added to the GUI and can be enabled from menu Options → Log Viewer: ![changes/2.6/28_loggerpanel_option.png](/images/screenshots/changes/2.6/28_loggerpanel_option.png) This Log Viewer shows the jmeter.log file, and useful (for example) to debug BeanShell/BSF scripts: ![changes/2.6/28_loggerpanel.png](/images/screenshots/changes/2.6/28_loggerpanel.png) #### The menu item Options / Choose Language is now fully functional The menu item Options / Choose Language now changes all the displayed text to the new language provided all messages are translated. You can help on this by translating into your language. #### Legacy JMX and JTL Avalon format support restored Support for reading/writing the original Avalon XML format of JMX (script) and JTL (sample result) files was dropped in JMeter version 2.4. JMeter can now read the Avalon format files again, however there is no support for saving files in the old format. #### JMeter jars available from Maven repository JMeter jars are now available from Maven repository. ### Known bugs The Include Controller has some problems in non-GUI mode (see Bugs 40671, 41286, 44973, 50898). In particular, it can cause a NullPointerException if there are two include controllers with the same name. The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). ### Incompatible changes JMeter versions since 2.1 failed to create a container sample when loading embedded resources. This has been corrected; can still revert to the [Bug 51939](https://bz.apache.org/bugzilla/show_bug.cgi?id=51939) behaviour by setting the following property: `httpsampler.separate.container=false` Mirror server now uses default port 8081, was 8080 before 2.5.1. TCP Sampler handles SocketTimeoutException, SocketException and InterruptedIOException differently since 2.6, when these occurs, Sampler is marked as failed. Sample Sender implementations now resolve their configuration on Client side since 2.6. This behaviour can be changed with property sample_sender_client_configured (set it to false). The HTTP User Parameter Modifier test element has been removed; it has been deprecated for a long time. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 51932](https://bz.apache.org/bugzilla/show_bug.cgi?id=51932) - CacheManager does not handle cache-control header with any attributes after max-age - [Bug 51918](https://bz.apache.org/bugzilla/show_bug.cgi?id=51918) - GZIP compressed traffic produces errors, when multiple connections allowed - [Bug 51939](https://bz.apache.org/bugzilla/show_bug.cgi?id=51939) - Should generate new parent sample if necessary when retrieving embedded resources - [Bug 51942](https://bz.apache.org/bugzilla/show_bug.cgi?id=51942) - Synchronisation issue on CacheManager when Concurrent Download is used - [Bug 51957](https://bz.apache.org/bugzilla/show_bug.cgi?id=51957) - Concurrent get can hang if a task does not complete - [Bug 51925](https://bz.apache.org/bugzilla/show_bug.cgi?id=51925) - Calling Stop on Test leaks executor threads when concurrent download of resources is on - [Bug 51980](https://bz.apache.org/bugzilla/show_bug.cgi?id=51980) - HtmlParserHTMLParser double-counts images used in links - [Bug 52064](https://bz.apache.org/bugzilla/show_bug.cgi?id=52064) - OutOfMemory Risk in CacheManager - [Bug 51919](https://bz.apache.org/bugzilla/show_bug.cgi?id=51919) - Random ConcurrentModificationException or NoSuchElementException in CookieManager#removeMatchingCookies when using Concurrent Download - [Bug 52126](https://bz.apache.org/bugzilla/show_bug.cgi?id=52126) - HttpClient4 does not clear cookies between iterations - [Bug 52129](https://bz.apache.org/bugzilla/show_bug.cgi?id=52129) - Reported Body Size is wrong when using HTTP Client 4 and Keep Alive connection - [Bug 52137](https://bz.apache.org/bugzilla/show_bug.cgi?id=52137) - Problems with HTTP Cache Manager - [Bug 52221](https://bz.apache.org/bugzilla/show_bug.cgi?id=52221) - Nullpointer Exception with use Retrieve Embedded Resource without HTTP Cache Manager - [Bug 52310](https://bz.apache.org/bugzilla/show_bug.cgi?id=52310) - variable in IPSource failed HTTP request if "Concurrent Pool Size" is enabled - [Bug 52371](https://bz.apache.org/bugzilla/show_bug.cgi?id=52371) - API Incompatibility - Methods in HTTPSampler2 now require PostMethod instead of HttpMethod[Base]. Reverted to original types. - [Bug 49950](https://bz.apache.org/bugzilla/show_bug.cgi?id=49950) - Proxy : IndexOutOfBoundsException when recording with Proxy server - [Bug 52409](https://bz.apache.org/bugzilla/show_bug.cgi?id=52409) - HttpSamplerBase#errorResult modifies sampleResult passed as parameter; fix code which assumes that a new instance is created (i.e. when adding a sub-sample) - [Bug 52507](https://bz.apache.org/bugzilla/show_bug.cgi?id=52507) - Delete Http User Parameters modifier (deprecated, obsolete) #### Other Samplers - [Bug 51996](https://bz.apache.org/bugzilla/show_bug.cgi?id=51996) - JMS Initial Context leak newly created Context when Multiple Thread enter InitialContextFactory#lookupContext at the same time - [Bug 51691](https://bz.apache.org/bugzilla/show_bug.cgi?id=51691) - Authorization does not work for JMS Publisher and JMS Subscriber - [Bug 52036](https://bz.apache.org/bugzilla/show_bug.cgi?id=52036) - Durable Subscription fails with ActiveMQ due to missing clientId field - [Bug 52044](https://bz.apache.org/bugzilla/show_bug.cgi?id=52044) - JMS Subscriber used with many threads leads to javax.naming.NamingException: Something already bound with ActiveMQ - [Bug 52072](https://bz.apache.org/bugzilla/show_bug.cgi?id=52072) - LengthPrefixedBinaryTcpClientImpl may end a sample prematurely - [Bug 52390](https://bz.apache.org/bugzilla/show_bug.cgi?id=52390) - AbstractJDBCTestElement:Memory leak and synchronization issue in perConnCache #### Controllers - [Bug 51865](https://bz.apache.org/bugzilla/show_bug.cgi?id=51865) - Infinite loop inside thread group does not work properly if "Start next loop after a Sample error" option set - [Bug 51868](https://bz.apache.org/bugzilla/show_bug.cgi?id=51868) - A lot of exceptions in jmeter.log while using option "Start next loop" for thread - [Bug 51866](https://bz.apache.org/bugzilla/show_bug.cgi?id=51866) - Counter under loop doesn't work properly if "Start next loop on error" option set for thread group - [Bug 52296](https://bz.apache.org/bugzilla/show_bug.cgi?id=52296) - TransactionController + Children ThrouputController or InterleaveController leads to ERROR sampleEnd called twice java.lang.Throwable: Invalid call sequence when TPC does not run sample - [Bug 52330](https://bz.apache.org/bugzilla/show_bug.cgi?id=52330) - With next-Loop-On-Error after error samples are not executed in next loop #### Listeners - [Bug 52357](https://bz.apache.org/bugzilla/show_bug.cgi?id=52357) - View results in Table does not allow for multiple result samples - [Bug 52491](https://bz.apache.org/bugzilla/show_bug.cgi?id=52491) - Incorrect parsing of Post data parameters in Tree Listener / Http Request view #### Assertions - [Bug 52519](https://bz.apache.org/bugzilla/show_bug.cgi?id=52519) - XMLSchemaAssertion uses JMeter JVM file.encoding instead of response encoding #### Functions - The CRLF example for the char function was wrong; CRLF=(0xD,0xA), not (0xC,0xA) #### I18N #### General - [Bug 51937](https://bz.apache.org/bugzilla/show_bug.cgi?id=51937) - JMeter does not handle missing TestPlan entry well - [Bug 51988](https://bz.apache.org/bugzilla/show_bug.cgi?id=51988) - CSV Data Set Configuration does not resolve default delimiter for header parsing when variables field is empty - [Bug 52003](https://bz.apache.org/bugzilla/show_bug.cgi?id=52003) - View Results Tree "Scroll automatically" does not scroll properly in case nodes are expanded - [Bug 27112](https://bz.apache.org/bugzilla/show_bug.cgi?id=27112) - User Parameters should use scrollbars - [Bug 52029](https://bz.apache.org/bugzilla/show_bug.cgi?id=52029) - Command-line shutdown only gets sent to last engine that was started - [Bug 52093](https://bz.apache.org/bugzilla/show_bug.cgi?id=52093) - Toolbar ToolTips don't switch language - [Bug 51733](https://bz.apache.org/bugzilla/show_bug.cgi?id=51733) - SyncTimer is messed up if you a interrupt a test plan - [Bug 52118](https://bz.apache.org/bugzilla/show_bug.cgi?id=52118) - New toolbar : shutdown and stop buttons not disabled when no test is running - [Bug 52125](https://bz.apache.org/bugzilla/show_bug.cgi?id=52125) - StatCalculator.addAll(StatCalculator calc) joins incorrect if there are more samples with the same response time in one of the TreeMap - [Bug 52339](https://bz.apache.org/bugzilla/show_bug.cgi?id=52339) - JMeter Statistical mode in distributed testing shows wrong response time - [Bug 52215](https://bz.apache.org/bugzilla/show_bug.cgi?id=52215) - Confusing synchronization in StatVisualizer, SummaryReport ,Summariser and issue in StatGraphVisualizer - [Bug 52216](https://bz.apache.org/bugzilla/show_bug.cgi?id=52216) - TableVisualizer : currentData field is badly synchronized - [Bug 52217](https://bz.apache.org/bugzilla/show_bug.cgi?id=52217) - ViewResultsFullVisualizer : Synchronization issues on root and treeModel - [Bug 43294](https://bz.apache.org/bugzilla/show_bug.cgi?id=43294) - XPath Extractor namespace problems - [Bug 52224](https://bz.apache.org/bugzilla/show_bug.cgi?id=52224) - TestBeanHelper does not support NOT_UNDEFINED == Boolean.FALSE - [Bug 52279](https://bz.apache.org/bugzilla/show_bug.cgi?id=52279) - Switching to another language loses icons in Tree and logs error Can't obtain GUI class from … - [Bug 52280](https://bz.apache.org/bugzilla/show_bug.cgi?id=52280) - The menu item Options / Choose Language does not change all the displayed text to the new language - [Bug 52376](https://bz.apache.org/bugzilla/show_bug.cgi?id=52376) - StatCalculator#addValue(T val, int sampleCount) should use long, not int - [Bug 49374](https://bz.apache.org/bugzilla/show_bug.cgi?id=49374) - Encoding of embedded element URLs depend on the file.encoding property - [Bug 52399](https://bz.apache.org/bugzilla/show_bug.cgi?id=52399) - URLRewritingModifier uses default file.encoding to match text content - [Bug 50438](https://bz.apache.org/bugzilla/show_bug.cgi?id=50438) - code calculates average with integer math, expecting double value - [Bug 52469](https://bz.apache.org/bugzilla/show_bug.cgi?id=52469) - Changes in Support of SSH-Tunneling of RMI traffic for Remote Testing - [Bug 52466](https://bz.apache.org/bugzilla/show_bug.cgi?id=52466) - Upgrade Test Plan feature : NameUpdater does not upgrade properties - [Bug 52503](https://bz.apache.org/bugzilla/show_bug.cgi?id=52503) - Unify File→Close and Window close file saving behaviour - [Bug 52537](https://bz.apache.org/bugzilla/show_bug.cgi?id=52537) - Help does not scroll to correct anchor when file is first loaded ### Improvements #### HTTP Samplers - [Bug 51981](https://bz.apache.org/bugzilla/show_bug.cgi?id=51981) - Better support for file: protocol in HTTP sampler - [Bug 52033](https://bz.apache.org/bugzilla/show_bug.cgi?id=52033) - Allowing multiple certificates (JKS) - [Bug 52352](https://bz.apache.org/bugzilla/show_bug.cgi?id=52352) - Proxy : Support IPv6 URLs capture - [Bug 44301](https://bz.apache.org/bugzilla/show_bug.cgi?id=44301) - Enable "ignore failed" for embedded resources #### Other samplers - [Bug 51419](https://bz.apache.org/bugzilla/show_bug.cgi?id=51419) - JMS Subscriber: ability to use Selectors - [Bug 52088](https://bz.apache.org/bugzilla/show_bug.cgi?id=52088) - JMS Sampler : Add a selector when REQUEST / RESPONSE is chosen - [Bug 52104](https://bz.apache.org/bugzilla/show_bug.cgi?id=52104) - TCP Sampler handles badly errors - [Bug 52087](https://bz.apache.org/bugzilla/show_bug.cgi?id=52087) - TCPClient interface does not allow for partial reads - [Bug 52115](https://bz.apache.org/bugzilla/show_bug.cgi?id=52115) - SOAP/XML-RPC should not send a POST request when file to send is not found - [Bug 40750](https://bz.apache.org/bugzilla/show_bug.cgi?id=40750) - TCPSampler : Behaviour when sockets are closed by remote host - [Bug 52396](https://bz.apache.org/bugzilla/show_bug.cgi?id=52396) - TCP Sampler in "reuse connection mode" reuses previous sampler's connection even if it's configured with other host, port, user or password - [Bug 52048](https://bz.apache.org/bugzilla/show_bug.cgi?id=52048) - BSFSampler, BSFPreProcessor and BSFPostProcessor should share the same GUI #### Controllers #### Listeners - [Bug 52022](https://bz.apache.org/bugzilla/show_bug.cgi?id=52022) - In View Results Tree rather than showing just a message if the results are to big, show as much of the result as are configured - [Bug 52201](https://bz.apache.org/bugzilla/show_bug.cgi?id=52201) - Add option to TableVisualiser to display child samples instead of parent - [Bug 52214](https://bz.apache.org/bugzilla/show_bug.cgi?id=52214) - Save Responses to a file - improve naming algorithm - [Bug 52340](https://bz.apache.org/bugzilla/show_bug.cgi?id=52340) - Allow remote sampling mode to be changed at run-time - [Bug 52452](https://bz.apache.org/bugzilla/show_bug.cgi?id=52452) - Improvements on Aggregate Graph Listener (GUI and settings) - Resurrected OldSaveService to allow reading Avalon format JTL (result) files #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 52128](https://bz.apache.org/bugzilla/show_bug.cgi?id=52128) - Add JDBC pre- and post-processor - [Bug 52183](https://bz.apache.org/bugzilla/show_bug.cgi?id=52183) - SyncTimer could be improved (performance+reliability) - [Bug 52317](https://bz.apache.org/bugzilla/show_bug.cgi?id=52317) - Counter : Add option to reset counter on each Thread Group iteration - [Bug 37073](https://bz.apache.org/bugzilla/show_bug.cgi?id=37073) - Add a Poisson based timer - [Bug 52497](https://bz.apache.org/bugzilla/show_bug.cgi?id=52497) - Improve DebugSampler and DebugPostProcessor #### Functions - [Bug 52006](https://bz.apache.org/bugzilla/show_bug.cgi?id=52006) - Create a function RandomString to generate random Strings - [Bug 52016](https://bz.apache.org/bugzilla/show_bug.cgi?id=52016) - It would be useful to support Jexl2 - __char() function now supports octal values - New function __machineIP returning IP address - [Bug 51091](https://bz.apache.org/bugzilla/show_bug.cgi?id=51091) - New function returning the name of the current "Test Plan" #### I18N #### General - [Bug 51892](https://bz.apache.org/bugzilla/show_bug.cgi?id=51892) - Default mirror port should be different from default proxy port - [Bug 51817](https://bz.apache.org/bugzilla/show_bug.cgi?id=51817) - Moving variables up and down in User Defined Variables control - [Bug 51876](https://bz.apache.org/bugzilla/show_bug.cgi?id=51876) - Functionality to search in Samplers TreeView - [Bug 52019](https://bz.apache.org/bugzilla/show_bug.cgi?id=52019) - Add menu option to Start a test ignoring Pause Timers - [Bug 52027](https://bz.apache.org/bugzilla/show_bug.cgi?id=52027) - Allow System or CrossPlatform LAF to be set from options menu - [Bug 52037](https://bz.apache.org/bugzilla/show_bug.cgi?id=52037) - Remember user-set LaF over restarts. - [Bug 51861](https://bz.apache.org/bugzilla/show_bug.cgi?id=51861) - Improve HTTP Request GUI to better show parameters without name (GWT RPC requests for example) (UNDER DEVELOPMENT) - [Bug 52040](https://bz.apache.org/bugzilla/show_bug.cgi?id=52040) - Add a toolbar in JMeter main window - [Bug 51816](https://bz.apache.org/bugzilla/show_bug.cgi?id=51816) - Comment Field in User Defined Variables control. - [Bug 52052](https://bz.apache.org/bugzilla/show_bug.cgi?id=52052) - Using a delimiter to separate result-messages for JMS Subscriber - [Bug 52103](https://bz.apache.org/bugzilla/show_bug.cgi?id=52103) - Add automatic scrolling option to table visualizer - [Bug 52097](https://bz.apache.org/bugzilla/show_bug.cgi?id=52097) - Save As should point to same folder that was used to open a file if MRU list is used - [Bug 52085](https://bz.apache.org/bugzilla/show_bug.cgi?id=52085) - Allow multiple selection in arguments panel - [Bug 52099](https://bz.apache.org/bugzilla/show_bug.cgi?id=52099) - Allow to set the transaction isolation in the JDBC Connection Configuration - [Bug 52116](https://bz.apache.org/bugzilla/show_bug.cgi?id=52116) - Allow to add (paste) entries from the clipboard to an arguments list - [Bug 52160](https://bz.apache.org/bugzilla/show_bug.cgi?id=52160) - Don't display TestBeanGui items which are flagged as hidden - [Bug 51886](https://bz.apache.org/bugzilla/show_bug.cgi?id=51886) - SampleSender configuration resolved partly on client and partly on server - [Bug 52161](https://bz.apache.org/bugzilla/show_bug.cgi?id=52161) - Enable plugins to add own translation rules in addition to upgrade.properties. Loads any additional properties found in META-INF/resources/org.apache.jmeter.nameupdater.properties files - [Bug 42538](https://bz.apache.org/bugzilla/show_bug.cgi?id=42538) - Add "duplicate node" in context menu - [Bug 46921](https://bz.apache.org/bugzilla/show_bug.cgi?id=46921) - Add Ability to Change Controller elements - [Bug 52240](https://bz.apache.org/bugzilla/show_bug.cgi?id=52240) - TestBeans should support Boolean, Integer and Long - [Bug 52241](https://bz.apache.org/bugzilla/show_bug.cgi?id=52241) - GenericTestBeanCustomizer assumes that the default value is the empty string - [Bug 52242](https://bz.apache.org/bugzilla/show_bug.cgi?id=52242) - FileEditor does not allow output to be saved in a File - [Bug 51093](https://bz.apache.org/bugzilla/show_bug.cgi?id=51093) - when loading a selection previously stored by "Save Selection As", show the file name in the blue window bar - [Bug 50086](https://bz.apache.org/bugzilla/show_bug.cgi?id=50086) - Password fields not Hidden in JMS Publisher, JMS Subscriber, Mail Reader sampler, SMTP sampler and Database Configuration - [Bug 29352](https://bz.apache.org/bugzilla/show_bug.cgi?id=29352) - Use external store to hold samples during distributed testing, Added DiskStore remote sample sender: like Hold, but saves samples to disk until end of test. - [Bug 52333](https://bz.apache.org/bugzilla/show_bug.cgi?id=52333) - Reduce overhead in calculating SampleResult#nanoTimeOffset - [Bug 52346](https://bz.apache.org/bugzilla/show_bug.cgi?id=52346) - Shutdown detects if there are any non-daemon threads left which prevent JVM exit. - [Bug 52281](https://bz.apache.org/bugzilla/show_bug.cgi?id=52281) - Support for file Drag and Drop - [Bug 52471](https://bz.apache.org/bugzilla/show_bug.cgi?id=52471) - Improve Mirror Server performance by Using Pool of threads instead of launching a Thread for each request - Resurrected OldSaveService to allow reading Avalon format JMX files (removed in 2.4) - Add a dialog box to confirm removing the element(s) when Remove action is called - [Bug 41788](https://bz.apache.org/bugzilla/show_bug.cgi?id=41788) - Log viewer (console window) needed as an option - Add option to change the pause time (default 2000ms) in the daemon thread which checks for successful JVM exit. The thread is not now started unless the pause time is greater than 0. ### Non-functional changes - fixes to build.xml: support scripts; localise re-usable property names - [Bug 51923](https://bz.apache.org/bugzilla/show_bug.cgi?id=51923) - Counter function bug or documentation issue ? (fixed docs) - Update velocity.jar to 1.7 (from 1.6.2) - Update js.jar to 1.7R3 (from 1.6R5) - Update commons-codec 1.5 ⇒ 1.6 - Update commons-io 2.0.1 ⇒ 2.1 - Update commons-jexl 2.0.1 ⇒ 2.1.1 - Update jdom 1.1 ⇒ 1.1.2 - Update junit 4.9 ⇒ 4.10 - [Bug 51954](https://bz.apache.org/bugzilla/show_bug.cgi?id=51954) - Generated documents include </br> entries which cause extra blank lines - [Bug 52075](https://bz.apache.org/bugzilla/show_bug.cgi?id=52075) - JMeterProperty.clone() currently returns Object; it should return JMeterProperty - Updated httpcore to 4.1.4 - [Bug 49753](https://bz.apache.org/bugzilla/show_bug.cgi?id=49753) - Please publish jMeter artifacts on Maven central repository ## Version 2.5.1 ### Summary of main changes - HttpClient4 sampler now re-uses connections properly (previously it would use one per sample, which could quickly cause resource exhaustion). - Various fixes to JMS samplers - Functions are no longer spuriously invoked when used with a Configuration element - WebService sampler GUI has been re-organized for better design and more user-friendliness. Some improvements on WSDL configuration assistant - Better handling of test shutdown. System.exit now only called if there is no other option; even this can be disabled. ### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a NullPointerException if there are two include controllers with the same name. The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The If Controller may cause an infinite loop if the condition is always false from the first iteration. A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). The menu item Options / Choose Language does not change all the displayed text to the new language. [The behaviour has improved, but language change is still not fully working] To override the default local language fully, set the JMeter property "language" before starting JMeter. ### Incompatible changes The HttpClient4 and Commons HttpClient 3.1 samplers previously used a retry count of 3. This has been changed to default to 1, to be compatible with the Java implementation. The retry count can be overridden by setting the relevant JMeter property, for example: ``` httpclient4.retrycount=3 httpclient3.retrycount=3 ``` ### Bug fixes #### HTTP Samplers and Proxy - Fix HttpClient 4 sampler so it reuses HttpClient instances and connections where possible. - Temporary fix to HC4 sampler to work round HTTPCLIENT-1120. - [Bug 51863](https://bz.apache.org/bugzilla/show_bug.cgi?id=51863) - Lots of ESTABLISHED connections with HttpClient 4 implementation (vs HttpClient 3.1 impl) - [Bug 51750](https://bz.apache.org/bugzilla/show_bug.cgi?id=51750) - Retrieve all embedded resources doesn't follow IFRAME - [Bug 51752](https://bz.apache.org/bugzilla/show_bug.cgi?id=51752) - HTTP Cache is broken when using "Retrieve all embedded resources" with concurrent pool - [Bug 39219](https://bz.apache.org/bugzilla/show_bug.cgi?id=39219) - HTTP Server: You can't stop it after File→Open - [Bug 51775](https://bz.apache.org/bugzilla/show_bug.cgi?id=51775) - Port number duplicates in Host header when capturing by HttpClient (3.1 and 4.x) - [Bug 50617](https://bz.apache.org/bugzilla/show_bug.cgi?id=50617) - Monitor Results legend show "dead" server although values from the server are retrieved #### Other Samplers - [Bug 50424](https://bz.apache.org/bugzilla/show_bug.cgi?id=50424) - Web Methods drop down list box inconsistent - [Bug 43293](https://bz.apache.org/bugzilla/show_bug.cgi?id=43293) - Java Request fields not cleared when creating new sampler - [Bug 51830](https://bz.apache.org/bugzilla/show_bug.cgi?id=51830) - Webservice Soap Request triggers too many popups when Webservice WSDL URL is down - WebService(SOAP) request - add a connect timeout to get the wsdl used to populate Web Methods when server doesn't response - [Bug 51841](https://bz.apache.org/bugzilla/show_bug.cgi?id=51841) - JMS : If an error occurs in ReceiveSubscriber constructor or Publisher, then Connections will stay open - [Bug 51691](https://bz.apache.org/bugzilla/show_bug.cgi?id=51691) - Authorization does not work for JMS Publisher and JMS Subscriber - [Bug 51840](https://bz.apache.org/bugzilla/show_bug.cgi?id=51840) - JMS : Cache of InitialContext has some issues - [Bug 47888](https://bz.apache.org/bugzilla/show_bug.cgi?id=47888) - JUnit Sampler re-uses test object #### Controllers - If Controller - Fixed two regressions introduced by [Bug 50032](https://bz.apache.org/bugzilla/show_bug.cgi?id=50032) (see [Bug 50618](https://bz.apache.org/bugzilla/show_bug.cgi?id=50618) too) - If Controller - Catches a StackOverflowError when a condition returns always false (after at least one iteration with return true) See [Bug 50618](https://bz.apache.org/bugzilla/show_bug.cgi?id=50618) - [Bug 51869](https://bz.apache.org/bugzilla/show_bug.cgi?id=51869) - NullPointer Exception when using Include Controller #### Listeners #### Assertions #### Functions - [Bug 48943](https://bz.apache.org/bugzilla/show_bug.cgi?id=48943) - Functions are invoked additional times when used in combination with a Config Element #### I18N - WebService(SOAP) request - add I18N for some labels #### General - [Bug 51831](https://bz.apache.org/bugzilla/show_bug.cgi?id=51831) - Cannot disable UDP server or change the maximum UDP port - [Bug 51821](https://bz.apache.org/bugzilla/show_bug.cgi?id=51821) - Add short-cut for Enabling / Disabling (sub)tree or branches in test plan. - [Bug 47921](https://bz.apache.org/bugzilla/show_bug.cgi?id=47921) - Variables not released for GC after JMeterThread exits. - [Bug 51839](https://bz.apache.org/bugzilla/show_bug.cgi?id=51839) - "… end of run" printed prematurely - [Bug 51847](https://bz.apache.org/bugzilla/show_bug.cgi?id=51847) - Some JUnit tests are Locale sensitive and fail if Locale is different from US - [Bug 51855](https://bz.apache.org/bugzilla/show_bug.cgi?id=51855) - Parent samples may have slightly inaccurate elapsed times - [Bug 51880](https://bz.apache.org/bugzilla/show_bug.cgi?id=51880) - The shutdown command is not working if I invoke it before all the thread are started - Remote Shut host menu item was not being enabled. - [Bug 51888](https://bz.apache.org/bugzilla/show_bug.cgi?id=51888) - Occasional deadlock when stopping a testplan ### Improvements #### HTTP Samplers - [Bug 51380](https://bz.apache.org/bugzilla/show_bug.cgi?id=51380) - Control reuse of cached SSL Context from iteration to iteration - [Bug 51882](https://bz.apache.org/bugzilla/show_bug.cgi?id=51882) - HTTPHC3Client uses a default retry count of 3, make it configurable; default is now 1 - Change the default HttpClient 4 sampler retry count to 1 #### Other samplers - Beanshell Sampler now supports Interruptible interface - [Bug 51605](https://bz.apache.org/bugzilla/show_bug.cgi?id=51605) - WebService(SOAP) Request - WebMethod field value changes surreptitiously for all the requests when a value is selected in a request - WebService(SOAP) Request - Reorganized GUI for better design and more user-friendliness #### Controllers #### Listeners - [Bug 42246](https://bz.apache.org/bugzilla/show_bug.cgi?id=42246) - Need for a 'auto-scroll' option in "View Results Tree" and "Assertion Results" - View Results Tree: Regexp Tester - little improvements on user interface #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 51885](https://bz.apache.org/bugzilla/show_bug.cgi?id=51885) - Allow a JMeter Variable as input to XPathExtractor #### Functions #### I18N #### General - [Bug 51822](https://bz.apache.org/bugzilla/show_bug.cgi?id=51822) - (part 1) save 1 invocation of GuiPackage#getCurrentGui - Added AsynchSampleSender which sends samples from server to client asynchronously. - Upgraded to htmlparser 2.1; JavaMail 1.4.4; JUnit 4.9 ### Non-functional changes - [Bug 49976](https://bz.apache.org/bugzilla/show_bug.cgi?id=49976) - FormCharSetFinder visibility is default instead of public. - [Bug 50917](https://bz.apache.org/bugzilla/show_bug.cgi?id=50917) - Property CookieManager.save.cookies not honored when set from test plan - Improve error logging when Javascript errors are detected. - Updated documentation footer ## Version 2.5 ### Summary of main changes - The HTTP implementation can now be selected at run-time, and JMeter now also supports Apache HttpComponents HttpClient 4.x. Note that Commons HttpClient 3.1 is no longer actively developed, and support may be removed from JMeter in a future release. - The HTTP sampler now allows concurrent downloads of embedded resources in an HTML page - The HTTP Sampler can now report the size of a request before decompression. - The JMS and Mail samplers have been improved. - The new Test Fragment Test Element makes using Include Controllers easier - There are various improvements to the View Results Tree Listener - [Bug 30563](https://bz.apache.org/bugzilla/show_bug.cgi?id=30563) - Thread Group should have a start next loop option on Sample Error - There are two new Thread Group types - setUp and tearDown - which are run before and after the main Thread groups. - Client-Server mode now supports external stop/shutdown via UDP multiple JMeter server instances can be started on the same host without needing to change the port property. - [Bug 50516](https://bz.apache.org/bugzilla/show_bug.cgi?id=50516) - "Host" header in HTTP Header Manager is not included in generated HTTP request ### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a NullPointerException if there are two include controllers with the same name. Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The menu item Options / Choose Language does not change all the displayed text to the new language. [The behaviour has improved, but language change is still not fully working] To override the default local language fully, set the JMeter property "language" before starting JMeter. ### Incompatible changes Unsupported methods are no longer converted to GET by the Commons HttpClient sampler. Removed method public static long currentTimeInMs(). This has been replaced by the instance method public long currentTimeInMillis(). ProxyControl.getSamplerTypeName() now returns a String rather than an int. This is internal to the workings of the JMeter Proxy & its GUI, so should not affect any user code. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 50178](https://bz.apache.org/bugzilla/show_bug.cgi?id=50178) - HeaderManager added as child of Thread Group can create concatenated HeaderManager names and OutOfMemoryException - [Bug 50392](https://bz.apache.org/bugzilla/show_bug.cgi?id=50392) - value is trimmed when sending the request in Multipart - [Bug 50686](https://bz.apache.org/bugzilla/show_bug.cgi?id=50686) - HeaderManager logging too verbose when merging instances - [Bug 50963](https://bz.apache.org/bugzilla/show_bug.cgi?id=50963) - AjpSampler throws java.lang.StringIndexOutOfBoundsException - [Bug 50516](https://bz.apache.org/bugzilla/show_bug.cgi?id=50516) - "Host" header in HTTP Header Manager is not included in generated HTTP request - [Bug 50544](https://bz.apache.org/bugzilla/show_bug.cgi?id=50544) - In Apache Common Log the HEAD requests cause problems. - [Bug 51268](https://bz.apache.org/bugzilla/show_bug.cgi?id=51268) - HTTPS request through an invalid proxy causes NullPointerException and does not show in result tree. Rather than delegating to the JMeter thread handler for "unexpected" failures, ensure all Exceptions generate a sample error. - [Bug 51275](https://bz.apache.org/bugzilla/show_bug.cgi?id=51275) - Cookie Panel clearGui() sets incorrect default policy in Java 1.6 #### Other Samplers - [Bug 50173](https://bz.apache.org/bugzilla/show_bug.cgi?id=50173) - JDBCSampler discards ResultSet from a PreparedStatement - Ensure JSR223 Sampler has access to the current SampleResult - [Bug 50977](https://bz.apache.org/bugzilla/show_bug.cgi?id=50977) - Unable to set TCP Sampler for individual samples #### Controllers - [Bug 50032](https://bz.apache.org/bugzilla/show_bug.cgi?id=50032) - Last_Sample_Ok along with other controllers doesn't work correctly when the threadgroup has multiple loops - [Bug 50080](https://bz.apache.org/bugzilla/show_bug.cgi?id=50080) - Transaction controller incorrectly creates samples including timer duration - [Bug 50134](https://bz.apache.org/bugzilla/show_bug.cgi?id=50134) - TransactionController : Reports bad response time when it contains other TransactionControllers #### Listeners - [Bug 50367](https://bz.apache.org/bugzilla/show_bug.cgi?id=50367) - Clear / Clear all in View results tree does not clear selected element #### Assertions - [Bug 51488](https://bz.apache.org/bugzilla/show_bug.cgi?id=51488) - Assertion: Variable name scope is shared among all assertions (and [Bug 51255](https://bz.apache.org/bugzilla/show_bug.cgi?id=51255)) #### Functions - [Bug 50568](https://bz.apache.org/bugzilla/show_bug.cgi?id=50568) - Function __FileToString(): Could not read file when encoding option is blank/empty #### I18N - [Bug 50811](https://bz.apache.org/bugzilla/show_bug.cgi?id=50811) - Incomplete Spanish translation #### General - [Bug 49734](https://bz.apache.org/bugzilla/show_bug.cgi?id=49734) - Null pointer exception on stop Threads command (Run → Stop) - [Bug 49666](https://bz.apache.org/bugzilla/show_bug.cgi?id=49666) - CSV Header read as data after EOF - [Bug 45703](https://bz.apache.org/bugzilla/show_bug.cgi?id=45703) - Synchronizing Timer - [Bug 50088](https://bz.apache.org/bugzilla/show_bug.cgi?id=50088) - fix getAvgPageBytes in SamplingStatCalculator so it returns what it should - [Bug 50203](https://bz.apache.org/bugzilla/show_bug.cgi?id=50203) Cannot set property "jmeter.save.saveservice.default_delimiter=\t" - mirror-server.sh - fix classpath to use : separator (not ;) - [Bug 50286](https://bz.apache.org/bugzilla/show_bug.cgi?id=50286) - URL Re-writing Modifier: extracted jsessionid value is incorrect when is between XML tags - System.nanoTime() tends to drift relative to System.currentTimeMillis(). Change SampleResult to recalculate offset each time. Also enable reversion to using System.currentTimeMillis() only. - [Bug 50425](https://bz.apache.org/bugzilla/show_bug.cgi?id=50425) - Remove thread groups from Controller add menu - [Bug 50675](https://bz.apache.org/bugzilla/show_bug.cgi?id=50675) - CVS Data Set Config incompatible with Remote Start Fixed RMI startup to provide location of JMX file relative to user.dir. - [Bug 50221](https://bz.apache.org/bugzilla/show_bug.cgi?id=50221) - Renaming elements in the tree does not resize label - [Bug 51002](https://bz.apache.org/bugzilla/show_bug.cgi?id=51002) - Stop Thread if CSV file is not available. JMeter now treats IOError as EOF. - Define sun.net.http.allowRestrictedHeaders=true by default. This fixes [Bug 51238](https://bz.apache.org/bugzilla/show_bug.cgi?id=51238). - [Bug 51645](https://bz.apache.org/bugzilla/show_bug.cgi?id=51645) - CSVDataSet does not read UTF-8 files when file.encoding is UTF-8 ### Improvements #### HTTP Samplers - AJP Sampler now implements Interruptible - Allow HTTP implementation to be selected at run-time - [Bug 50684](https://bz.apache.org/bugzilla/show_bug.cgi?id=50684) - Optionally disable Content-Type and Transfer-Encoding in Multipart POST - [Bug 50943](https://bz.apache.org/bugzilla/show_bug.cgi?id=50943) - Allowing concurrent downloads of embedded resources in html page - [Bug 50170](https://bz.apache.org/bugzilla/show_bug.cgi?id=50170) - Bytes reported by http sampler is after GUnZip Add optional properties to allow change the method to get response size - Hiding the proxy password on HTTP Sampler (just on GUI, not in JMX file) #### Other samplers - [Bug 49622](https://bz.apache.org/bugzilla/show_bug.cgi?id=49622) - Allow sending messages without a subject (SMTP Sampler) - [Bug 49603](https://bz.apache.org/bugzilla/show_bug.cgi?id=49603) - Allow accepting expired certificates on Mail Reader Sampler - [Bug 49775](https://bz.apache.org/bugzilla/show_bug.cgi?id=49775) - Allow sending messages without a body - [Bug 49862](https://bz.apache.org/bugzilla/show_bug.cgi?id=49862) - Improve SMTPSampler Request output. - [Bug 50268](https://bz.apache.org/bugzilla/show_bug.cgi?id=50268) - Adds static and dynamic destinations to JMS Publisher - JMS Subscriber - Add dynamic destination - [Bug 50666](https://bz.apache.org/bugzilla/show_bug.cgi?id=50666) - JMSSubscriber: support for durable subscriptions - [Bug 50937](https://bz.apache.org/bugzilla/show_bug.cgi?id=50937) - TCP Sampler does not provide for / honor connect timeout - [Bug 50569](https://bz.apache.org/bugzilla/show_bug.cgi?id=50569) - Jdbc Request Sampler to optionally store result set object data - [Bug 51011](https://bz.apache.org/bugzilla/show_bug.cgi?id=51011) - Mail Reader: upon authentication failure, tell what you tried #### Controllers - [Bug 50475](https://bz.apache.org/bugzilla/show_bug.cgi?id=50475) - Introduction of a Test Fragment Test Element for a better Include flow #### Listeners - View Results Tree - Add a dialog's text box on "Sampler result tab → Parsed" to display the long value with a double click on cell - [Bug 37156](https://bz.apache.org/bugzilla/show_bug.cgi?id=37156) - Formatted view of Request in Results Tree - [Bug 49365](https://bz.apache.org/bugzilla/show_bug.cgi?id=49365) - Allow result set to be written to file in a path relative to the loaded script - [Bug 50579](https://bz.apache.org/bugzilla/show_bug.cgi?id=50579) - Error count is long, sample count is int. Changed sample count to long. - View Results Tree - Add new size fields: response headers and response body (in bytes) - derived from [Bug 43363](https://bz.apache.org/bugzilla/show_bug.cgi?id=43363) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 48015](https://bz.apache.org/bugzilla/show_bug.cgi?id=48015) - Proposal new icons for pre-processor, post-processor and assertion elements - [Bug 50962](https://bz.apache.org/bugzilla/show_bug.cgi?id=50962) - SizeAssertionGui validation prevents the use of variables for the size - Size Assertion - Add response size scope (full, headers, body, code, message) - derived from [Bug 43363](https://bz.apache.org/bugzilla/show_bug.cgi?id=43363) #### Functions - [Bug 49975](https://bz.apache.org/bugzilla/show_bug.cgi?id=49975) - New function returning the name of the current sampler #### I18N - Add French translation for the new labels and reduce size for some labels (by abbreviation) on HTTP Sample #### General - [Bug 30563](https://bz.apache.org/bugzilla/show_bug.cgi?id=30563) - Thread Group should have a start next loop option on Sample Error - [Bug 50347](https://bz.apache.org/bugzilla/show_bug.cgi?id=50347) - Eclipse setup instructions should remind user to download dependent jars - [Bug 50490](https://bz.apache.org/bugzilla/show_bug.cgi?id=50490) - Setup and Post Thread Group enhancements for better test flow. - All BeanShell test elements now have the script variables "prev" and "Label" defined. - [Bug 50708](https://bz.apache.org/bugzilla/show_bug.cgi?id=50708) - Classpath jar order in NewDriver not alphabetically - [Bug 50659](https://bz.apache.org/bugzilla/show_bug.cgi?id=50659) - JMeter server does not support concurrent tests - prevent client from starting another - Added remote shutdown functionality - Client JMeter engine now supports external stop/shutdown via UDP - UDP shutdown can now use a range of ports, from jmeterengine.nongui.port=4445 to jmeterengine.nongui.maxport=4455, allowing multiple JMeter instances on the same host without needing to change the port property. - Updated to httpcore 4.1.3 and httpclient 4.1.2 ### Non-functional changes - [Bug 50008](https://bz.apache.org/bugzilla/show_bug.cgi?id=50008) - Allow BatchSampleSender to be subclassed - [Bug 50450](https://bz.apache.org/bugzilla/show_bug.cgi?id=50450) - use System.array copy in jacobi solver as, being native, is more performant. - [Bug 50487](https://bz.apache.org/bugzilla/show_bug.cgi?id=50487) - runSerialTest verifies objects that never need persisting - Use Thread.setDefaultUncaughtExceptionHandler() instead of private ThreadGroup - Update to Commons Net 3.0 ## Version 2.4 ### Summary of main changes - JMeter now requires at least Java 1.5. - HTTP Proxy can now record HTTPS sessions. - JUnit sampler now supports JUnit4 annotations. - Added JSR223 (javax.script) test elements. - MailReader Sampler can now use any protocol supported by the underlying implementation. - An SMTP Sampler has been added. - JMeter now allows users to provide their own Thread Group implementations. - View Results Tree now supports more display options, including search and Regex Testing. - StatCalculator performance is much improved; Aggregate Report etc. need far less memory. - JMS samplers have been extensively reworked, and should no longer lose messages. Correlation processing is improved. JMS Publisher and Subscriber now support both Topics and Queues. - Many other improvements have been made, please see below and in the manual. ### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a NullPointerException if there are two include controllers with the same name. Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The menu item Options / Choose Language does not change all the displayed text to the new language. [The behaviour has improved, but language change is still not fully working] To override the default local language fully, set the JMeter property "language" before starting JMeter. ### Incompatible changes HTTP Redirect now defaults to "Follow Redirects" rather than "Redirect Automatically". This is to enable JMeter to track cookies that may be sent during redirects. This does not affect existing test plans; it only affects the default for new HTTP Samplers. The Avalon file format for JMX and JTL files is no longer supported. Any such files will need to be converted by reading them in JMeter 2.3.4 and resaving them. The XPath Assertion and XPath Extractor elements no longer fetch external DTDs by default; this can be changed in the GUI. JMSConfigGui has been renamed as JMSSamplerGui. This does not affect existing test plans. The constructor public SampleResult(SampleResult res) has been changed to become a true "copy constructor". It no longer calls addSubResult(). This may possibly affect some 3rd party add-ons. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 47445](https://bz.apache.org/bugzilla/show_bug.cgi?id=47445) - Using Proxy with https-spoofing secure cookies need to be unsecured - [Bug 47442](https://bz.apache.org/bugzilla/show_bug.cgi?id=47442) - Missing replacement of https by http for certain conditions using https-spoofing - [Bug 48451](https://bz.apache.org/bugzilla/show_bug.cgi?id=48451) - Error in: SoapSampler.setPostHeaders(PostMethod post) in the else branch - [Bug 48542](https://bz.apache.org/bugzilla/show_bug.cgi?id=48542) - SoapSampler uses wrong response header field to decide if response is gzip encoded - [Bug 48568](https://bz.apache.org/bugzilla/show_bug.cgi?id=48568) - CookieManager broken for AjpSampler - [Bug 48570](https://bz.apache.org/bugzilla/show_bug.cgi?id=48570) - AjpSampler doesn't support query parameters (GET/POST) - [Bug 46901](https://bz.apache.org/bugzilla/show_bug.cgi?id=46901) - HTTP Sampler does not process var/func refs correctly in first file parameter - [Bug 43678](https://bz.apache.org/bugzilla/show_bug.cgi?id=43678) - Handle META tag http-equiv charset? - [Bug 49294](https://bz.apache.org/bugzilla/show_bug.cgi?id=49294) - Images not downloaded from redirected-to pages - [Bug 49560](https://bz.apache.org/bugzilla/show_bug.cgi?id=49560) - wrong "size in bytes" when following redirections #### Other Samplers - [Bug 47420](https://bz.apache.org/bugzilla/show_bug.cgi?id=47420) - LDAP extended request not closing connections during add request - [Bug 48573](https://bz.apache.org/bugzilla/show_bug.cgi?id=48573) - LDAPExtSampler directory context handling - [Bug 47870](https://bz.apache.org/bugzilla/show_bug.cgi?id=47870) - JMSSubscriber fails due to NPE - [Bug 47899](https://bz.apache.org/bugzilla/show_bug.cgi?id=47899) - NullPointerExceptions in JMS ReceiveSubscriber constructor - [Bug 48144](https://bz.apache.org/bugzilla/show_bug.cgi?id=48144) - NPE in JMS OnMessageSubscriber - [Bug 47992](https://bz.apache.org/bugzilla/show_bug.cgi?id=47992) - JMS Point-to-Point Request - Response option doesn't work - [Bug 48579](https://bz.apache.org/bugzilla/show_bug.cgi?id=48579) - Single Bind does not show config information when LdapExt Sampler is accessed - [Bug 49111](https://bz.apache.org/bugzilla/show_bug.cgi?id=49111) - "Message With ID Not Found" Error on JMS P2P sampler. - [Bug 47949](https://bz.apache.org/bugzilla/show_bug.cgi?id=47949) - JMS Subscriber never receives all the messages - [Bug 46142](https://bz.apache.org/bugzilla/show_bug.cgi?id=46142) - JMS Point-to-Point correlation problems - [Bug 48747](https://bz.apache.org/bugzilla/show_bug.cgi?id=48747) - TCP Sampler swallows exceptions - [Bug 48709](https://bz.apache.org/bugzilla/show_bug.cgi?id=48709) - TCP Sampler Config setting "classname" has no effect #### Controllers - [Bug 47385](https://bz.apache.org/bugzilla/show_bug.cgi?id=47385) - TransactionController should set AllThreads and GroupThreads - [Bug 47940](https://bz.apache.org/bugzilla/show_bug.cgi?id=47940) - Module controller incorrectly creates the replacement Sub Tree - [Bug 47592](https://bz.apache.org/bugzilla/show_bug.cgi?id=47592) - Run Thread groups consecutively with "Stop test" on error, JMeter will not mark to finished - [Bug 48786](https://bz.apache.org/bugzilla/show_bug.cgi?id=48786) - Run Thread groups consecutively: with "Stop test now" on error or manual stop, JMeter leaves the green box active - [Bug 48727](https://bz.apache.org/bugzilla/show_bug.cgi?id=48727) - Cannot stop test if all thread groups are disabled #### Listeners - [Bug 48603](https://bz.apache.org/bugzilla/show_bug.cgi?id=48603) - Mailer Visualiser sends two emails for a single failed response - Correct calculation of min/max/std.dev for aggregated samples (Summary Report) - [Bug 48889](https://bz.apache.org/bugzilla/show_bug.cgi?id=48889) - Wrong response time with mode=Statistical and num_sample_threshold > 1 - [Bug 47398](https://bz.apache.org/bugzilla/show_bug.cgi?id=47398) - SampleEvents are sent twice over RMI in distributed testing and non gui mode #### Assertions #### Functions #### I18N #### General - [Bug 47646](https://bz.apache.org/bugzilla/show_bug.cgi?id=47646) - NullPointerException in the "Random Variable" element - Disallow adding any child elements to JDBC Configuration - BeanInfoSupport now caches getBeanDescriptor() - should avoid an NPE on non-Sun JVMs when using CSVDataSet (and some other TestBeans) - [Bug 48350](https://bz.apache.org/bugzilla/show_bug.cgi?id=48350) - Deadlock on distributed testing with 2 clients - [Bug 48901](https://bz.apache.org/bugzilla/show_bug.cgi?id=48901) - Endless wait by adding Synchronizing Timer - [Bug 49149](https://bz.apache.org/bugzilla/show_bug.cgi?id=49149) - usermanual/index.html has typo in link to "Regular Expressions" page - [Bug 49394](https://bz.apache.org/bugzilla/show_bug.cgi?id=49394) - Classcast Exception in ActionRouter.postActionPerformed - [Bug 48136](https://bz.apache.org/bugzilla/show_bug.cgi?id=48136) - Essential files missing from source tarball. Source archives now contain all source files, including source files previously only provided in the binary archives. - [Bug 48331](https://bz.apache.org/bugzilla/show_bug.cgi?id=48331) - XpathExtractor does not return XML string representations for a Nodeset ### Improvements #### HTTP Samplers - [Bug 47622](https://bz.apache.org/bugzilla/show_bug.cgi?id=47622) - enable recording of HTTPS sessions - Allow Proxy Server to be specified on HTTP Sampler GUI and HTTP Config GUI - [Bug 47461](https://bz.apache.org/bugzilla/show_bug.cgi?id=47461) - Update Cache Manager to handle Expires HTTP header - [Bug 48153](https://bz.apache.org/bugzilla/show_bug.cgi?id=48153) - Support for Cache-Control and Expires headers - [Bug 47946](https://bz.apache.org/bugzilla/show_bug.cgi?id=47946) - Proxy should enable Grouping inside a Transaction Controller - [Bug 48300](https://bz.apache.org/bugzilla/show_bug.cgi?id=48300) - Allow override of IP source address for HTTP HttpClient requests - [Bug 49083](https://bz.apache.org/bugzilla/show_bug.cgi?id=49083) - collapse '/pathsegment/..' in redirect URLs #### Other samplers - JUnit sampler now supports JUnit4 tests (using annotations) - [Bug 47900](https://bz.apache.org/bugzilla/show_bug.cgi?id=47900) - Allow JMS SubscriberSampler to be interrupted - Added JSR223 Sampler - [Bug 47556](https://bz.apache.org/bugzilla/show_bug.cgi?id=47556) - JMS-PointToPoint-Sampler Timeout field should use Strings - [Bug 47947](https://bz.apache.org/bugzilla/show_bug.cgi?id=47947) - Mail Reader Sampler should allow port to be overridden - [Bug 48155](https://bz.apache.org/bugzilla/show_bug.cgi?id=48155) - Multiple problems / enhancements with JMS protocol classes - Allow MailReader sampler to use arbitrary protocols - [Bug 45053](https://bz.apache.org/bugzilla/show_bug.cgi?id=45053) - SMTP-Sampler for JMeter - [Bug 49552](https://bz.apache.org/bugzilla/show_bug.cgi?id=49552) - Add Message Headers on SMTPSampler - JMS Publisher and Subscriber now support both Topics and Queues. Added read Timeout to JMS Subscriber. General clean-up of JMS code. #### Controllers - [Bug 47909](https://bz.apache.org/bugzilla/show_bug.cgi?id=47909) - TransactionController should sum the latency - [Bug 41418](https://bz.apache.org/bugzilla/show_bug.cgi?id=41418) - Exclude timer duration from Transaction Controller runtime in report - [Bug 48749](https://bz.apache.org/bugzilla/show_bug.cgi?id=48749) - Allowing custom Thread Groups - [Bug 43389](https://bz.apache.org/bugzilla/show_bug.cgi?id=43389) - Allow Include files to be found relative to the current JMX file #### Listeners - Added DataStrippingSample sender - supports "Stripped" and "StrippedBatch" modes. - Added Comparison Assertion Visualizer - [Bug 47907](https://bz.apache.org/bugzilla/show_bug.cgi?id=47907) - Improvements (enhancements and I18N) Comparison Assertion and Comparison Visualizer - [Bug 36726](https://bz.apache.org/bugzilla/show_bug.cgi?id=36726) - add search function to Tree View Listener - [Bug 47869](https://bz.apache.org/bugzilla/show_bug.cgi?id=47869) - Ability to cleanup fields of SampleResult - [Bug 47952](https://bz.apache.org/bugzilla/show_bug.cgi?id=47952) - Added JSR223 Listener - [Bug 47474](https://bz.apache.org/bugzilla/show_bug.cgi?id=47474) - View Results Tree support for plugin renderers - Allow Idle Time to be saved to sample log files - [Bug 48259](https://bz.apache.org/bugzilla/show_bug.cgi?id=48259) - Improve StatCalculator performance by using TreeMap - Listeners using SamplingStatCalculator have much reduced memory needs as the Sample cache has been moved to the new CachingStatCalculator class. In particular, Aggregate Report can now handle large numbers of samples. - Aggregate Report and Summary Report now allow column headers to be optionally excluded - [Bug 49506](https://bz.apache.org/bugzilla/show_bug.cgi?id=49506) - Add .csv File Extension in open dialog box from "read from file" functionality of listeners - [Bug 49545](https://bz.apache.org/bugzilla/show_bug.cgi?id=49545) - Formatted (parsed) view of Sample Result in Results Tree #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 47338](https://bz.apache.org/bugzilla/show_bug.cgi?id=47338) - XPath Extractor forces retrieval of document DTD - Added Comparison Assertion - [Bug 47952](https://bz.apache.org/bugzilla/show_bug.cgi?id=47952) - Added JSR223 PreProcessor and PostProcessor - Added JSR223 Assertion - Added BSF Timer and JSR223 Timer - [Bug 48511](https://bz.apache.org/bugzilla/show_bug.cgi?id=48511) - add parent,child,all selection to regex extractor - Add Sampler scope selection to XPathExtractor - Regular Expression Extractor, Response Assertion and Size Assertion can now be applied to a JMeter variable - [Bug 46790](https://bz.apache.org/bugzilla/show_bug.cgi?id=46790) - CSV Data Set Config should be able to parse CSV headers #### Functions - [Bug 47565](https://bz.apache.org/bugzilla/show_bug.cgi?id=47565) - [Function] FileToString #### I18N - [Bug 47938](https://bz.apache.org/bugzilla/show_bug.cgi?id=47938) - Adding some French translations for new elements - [Bug 48714](https://bz.apache.org/bugzilla/show_bug.cgi?id=48714) - add new French messages #### General - [Bug 47223](https://bz.apache.org/bugzilla/show_bug.cgi?id=47223) - Slow Aggregate Report Performance (StatCalculator) - [Bug 47980](https://bz.apache.org/bugzilla/show_bug.cgi?id=47980) - hostname resolves to 127.0.0.1 - specifying IP not possible - [Bug 47943](https://bz.apache.org/bugzilla/show_bug.cgi?id=47943) - DisabledComponentRemover is not used in Start class - HeapDumper class for runtime generation of dumps - Basic read-only JavaMail provider implementation for reading raw mail files - [Bug 49540](https://bz.apache.org/bugzilla/show_bug.cgi?id=49540) - Sort "Add" menus alphabetically ### Non-functional changes - Beanshell, JavaMail and JMS API (Apache Geronimo) jars are now included in the binary archive. - Add TestBean Table Editor support - Removed all external libraries from SVN; added download_jars Ant target - Updated various jar files: - BeanShell - 2.0b4 ⇒ 2.0b5 - Commons Codec - 1.3 ⇒ 1.4 - Commons-Collections - 3.2 ⇒ 3.2.1 - JTidy ⇒ r938 - JUnit - 3.8.2 ⇒ 4.8.1 - Logkit - 1.2 ⇒ 2.0 - Xalan Serializer = 2.7.1 (previously erroneously shown as 2.9.1) - Xerces xml-apis = 1.3.04 (previously erroneously shown as 2.9.1) - Some jar files were renamed. ## Version 2.3.4 ### Summary of main changes This is a minor bug-fix release, mainly to correct some bugs that were accidentally added in 2.3.3. ### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a NullPointerException if there are two include controllers with the same name. Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The menu item Options / Choose Language does not change all the displayed text to the new language. [The behaviour has improved, but language change is still not fully working] To override the default local language fully, set the JMeter property "language" before starting JMeter. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 47321](https://bz.apache.org/bugzilla/show_bug.cgi?id=47321) - HTTPSampler2 response timeout not honored #### Other Samplers - [Bug 47290](https://bz.apache.org/bugzilla/show_bug.cgi?id=47290) - Infinite loop on connection factory lookup (JMS) - JDBC Sampler should not close Prepared or Callable statements as these are cached #### Controllers - [Bug 39509](https://bz.apache.org/bugzilla/show_bug.cgi?id=39509) - Once-only controller running twice #### Listeners - Change ResultCollector to only warn if the directory was not created - Fix some synchronisation issues in ResultCollector and SampleResult (wrong locks were being used) #### I18N - Fixed bug introduced in 2.3.3: JMeter does not start up if there is no messages.properties file for the default Locale. #### General - Fix problems with remote clients - bug introduced in 2.3.3 - [Bug 47377](https://bz.apache.org/bugzilla/show_bug.cgi?id=47377) - Make ClassFinder more robust and close zipfile resources - Fix some errors in generating the documentation (latent bug revealed in 2.3.3 when Velocity was upgraded) ### Improvements #### Other samplers - [Bug 47266](https://bz.apache.org/bugzilla/show_bug.cgi?id=47266) - FTP Request Sampler: allow specifying an FTP port, other than the default ## Version 2.3.3 ### Summary of main changes The handling of test closedown is much improved. The gradual "Shutdown" command now waits until all threads have stopped, and does not report an error if threads don't stop within 5 seconds. The immediate "Stop" command can now be used if "Shutdown" takes too long. Also the immediate "Stop" command is able to interrupt samplers which support the new Interruptible interface (e.g. HTTP and SOAP, FTP). This allows immediate completion of pending responses. Non-GUI mode tests can also now be sent a "Shutdown" or "Stop" message. [Test Action](/user-manual/component-reference/#Test_Action) now supports a "Stop Now" action, as do the [Thread Group](/user-manual/component-reference/#Thread_Group) and [Result Status Action Handler](/user-manual/component-reference/#Result_Status_Action_Handler) Post Processor elements. HTTP Cookie handling is improved, and HTTP POST can now use variable file names correctly. HTTP, SOAP/XML-RPC and WebService(SOAP) sampler character encodings updated to be more consistent. HTTP Samplers now support connection and response timeouts (requires JVM 1.5 for the HTTP Java sampler). Together with the closedown improvements described above, this should avoid most cases where a test run hangs. Multiple Header Manager elements are now supported for a single HTTP sampler. The Proxy Server is improved, and no longer stores "Host" headers by default. JDBC Request can optionally save the results of Select statements to variables. JDBC Request now handles quoted strings and UTF-8, and can handle arbitrary variable types. There are several new [functions](/usermanual/functions/): __char() function: allows arbitrary Unicode characters to be entered in fields. __unescape() function: allows Java-escaped strings to be used. _unescapeHtml() function: decodes Html-encoded text. __escapeHtml() function: encodes text using Html-encoding. A reference to a missing function - e.g. \$\{__missing(a)\} - is now treated the same as a missing variable. Previously the function name - and leading \{ - were dropped. This makes it easier to debug test plans. Some Assertions can now be applied to sub-samples as well as (or instead of) just the parent sample. There is a new [Random Variable](/user-manual/component-reference/#Random_Variable) Configuration element. JMS samplers are much improved (see details below). The [TCP Sampler](/user-manual/component-reference/#TCP_Sampler) now supports some additional clients and is a bit more flexible. Client-server mode has been improved, and the server can optionally use a fixed RMI port, which should help with setting up firewalls. Various I18N changes have been made; language change works better (though not perfect yet). There are improved French translations as well as new Polish and Brazilian Portuguese translations. The BeanShell jar is now included with the binary archive; there is no need to download it separately. ### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a `NullPointerException` if there are two include controllers with the same name. Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The menu item **Options → Choose Language** does not change all the displayed text to the new language. [The behaviour has improved, but language change is still not fully working] To override the default local language fully, set the JMeter property "`language`" before starting JMeter. ### Incompatible changes When loading sample results from a file, previous results are no longer cleared. This allows one to merge multiple files. If the previous behaviour is required, use the menu item **Run → Clear → (Ctrl+Shift+E)** or **Run → Clear All → (Ctrl+E)** before loading the file. The test elements "Save Results to a file" and "Generate Summary Results" are now shown as Listeners. They were previously shown as Post-Processors, even though they are implemented as Listeners. The Cookie Manager no longer saves incoming cookies as variables by default. To save cookies as variables, define the property "`CookieManager.save.cookies=true`". Also, cookies names are prefixed with "`COOKIE_`" before they are stored (this avoids accidental corruption of local variables) To revert to the original behaviour, define the property "`CookieManager.name.prefix= `" (one or more spaces). The Counter element is now shown as a Configuration element. It was previously shown as a Pre-Processor, even though it is implemented as a Config item. The above changes only affect the icons that are displayed and the locations in the GUI pop-up menus. They do not affect test plans or test behaviour. The PreProcessors are now invoked directly by the JMeterThread class, rather than by the TestCompiler#configureSampler() method. (JMeterThread handles the PostProcessors). This does not affect test plans or behaviour, but could perhaps affect 3rd party add-ons (very unlikely). Moved the Scoping Rules sub-section from Section 3. "Building a Test Plan" to Section 4. "Elements of a test plan" The While controller now trims leading and trailing spaces from the condition value before it is compared with `LAST`, blank or false. The "threadName" variable in the _jexl() and __javaScript() functions was previously misspelt as "theadName". The following deprecated methods were removed from JOrphanUtils: booleanToString(boolean) and valueOf(boolean). Java 1.4+ has these methods in the Boolean class. The TestElement interface has some new methods: - void setProperty(String key, String value, String dflt) - void setProperty(String key, boolean value, boolean dflt) - void setProperty(String key, int value) - void setProperty(String key, int value, int dflt) - int getPropertyAsInt(String key, int defaultValue) These are implemented in the AbstractTestElement class which all elements should extend so this is unlikely to cause a problem. ### Bug fixes #### HTTP Samplers and Proxy - [Bug 46332](https://bz.apache.org/bugzilla/show_bug.cgi?id=46332) - HTTP Cookie Manager ignores manually defined cookies (bug introduced in r707810) - Cookie Manager was not passing cookie policy to runtime threads so they always used compatibility mode - Add version attribute to JMeter Cookie class (needed for proper cookie support) - Cookie Manager now saves/restores cookie versions - Check validity of cookies before storing them. - HTTPSamplers can now use variables in POSTed file names - Fix processing of first file name in HTTP POST so functions/variables work (bug introduced with multiple file support) - [Bug 45831](https://bz.apache.org/bugzilla/show_bug.cgi?id=45831) - WS Sampler reports incorrect throughput if SOAP packet creation fails - HTTP, SOAP/XML-RPC and WebService(SOAP) sampler character encodings updated to be more consistent - [Bug 46148](https://bz.apache.org/bugzilla/show_bug.cgi?id=46148) - HTTP sampler fails on SSL requests when logging for jmeter.util is set to DEBUG - Fix Java 1.6 https error: java.net.SocketException: Unconnected sockets not implemented - [Bug 46838](https://bz.apache.org/bugzilla/show_bug.cgi?id=46838) - if there was no data, still need to set latency in HTTPSampler - [Bug 46993](https://bz.apache.org/bugzilla/show_bug.cgi?id=46993) - Saving from Header Manager generates ClassCastException - [Bug 46690](https://bz.apache.org/bugzilla/show_bug.cgi?id=46690) - handling of 302 redirects with invalid relative paths. JMeter now removes extraneous leading "../" segments (as do many browsers) - [Bug 44521](https://bz.apache.org/bugzilla/show_bug.cgi?id=44521) - empty variables for a POST in the HTTP Request don't get ignored - [Bug 46977](https://bz.apache.org/bugzilla/show_bug.cgi?id=46977) - JMeter does not handle HTTP headers not delimited by whitespace - Fix bug in HTTP file: handling - read bytes, not characters in the default encoding. - Remove Host from headers saved by the Proxy server, as that will normally be generated by the HTTP stack - [Bug 45199](https://bz.apache.org/bugzilla/show_bug.cgi?id=45199) - don't try to replace blank variables in Proxy recording - Change HTTPS spoofing so https: links are replaced even when URL match fails - [Bug 46436](https://bz.apache.org/bugzilla/show_bug.cgi?id=46436) - Improve error reporting in Proxy Gui - [Bug 46435](https://bz.apache.org/bugzilla/show_bug.cgi?id=46435) - More verbose error msg for error 501 (Proxy Server) #### Other Samplers - The "prev" and "sampler" objects are now defined for BSF test elements - Fix NPE (in DataSourceElement) when using JDBC in client-server mode - [Bug 45425](https://bz.apache.org/bugzilla/show_bug.cgi?id=45425) - JDBC Request does not support Unicode (changed sampler to use UTF-8) - [Bug 46522](https://bz.apache.org/bugzilla/show_bug.cgi?id=46522) - Incorrect "Response data" in JDBC sample when column names are missing - [Bug 46821](https://bz.apache.org/bugzilla/show_bug.cgi?id=46821) - JDBC select request doesn't store the first column in the variables - [Bug 43791](https://bz.apache.org/bugzilla/show_bug.cgi?id=43791) - ensure QueueReceiver is closed in JMS Point to Point sampler - [Bug 46016](https://bz.apache.org/bugzilla/show_bug.cgi?id=46016) - avoid possible NPE in JMSSampler - [Bug 46142](https://bz.apache.org/bugzilla/show_bug.cgi?id=46142) - JMS Receiver now uses MessageID - [Bug 45458](https://bz.apache.org/bugzilla/show_bug.cgi?id=45458) - Point to Point JMS in combination with authentication - [Bug 45460](https://bz.apache.org/bugzilla/show_bug.cgi?id=45460) - JMS TestPlan elements depend on resource property - Various ReceiveSubscriber thread-safety fixes - JMSPublisher and Subscriber fixes: thread-safety, support dynamic locale changes, locale independence for JMX attribute values - FTP Sampler now logs out before disconnecting. - TCP sampler now calls setupTest() and teardownTest() methods - [Bug 45887](https://bz.apache.org/bugzilla/show_bug.cgi?id=45887) - TCPSampler: timeout property incorrectly set #### Controllers - Fix NPE when using nested Transaction Controllers with parent samples - Fix processing of Transaction Controller parent mode so current sampler is set to actual sampler - [Bug 44941](https://bz.apache.org/bugzilla/show_bug.cgi?id=44941) - Throughput controllers should not share global counters - [Bug 47120](https://bz.apache.org/bugzilla/show_bug.cgi?id=47120) - Throughput Controller: change percent executions to total executions, the value is stored in a String and interpreted as 1 execution - [Bug 47150](https://bz.apache.org/bugzilla/show_bug.cgi?id=47150) - ThreadGroup with a loop count of zero causes infinite loop - [Bug 47009](https://bz.apache.org/bugzilla/show_bug.cgi?id=47009) - Insert parent caused child controller name to be reset - [Bug 47165](https://bz.apache.org/bugzilla/show_bug.cgi?id=47165) - Using duplicate Module Controller names in command line mode causes NPE #### Listeners - Mailer Visualizer documentation now agrees with code i.e. failure/success counts need to be exceeded to trigger the mail. - Mailer Visualizer now shows the failure count - Mailer Visualiser - fix parsing of multiple e-mail address when using Test button - [Bug 45976](https://bz.apache.org/bugzilla/show_bug.cgi?id=45976) - incomplete result file when using remote testing with more than 1 server - Fix Summariser so it works in client server mode - [Bug 34096](https://bz.apache.org/bugzilla/show_bug.cgi?id=34096) - Duplicate samples not eliminated when writing to CSV files - Save "Include group Name in Label" setting in Aggregate and Summary reports - The JMeter variable "sample_variables" is sent to all server instances to ensure the data is available to the client. - CSVSaveService - check for EOF while reading quoted string #### Assertions - [Bug 45749](https://bz.apache.org/bugzilla/show_bug.cgi?id=45749) - Response Assertion does not work with a substring that happens to be an invalid RE - [Bug 45904](https://bz.apache.org/bugzilla/show_bug.cgi?id=45904) - Allow 'Not' Response Assertion to succeed with null sample #### Functions - Fix regex function - was failing to process $m$mid$n$ correctly - Protect against possible NPE in RegexFunction if called during test shutdown. - Avoid NPE if XPath function does not match any nodes - Correct the variable name "theadName" to "threadName" in the __jexl() and __javaScript() functions - A reference to a missing function - e.g. \$\{__missing(a)\} - is now treated the same as a missing variable. Previously the function name - and leading \{ - were dropped. #### I18N - Fixed language change handling for menus (does not yet work for TestBeans) - Add HeaderAsPropertyRenderer to support header resource names; use this to fix locale changes in various GUI elements - [Bug 46424](https://bz.apache.org/bugzilla/show_bug.cgi?id=46424) - corrections to French translation - [Bug 46844](https://bz.apache.org/bugzilla/show_bug.cgi?id=46844) - "Library" label in test plan are not I18N - [Bug 47064](https://bz.apache.org/bugzilla/show_bug.cgi?id=47064) - fixes for Mac LAF - [Bug 47127](https://bz.apache.org/bugzilla/show_bug.cgi?id=47127) - Unable to change language to pl_PL - [Bug 47137](https://bz.apache.org/bugzilla/show_bug.cgi?id=47137) - Labels in View Results Tree aren't I18N - [Bug 46423](https://bz.apache.org/bugzilla/show_bug.cgi?id=46423) - I18N of Proxy Recorder - [Bug 45928](https://bz.apache.org/bugzilla/show_bug.cgi?id=45928) - AJP/1.3 Sampler doesn't retrieve its label from messages.properties #### General - Prompt to overwrite an existing file when first saving a new test plan - Amend TestBeans to show the correct popup menu for Listeners - [Bug 45185](https://bz.apache.org/bugzilla/show_bug.cgi?id=45185) - CSV dataset blank delimiter causes OOM - Fix incorrect GUI classifications: "Save Results to a file" and "Generate Summary Results" are now shown as Listeners. "Counter" is now shown as a Configuration element. - [Bug 41608](https://bz.apache.org/bugzilla/show_bug.cgi?id=41608) - misleading warning log message removed - [Bug 46359](https://bz.apache.org/bugzilla/show_bug.cgi?id=46359) - BSF JavaScript Preprocessor cannot access sampler variable on first iteration (Implement temporary work-round for BSF-22) - [Bug 46407](https://bz.apache.org/bugzilla/show_bug.cgi?id=46407) - BSF elements do not load script files, attempt to interpret filename as script - Better handling of Exceptions during test shutdown - Fix potential thread safety issue in JMeterThread class - [Bug 46491](https://bz.apache.org/bugzilla/show_bug.cgi?id=46491) - Incorrect value for the last variable in "CSV Data Set Config" (error in processing quoted strings) ### Improvements #### HTTP Samplers - [Bug 45479](https://bz.apache.org/bugzilla/show_bug.cgi?id=45479) - Support for multiple HTTP Header Manager nodes - HTTP Samplers now support connection and request timeouts (requires Java 1.5 for Java Http sampler) - Apache SOAP 2.3.1 does not give access to HTTP response code/message, so WebService sampler now treats an empty response as an error - Mirror server now supports "X-Sleep" header - if this is set, the responding thread will wait for the specified number of milliseconds - [Bug 45694](https://bz.apache.org/bugzilla/show_bug.cgi?id=45694) - Support GZIP compressed logs in Access Log Sampler #### Other samplers - JDBC Request can optionally save the results of Select statements to variables. - JDBC Request now handles quoted strings. - JDBC Request now handles arbitrary variable types. - LDAP result data now formatted with line breaks - [Bug 45200](https://bz.apache.org/bugzilla/show_bug.cgi?id=45200) - MailReaderSampler: store the whole MIME message in the SamplerResult - [Bug 45571](https://bz.apache.org/bugzilla/show_bug.cgi?id=45571) - JMS Sampler correlation enhancement - [Bug 46030](https://bz.apache.org/bugzilla/show_bug.cgi?id=46030) - Extend TCP Sampler to Support Length-Prefixed Binary Data - Add classname field to TCP Sampler GUIs #### Controllers - Allow If Controller to use variable expressions (not just Javascript) - Trim spaces from While Controller condition before comparing against LAST, blank or false #### Listeners - Save Responses to a file can save the generated filename(s) to variables. - Add option to skip suffix generation in Save Responses to a File - [Bug 43119](https://bz.apache.org/bugzilla/show_bug.cgi?id=43119) - Save Responses to file: optionally omit the file number - Add BSF Listener element - [Bug 47176](https://bz.apache.org/bugzilla/show_bug.cgi?id=47176) - Monitor Results : improve load status graphic - [Bug 40045](https://bz.apache.org/bugzilla/show_bug.cgi?id=40045) - Allow Results monitor to select a specific connector - Read XML JTL files more efficiently - pass samples to visualizers as they are read, rather than saving them all and then processing them #### Assertions, Config, Pre- & Post-Processors - [Bug 45903](https://bz.apache.org/bugzilla/show_bug.cgi?id=45903) - allow Assertions to apply to sub-samples - Add Body (unescaped) source option to Regular Expression Extractor. - Random Variable - new configuration element to create random numeric variables #### Functions - Add OUT and log variables to __jexl() function - Use Script to evaluate __jexl() function so can have multiple statements. - Add log variable to the __javaScript() function - Added __char() function: allows arbitrary Unicode characters to be entered in fields. - Added __unescape() function: allows Java-escaped strings to be used. - Added __unescapeHtml() function: decodes Html-encoded text. - Added __escapeHtml() function: encodes text using Html-encoding. #### I18N - [Bug 45929](https://bz.apache.org/bugzilla/show_bug.cgi?id=45929) - improved French translations - [Bug 47132](https://bz.apache.org/bugzilla/show_bug.cgi?id=47132) - Brazilian Portuguese translations - [Bug 46900](https://bz.apache.org/bugzilla/show_bug.cgi?id=46900) - Polish translations - Added locales.add property to allow for new Locales #### General - Allow spaces in JMeter path names (apply work-round for [Java Bug 4496398](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4496398)) - Process JVM_ARGS last in script files so users can override default settings - [Bug 46636](https://bz.apache.org/bugzilla/show_bug.cgi?id=46636) - Allow server mode to optionally use a fixed rmi port - Make some samplers interruptible: HTTP (both), SoapSampler, FTPSampler - Test Action now supports "Stop Now" action, as do the Thread Group and Result Status Post Processor elements - The Menu items Stop and Shutdown now behave better. Shutdown will now wait until all threads exit. In GUI mode it can be cancelled and Stop run instead. Stop now reports if some threads will not exit, and exits if running in non-GUI mode - Add UDP server to wait for shutdown message if running in non-GUI mode; add UDP client to send the message. - [Bug 41209](https://bz.apache.org/bugzilla/show_bug.cgi?id=41209) - JLabeled* and ToolTips - Include BeanShell 2.0b4 jar in binary download. ### Non-functional changes - Introduce AbstractListenerGui class to make it easier to create Listeners with no visual output - Assertions are run after PostProcessors; change order of pop-up menus accordingly - Remove unnecessary clone() methods from function classes - Moved PreProcessor invocation to JMeterThread class - Made HashTree Map field final - Improve performance of calling ResultCollector#isSampleWanted() for multiple samples - Updated to new versions of: xmlgraphics-commons (1.3.1), jdom (1.1), xstream (1.3.1), velocity (1.6.2) ### Version 2.3.2 #### Summary of main changes ##### Bug fixes Version 2.3.1 changed the way binary and text content types were determined as far as the View Results Tree Listener was concerned: originally everything except "image/" content types were considered text, but 2.3.1 introduced a check for specific content types. This has caused problems, as several popular types were omitted and these were no longer shown by default in the Response tab. Rather than try to list all the possible text types, JMeter now just checks for the following binary types: - image/* - audio/* - video/* All other types are now assumed to be text. JMeter 2.3.1 introduced a bug in the Cookie Manager - if "Clear Cookie each iteration" was selected, all threads would see the same cookies. This bug has been corrected. ##### Improvements The Proxy server can now record binary requests. By default the content types application/x-amf and application/x-java-serialized-object will be treated as binary and saved in a file. To change the content types, update the property **proxy.binary.types**. The CSV Dataset configuration element has new file sharing options: per thread group, per thread, per identifier. This allows for more flexible file processing, e.g. each thread can process the same data in the same order. Switch Controller now works properly with functions and variables, and the condition can now be a name instead of a number. Simple Controller now works properly under a While Controller CSV fields in JTL files can now contain delimiters. CSV and XML files can now contain additional variables (define the JMeter property **sample_variables**). Response Assertion can now match on substrings (i.e. not regular expression). Regex extractor can operate on variables. XPath processing is improved; Tidy errors are handled better. Save Table Data buttons added to Summary and Aggregate reports to allow easy saving of the calculated data. HTTP samplers can now save just the MD5 hash of responses, rather than the entire response. As a special case, if the HTTP Sampler path starts with "http://" or "https://" then this is used as the full URL, overriding the host and port fields. The HTTP Samplers can now POST multiple files. Webservice(SOAP) Sampler can now load local WSDL files using the "file:" protocol. A simple HTTP Cache Manager has been added. This needs further development. View Results Tree Listener now uses Tidy to display XML. This should allow more content to be displayed successfully. It also avoids the need to download remote DTD files, which can slow the rendering considerably. MailReader sampler now supports POP3S and IMAPS protocols. Individual mails are now added as sub-samples. Various improvements to the BSF Sampler: now supports Jexl, and Javascript bug works properly. Added BSF PreProcessor, PostProcessor and Assertion test elements. All now have access to "props" JMeter Properties object. Number of classes loaded in non-GUI mode is much reduced. #### Known bugs The Include Controller has some problems in non-GUI mode. In particular, it can cause a NullPointerException if there are two include controllers with the same name. Once Only controller behaves OK under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). The menu item Options / Choose Language does not change all the displayed text to the new language. To override the default local language, set the JMeter property "language" before starting JMeter. #### Incompatible changes - To reduce the number of classes loaded in non-GUI mode, Functions will only be found if their classname contains the string '.functions.' and does not contain the string '.gui.'. All existing JMeter functions conform to this restriction. To revert to earlier behaviour, comment or change the properties classfinder.functions.* in jmeter.properties. - The reference value parameter for intSum() is now optional. As a consequence, if a variable name is used, it must not be a valid integer. - The supplied TCPClient implementation no longer treats tcp.eolByte=0 as special. To skip EOL checking, set tcp.eolByte=1000 (or some other value which is not a valid byte) - Leading and trailing spaces are trimmed from variable names in function calls. For example, \$\{__Random(1,63, LOTTERY )\} will use the variable 'LOTTERY' rather than ' LOTTERY '. - Synchronization has been removed from the RunningSample class (it was not fully threadsafe anyway). Developers of 3rd party add-ons that use the class may need to synchronize access. #### Bug fixes - Check that the CSV delimiter is reasonable. - Fix Switch Controller to work properly with functions and variables - [Bug 44011](https://bz.apache.org/bugzilla/show_bug.cgi?id=44011) - application/soap+xml not treated as a text type - [Bug 43427](https://bz.apache.org/bugzilla/show_bug.cgi?id=43427) - Simple Controller is only partly executed in While loop - [Bug 33954](https://bz.apache.org/bugzilla/show_bug.cgi?id=33954) - Stack Overflow in If/While controllers (may have been fixed previously) - [Bug 44022](https://bz.apache.org/bugzilla/show_bug.cgi?id=44022) - Memory Leak when closing test plan - [Bug 44042](https://bz.apache.org/bugzilla/show_bug.cgi?id=44042) - Regression in Cookie Manager (Bug introduced in 2.3.1) - [Bug 41028](https://bz.apache.org/bugzilla/show_bug.cgi?id=41028) - JMeter server doesn't alert the user when the host is defined as a loopback address - [Bug 44142](https://bz.apache.org/bugzilla/show_bug.cgi?id=44142) - Function __machineName causes NPE if parameters are omitted. - [Bug 44144](https://bz.apache.org/bugzilla/show_bug.cgi?id=44144) - JMS point-to-point: request response test does not work - [Bug 44314](https://bz.apache.org/bugzilla/show_bug.cgi?id=44314) - Not possible to add more than one SyncTimer - Capture Tidy console error output and log it - Fix problems using Tidy(tolerant parser) in XPath Assertion and XPath Extractor - [Bug 44374](https://bz.apache.org/bugzilla/show_bug.cgi?id=44374) - improve timer calculation - Regular Expression Extractor now deletes all stale variables from previous matches. - [Bug 44707](https://bz.apache.org/bugzilla/show_bug.cgi?id=44707) - Running remote test changes internal test plan - [Bug 44625](https://bz.apache.org/bugzilla/show_bug.cgi?id=44625) - Cannot have two or more FTP samplers with different "put" and "get" actions - [Bug 40850](https://bz.apache.org/bugzilla/show_bug.cgi?id=40850) - BeanShell memory leak - Ensure ResponseCode and ResponseMessage are set for successful JDBC samples - FTPSampler now detects and reports failure to open the remote file - Class directories defined in search_paths and user.classpath no longer need trailing "/" - [Bug 44852](https://bz.apache.org/bugzilla/show_bug.cgi?id=44852) SOAP/ XML-RPC Request does not show Request details in View Results Tree - WebService(SOAP) Sampler ResponseData now includes the EOLs sent by server - [Bug 44910](https://bz.apache.org/bugzilla/show_bug.cgi?id=44910) - close previous socket (if any) in TCP Sampler - [Bug 44912](https://bz.apache.org/bugzilla/show_bug.cgi?id=44912) - Filter not working in Log Parser - The BeanShell and BSF component documentation made some incorrect references to the "SampleResponse" object; this has been corrected to "SampleResult" - BSF Sampler now works properly with Javascript - Test Action "Stop Test" now works - [Bug 42833](https://bz.apache.org/bugzilla/show_bug.cgi?id=42833) - Argument class uses LinkedHashMap in getArgumentsAsMap() to preserve ordering - [Bug 45093](https://bz.apache.org/bugzilla/show_bug.cgi?id=45093) - SizeAssertion did not call getBytes() - [Bug 45007](https://bz.apache.org/bugzilla/show_bug.cgi?id=45007) - Rewrite Location headers when using Proxy HTTPS spoofing - Use CRLF rather than LF in Proxy when returning headers to the client - [Bug 45007](https://bz.apache.org/bugzilla/show_bug.cgi?id=45007) - fix content length header if content may have been changed #### Improvements - CSV files can now handle fields with embedded delimiters. - longSum() function added - [Bug 43382](https://bz.apache.org/bugzilla/show_bug.cgi?id=43382) - configure Tidy output (warnings, errors) for XPath Assertion and Post-Processor - [Bug 43984](https://bz.apache.org/bugzilla/show_bug.cgi?id=43984) - trim spaces from port field - Add optional comment to __log() function - Make Random function variable name optional - Reduce class loading in non-GUI mode by only looking for Functions in class names that contain '.functions.' and don't contain '.gui.' - [Bug 43379](https://bz.apache.org/bugzilla/show_bug.cgi?id=43379) - Switch Controller now supports selection by name as well as number - Can specify list of variable names to be written to JTL files (CSV and XML format) - Now checks that the remoteStart options -r and -R are only used with non_GUI -n option - [Bug 44184](https://bz.apache.org/bugzilla/show_bug.cgi?id=44184) - Allow header to be saved with Aggregate Graph data - Added "Save Table Data" buttons to Aggregate and Summary Reports - save table as CSV format with header - Allow most functions to be used on the Test Plan. Note __evalVar(), __split() and __regex() cannot be used on the Test Plan. - Allow Global properties to be loaded from a file, e.g. -Gglobal.properties - Add "Substring" option to Response Assertion - [Bug 44378](https://bz.apache.org/bugzilla/show_bug.cgi?id=44378) - Turkish localisation - Add optional output variable name to Jexl function - Add application/vnd.wap.xhtml+xml as a text type - Add means to override maximum display size in View Results Tree - set the property: view.results.tree.max_size - Use Tidy to display XML in View Results Tree Listener (avoids fetching DTDs) - [Bug 44487](https://bz.apache.org/bugzilla/show_bug.cgi?id=44487) - German translation - As a special case, if the HTTP Sampler path starts with "http://" or "https://" then this is used as the full URL. - [Bug 44575](https://bz.apache.org/bugzilla/show_bug.cgi?id=44575) - Result Saver can now save only successful results - [Bug 44650](https://bz.apache.org/bugzilla/show_bug.cgi?id=44650) - CSV Dataset now handles quoted column values - [Bug 44600](https://bz.apache.org/bugzilla/show_bug.cgi?id=44600) - 1-ms resolution timer when running with Java 1.5+ - [Bug 44632](https://bz.apache.org/bugzilla/show_bug.cgi?id=44632) - Text input enhancement to FTP Sampler - [Bug 42204](https://bz.apache.org/bugzilla/show_bug.cgi?id=42204) - add thread group name to Aggregate and Summary reports - FTP Sampler sets latency = time to login - FTP Sampler sets a URL if it can - [Bug 41921](https://bz.apache.org/bugzilla/show_bug.cgi?id=41921) - add option for samplers to store MD5 of response; done for HTTP Samplers. - Regex Function can now also be applied to a variable rather than just the previous sample result. - Remove HTML Parameter Mask,HTTP User Parameter Modifier from menus as they are deprecated - [Bug 44807](https://bz.apache.org/bugzilla/show_bug.cgi?id=44807) - allow session ids to be terminated by backslash - [Bug 44784](https://bz.apache.org/bugzilla/show_bug.cgi?id=44784) - allow for broken server returning additional charset - Added TESTSTART.MS property / variable = test start time in milliseconds - Add POP3S and IMAPS protocols to Mail Reader Sampler. - Mail Reader Sampler now creates a sub-sample for each mail. - The supplied TCPClient implementation no longer treats tcp.eolByte=0 as special. To skip EOL checking, set tcp.eolByte=1000 (or some other value which is not a valid byte) - JUnit sampler GUI now also finds Test classes defined in user.classpath - Leading and trailing spaces are trimmed from variable names in function calls. For example, \$\{__Random(1,63, LOTTERY )\} will use the variable 'LOTTERY' rather than ' LOTTERY ' - Webservice(SOAP) Sampler can now load local WSDL files using the file: protocol - [Bug 44872](https://bz.apache.org/bugzilla/show_bug.cgi?id=44872) - Add "All Files" filter to Open File dialogs - Mirror server can now be run independently (mirror-server.cmd and mirror-server.sh) - [Bug 19128](https://bz.apache.org/bugzilla/show_bug.cgi?id=19128) - Added multiple file POST support to HTTP Samplers - Allow use of special name LAST to mean the last test run; applies to -t, -l, -j flags - [Bug 44418](https://bz.apache.org/bugzilla/show_bug.cgi?id=44418)/42178 - CSV Dataset file handling improvements - Give BeanShell, Javascript and Jexl functions access to JMeter properties via the "props" object - Give BSF Sampler access to JMeter Properties via "props" object - Add Jexl as a supported BSF Sampler language - Give Beanshell test elements access to JMeter Properties via "props" object - Added BSF PreProcessor, PostProcessor and Assertion test elements - All BSF elements now have access to System.out via the variable "OUT" - Summariser updated to handle variable names - Synchronisation added to Summary and Aggregate Report to try to prevent occasional lost samples - [Bug 44808](https://bz.apache.org/bugzilla/show_bug.cgi?id=44808),[Bug 39641](https://bz.apache.org/bugzilla/show_bug.cgi?id=39641) - Proxy support for binary requests - [Bug 28502](https://bz.apache.org/bugzilla/show_bug.cgi?id=28502) - HTTP Resource Cache #### Non-functional changes - Better handling of MirrorServer startup problems and improved unit test. - Build process now detects missing 3rd party libraries and reports need for both binary and source archives - Skip BeanShell tests if jar is not present - Update to Xerces 2.9.1, Xalan 2.7.1, Commons IO 1.4, Commons Lang 2.4, Commons-Logging 1.1.1, XStream 1.3, XPP3 1.1.4c - Use properties for log/logn function descriptions - Check that all jmx files in the demos directory can be loaded OK - Update copyright to 2008; use copy tag instead of numeric character in HTML output - Methods called from constructors must not be overridable: make GUI init methods private - Make static variables final if possible - Split changes into current and previous #### Version 2.3.1 ##### Summary of changes ###### JMeter Proxy The Proxy spoof function was broken in 2.3; it has been fixed. Spoof now supports an optional parameter to limit spoofing to particular URLs. This is useful for HTTPS pages that have insecure content - e.g. images/stylesheets may be accessed using HTTP. Spoofed responses now drop the default port (443) from https links to make them work better. Ignored proxy samples are now visible in Listeners - the label is enclosed in [ and ] as an indication. Proxy documentation has been improved. ###### GUI changes The Add menus show element types in the order in which they are processed - see [Test Plan Execution Order](/usermanual/test-plan/#executionorder). It is no longer possible to add test elements to inappropriate parts of the tree - e.g. samplers cannot be added directly under a test plan. This also applies to Paste and drag and drop. The File menu now supports a "Revert" option, which reloads the current file. Also the last few file names used are remembered for easy reloading. The Options Menu now supports Collapse All and Expand All items to collapse and expand the test tree. ###### Remote testing The JMeter server now starts the RMI server directly (by default). This simplifies testing, and means that the RMI server will be stopped when the server stops. Functions can now be used in Listener filenames (variables do not work). Command-line option -G can now be used to define properties for remote servers. Option -X can be used to stop a remote server after a non-GUI run. Server can be set to automatically exit after a single test (set property server.exitaftertest=true). ###### Other enhancements JMeter startup no longer loads as many classes; this should reduce memory requirements. Parameter and file support added to all BeanShell elements. Javascript function now supports access to JMeter objects; Jexl function always did have access, but the documentation has now been included. New functions __eval() and __evalVar() for evaluating variables. CSV files with the correct header column names are now automatically recognised when loaded. There is no need to configure the properties. The hostname can now be saved in CSV and XML output files. New "Successes only" option added when saving result files. Errors / Successes only option is now supported when loading XML and CSV files. General documentation improvements. ###### HTTP PUT and DELETE should now work properly. Cookie Manager no longer clears manually entered cookies. Now handles the META tag http-equiv charset ###### JDBC JDBC Sampler now allows INOUT and OUT parameters for Called procedures. JDBC Sampler now allows per-thread connections - set Max Connections = 0 in JDBC Config. --- ##### Incompatible changes - JMeter server now creates the RMI registry by default. If the RMI registry has already been started externally, this will generate a warning message, but the server will continue. This should not affect JMeter testing. However, if you are also using the RMI registry for other applications there may be problems. For example, when the JMeter server shuts down it will stop the RMI registry. Also user-written command files may need to be adjusted (the ones supplied with JMeter have been updated). To revert to the earlier behaviour, define the JMeter property: **server.rmi.create=false**. - The Proxy server removes If-Modified-Since and If-None-Match headers from generated Header Managers. To revert to the previous behaviour, define the property proxy.headers.remove with no value ##### Bug fixes - [Bug 43430](https://bz.apache.org/bugzilla/show_bug.cgi?id=43430) - Count of active threads is incorrect for remote samples - Throughput Controller was not working for "all thread" counts - If a POST body is built from parameter values only, these are now encoded if the checkbox is set. - [Bug 43584](https://bz.apache.org/bugzilla/show_bug.cgi?id=43584) - Assertion Failure Message contains a comma that is also used as the delimiter for CSV files - HTTP Mirror Server now always returns the exact same content, it used to return incorrect data if UTF-8 encoding was used for HTTP POST body, for example - [Bug 43612](https://bz.apache.org/bugzilla/show_bug.cgi?id=43612) - HTTP PUT does not honor request parameters - [Bug 43694](https://bz.apache.org/bugzilla/show_bug.cgi?id=43694) - ForEach Controller (empty collection processing error) - [Bug 42012](https://bz.apache.org/bugzilla/show_bug.cgi?id=42012) - Variable Listener filenames do not get processed in remote tests. Filenames can now include function references; variable references do not work. - Ensure Listener nodes get own save configuration when copy-pasted - Correct Proxy Server include and exclude matching description - port and query are included, contrary to previously documented. - Aggregate Graph and Aggregate Report Column Header is KB/Sec; fixed the values to be KB rather than bytes - Fix SamplingStatCalculator so it no longer adds elapsed time to endTime, as this is handled by SampleResult. This corrects discrepancies between Summary Report and Aggregate Report throughput calculation. - Default HTTPSampleResult to ISO-8859-1 encoding - Fix default encoding for blank encoding - Fix Https spoofing (port problem) which was broken in 2.3 - Fix HTTP (Java) sampler so http.java.sampler.retries means retries, i.e. does not include initial try - Fix SampleResult dataType checking to better detect TEXT documents ##### Improvements - Add run_gui Ant target, to package and then start the JMeter GUI from Ant - Add File→Revert to easily drop the current changes and reload the project file currently loaded - [Bug 31366](https://bz.apache.org/bugzilla/show_bug.cgi?id=31366) - Remember recently opened file(s) - [Bug 43351](https://bz.apache.org/bugzilla/show_bug.cgi?id=43351) - Add support for Parameters and script file to all BeanShell test elements - SaveService no longer needs to instantiate classes - New functions: __eval() and __evalVar() - Menu items now appear in execution order - Test Plan items can now only be dropped/pasted/merged into parts of the tree where they are allowed - Property Display to show the value of System and JMeter properties and allow them to be changed - [Bug 43451](https://bz.apache.org/bugzilla/show_bug.cgi?id=43451) - Allow Regex Extractor to operate on Response Code/Message - JDBC Sampler now allows INOUT and OUT parameters for Called procedures - JDBC Sampler now allows per-thread connections - Cookie Manager not longer clears cookies defined in the GUI - HTTP Parameters without names are ignored (except for POST requests with no file) - "Save Selection As" added to main menu; now checks only item is selected - Test Plan now has Paste menu item (paste was already supported via ^V) - If the default delimiter does not work when loading a CSV file, guess the delimiter by analysing the header line. - Add optional "loopback" protocol for HttpClient sampler - HTTP Mirror Server now supports blocking waiting for more data to appear, if content-length header is present in request - HTTP Mirror Server GUI now has the Start and Stop buttons in a more visible place - Server mode now creates the RMI registry; to disable set the JMeter property server.rmi.create=false - HTTP Sampler now supports using MIME Type field to specify content-type request header when body is constructed from parameter values - Enable exit after a single server test - define JMeter property server.exitaftertest=true - Added -G option to set properties in remote servers - Added -X option to stop remote servers after non-GUI run - [Bug 43485](https://bz.apache.org/bugzilla/show_bug.cgi?id=43485) - Ability to specify keep-alive on SOAP/XML-RPC request - [Bug 43678](https://bz.apache.org/bugzilla/show_bug.cgi?id=43678) - Handle META tag http-equiv charset - [Bug 42555](https://bz.apache.org/bugzilla/show_bug.cgi?id=42555) - [I18N] Proposed corrections for the french translation - [Bug 43727](https://bz.apache.org/bugzilla/show_bug.cgi?id=43727) - Test Action does not support variables or functions - The Proxy server removes If-Modified-Since and If-None-Match headers from generated Header Managers by default. To change the list of removed headers, define the property proxy.headers.remove as a comma-separated list of headers to remove - The javaScript function now has access to JMeter variables and context etc. See [JavaScript function](/usermanual/functions/#__javaScript) - Use drop-down list for BSF Sampler language field - Add hostname to items that can be saved in CSV and XML output files. - Errors only flag is now supported when loading XML and CSV files - Ensure ResultCollector uses SaveService encoding - Proxy now rejects attempts to use it with https - Proxy spoofing can now use RE matching to determine which urls to spoof (useful if images are not https) - Proxy spoofing now drops the default HTTPS port (443) when converting https: links to http: - Add Successes Only logging and display - The JMeter log file name is formatted as a SimpleDateFormat (applied to the current date) if it contains paired single-quotes, .e.g. 'jmeter_'yyyyMMddHHmmss'.log' - Added Collapse All and Expand All Option menu items - Allow optional definition of extra content-types that are viewable as text ##### Non-functional Improvements - Functor code tightened up; Functor can now be used with interfaces, as well as pre-defined targets and parameters. - Save graphics function now prompts before overwriting an existing file - Debug Sampler and Debug PostProcessor added. - Fixed up method names in Calculator and SamplingStatCalculator - Tidied up Listener documentation. #### Version 2.3 #### Fixes since 2.3RC4 ##### Bug fixes - Fix NPE in SampleResultConverter - XStream PrettyPrintWriter cannot handle nulls - If Java HTTP sampler sees null ResponseMessage, replace with HTTP header - [Bug 43332](https://bz.apache.org/bugzilla/show_bug.cgi?id=43332) - 2.3RC4 does not clear Guis based on TestBean - [Bug 42948](https://bz.apache.org/bugzilla/show_bug.cgi?id=42948) - Problems with Proxy gui table fields in Java 1.6 - Fixup broken jmeter-server script - [Bug 43364](https://bz.apache.org/bugzilla/show_bug.cgi?id=43364) - option to revert If Controller to pre 2.3RC3 behaviour - [Bug 43449](https://bz.apache.org/bugzilla/show_bug.cgi?id=43449) - Statistical Remote mode does not handle Latency - [Bug 43450](https://bz.apache.org/bugzilla/show_bug.cgi?id=43450) (partial fix) - Allow SampleCount and ErrorCount to be saved to/restored from files ##### Improvements - Add nameSpace option to XPath extractor - Add NULL parameter option to JDBC sampler - Add documentation links for Rhino and BeanShell to functions; clarify variables and properties - Ensure uncaught exceptions are logged - Look for user.properties and system.properties in JMeter bin directory if not found locally ##### Fixes since 2.3RC3 - Fixed NPE in Summariser (bug introduced in 2.3RC3) - Fixed setup of proxy port (bug introduced in 2.3RC3) - Fixed errors when running non-GUI on a headless host (bug introduced in 2.3RC3) - [Bug 43054](https://bz.apache.org/bugzilla/show_bug.cgi?id=43054) - SSLManager causes stress tests to saturate and crash (bug introduced in 2.3RC3) - Clarified HTTP Request Defaults usage of the port field - [Bug 43006](https://bz.apache.org/bugzilla/show_bug.cgi?id=43006) - NPE if icon.properties file not found - [Bug 42918](https://bz.apache.org/bugzilla/show_bug.cgi?id=42918) - Size Assertion now treats an empty response as having zero length - [Bug 43007](https://bz.apache.org/bugzilla/show_bug.cgi?id=43007) - Test ends before all threadgroups started - Fix possible NPE in HTTPSampler2 if 302 does not have Location header. - [Bug 42919](https://bz.apache.org/bugzilla/show_bug.cgi?id=42919) - Failure Message blank in CSV output [now records first non-blank message] - Add link to Extending JMeter PDF - Allow for quoted charset in Content-Type parsing - [Bug 39792](https://bz.apache.org/bugzilla/show_bug.cgi?id=39792) - ClientJMeter synchronisation needed - [Bug 43122](https://bz.apache.org/bugzilla/show_bug.cgi?id=43122) - GUI changes not always picked up when short-cut keys used (bug introduced in 2.3RC3) - [Bug 42947](https://bz.apache.org/bugzilla/show_bug.cgi?id=42947) - TestBeanGUI changes not picked up when short-cut keys used - Added serializer.jar (needed for update to xalan 2.7.0) - [Bug 38687](https://bz.apache.org/bugzilla/show_bug.cgi?id=38687) - Module controller does not work in non-GUI mode ##### Improvements since 2.3RC3 - Add stop thread option to CSV Dataset - Updated commons-httpclient to 3.1 - [Bug 28715](https://bz.apache.org/bugzilla/show_bug.cgi?id=28715) - allow variable cookie values (set CookieManager.allow_variable_cookies=false to disable) - [Bug 40873](https://bz.apache.org/bugzilla/show_bug.cgi?id=40873) - add JMS point-to-point non-persistent delivery option - [Bug 43283](https://bz.apache.org/bugzilla/show_bug.cgi?id=43283) - Save action adds .jmx if not present; checks for existing file on Save As - `Control + A` key does not work for Save All As; changed to `Control + Shift + S` - [Bug 40991](https://bz.apache.org/bugzilla/show_bug.cgi?id=40991) - Allow Assertions to check Headers #### Version 2.3RC3 ##### Known problems/restrictions: The JMeter remote server does not support multiple concurrent tests - each remote test should be run in a separate server. Otherwise tests may fail with random Exceptions, e.g. ConcurrentModification Exception in StandardJMeterEngine. See [Bug 43168](https://bz.apache.org/bugzilla/show_bug.cgi?id=43168). The default HTTP Request (not HTTPClient) sampler may not work for HTTPS connections via a proxy. This appears to be due to a Java bug, see [Bug 39337](https://bz.apache.org/bugzilla/show_bug.cgi?id=39337). To avoid the problem, try a more recent version of Java, or switch to the HTTPClient version of the HTTP Request sampler. Transaction Controller parent mode does not support nested Transaction Controllers. Doing so may cause a Null Pointer Exception in TestCompiler. Thread active counts are always zero in CSV and XML files when running remote tests. The property file_format.testlog=2.1 is treated the same as 2.2. However JMeter does honour the 3 testplan versions. [Bug 22510](https://bz.apache.org/bugzilla/show_bug.cgi?id=22510) - JMeter always uses the first entry in the keystore. Remote mode does not work if JMeter is installed in a directory where the path name contains spaces. BeanShell test elements leak memory. This can be reduced by using a file instead of including the script in the test element. Variables and functions do not work in Listeners in client-server (remote) mode so they cannot be used to name log files in client-server mode. CSV Dataset variables are defined after configuration processing is completed, so they cannot be used for other configuration items such as JDBC Config. (see [Bug 40394](https://bz.apache.org/bugzilla/show_bug.cgi?id=40394)) ##### Summary of changes (for more details, see below) Some of the main enhancements are: - Htmlparser 2.0 now used for parsing - HTTP Authorization now supports domain and realm - HttpClient options can be specified via httpclient.parameters file - HttpClient now behaves the same as Java Http for SSL certificates - HTTP Mirror Server to allow local testing of HTTP samplers - HTTP Proxy supports XML-RPC recording, and other proxy improvements - __V() function allows support of nested variable references - LDAP Ext sampler optionally parses result sets and supports secure mode - FTP Sampler supports Ascii/Binary mode and upload - Transaction Controller now optionally generates a Sample with subresults - HTTPS session contexts are now per-thread, rather than shared. This gives better emulation of multiple users - BeanShell elements now support ThreadListener and TestListener interfaces - Coloured icons in Tree View Listener and elsewhere to better differentiate failed samples. The main bug fixes are: - HTTPS (SSL) handling now much improved - Various Remote mode bugs fixed - `Control + C` and `Control + V` now work in the test tree - Latency and Encoding now available in CSV log output - Test elements no longer default to previous contents; test elements no longer cleared when changing language. ##### Incompatible changes (usage): N.B. The javax.net.ssl properties have been moved from jmeter.properties to system.properties, and will no longer work if defined in jmeter.properties. The new arrangement is more flexible, as it allows arbitrary system properties to be defined. SSL session contexts are now created per-thread, rather than being shared. This generates a more realistic load for HTTPS tests. The change is likely to slow down tests with many SSL threads. The original behaviour can be enabled by setting the JMeter property: ``` https.sessioncontext.shared=true ``` The LDAP Extended Sampler now uses the same panel for both Thread Bind and Single-Bind tests. This means that any tests using the Single-bind test will need to be updated to set the username and password. [Bug 41140](https://bz.apache.org/bugzilla/show_bug.cgi?id=41140): JMeterThread behaviour was changed so that PostProcessors are run in forward order (as they appear in the test plan) rather than reverse order as previously. The original behaviour can be restored by setting the following JMeter property: jmeterthread.reversePostProcessors=true The HTTP Authorization Manager now has extra columns for domain and realm, so the temporary work-round of using '\' and '@' in the username to delimit the domain and realm has been removed. `Control + Z` no longer used for Remote Start All - this now uses `Control + Shift + R` HttpClient now uses pre-emptive authentication. This can be changed by setting the following: ``` jmeter.properties: httpclient.parameters.file=httpclient.parameters httpclient.parameters: http.authentication.preemptive$Boolean=false ``` The port field in HTTP Request Defaults is no longer ignored for https samplers if it is set to 80. ##### Incompatible changes (development): **N.B.**The clear() method was defined in the following interfaces: Clearable, JMeterGUIComponent and TestElement. The methods serve different purposes, so two of them were renamed: the Clearable method is now clearData() and the JMeterGUIComponent method is now clearGui(). 3rd party add-ons may need to be rebuilt. Calculator and SamplingStatCalculator classes no longer provide any formatting of their data. Formatting should now be done using the jorphan.gui Renderer classes. Removed deprecated method JMeterUtils.split() - use JOrphanUtils version instead. Removed method saveUsingJPEGEncoder() from SaveGraphicsService. It was unused so far, and used the only Sun-specific class in JMeter. ##### New functionality/improvements: - Add Domain and Realm support to HTTP Authorization Manager - HttpClient now behaves the same as the JDK http sampler for invalid certificates etc - Added httpclient.parameters.file to allow HttpClient parameters to be defined - [Bug 33964](https://bz.apache.org/bugzilla/show_bug.cgi?id=33964) - Http Requests can send a file as the entire post body if name/type are omitted - [Bug 41705](https://bz.apache.org/bugzilla/show_bug.cgi?id=41705) - add content-encoding option to HTTP samplers for POST requests - [Bug 40933](https://bz.apache.org/bugzilla/show_bug.cgi?id=40933),[Bug 40945](https://bz.apache.org/bugzilla/show_bug.cgi?id=40945) - optional RE matching when retrieving embedded resource URLs - [Bug 27780](https://bz.apache.org/bugzilla/show_bug.cgi?id=27780) - (patch 19936) create multipart/form-data HTTP request without uploading file - [Bug 42098](https://bz.apache.org/bugzilla/show_bug.cgi?id=42098) - Use specified encoding for parameter values in HTTP GET - [Bug 42506](https://bz.apache.org/bugzilla/show_bug.cgi?id=42506) - JMeter threads now use independent SSL sessions - [Bug 41707](https://bz.apache.org/bugzilla/show_bug.cgi?id=41707) - HTTP Proxy XML-RPC support - [Bug 41880](https://bz.apache.org/bugzilla/show_bug.cgi?id=41880) - Add content-type filtering to HTTP Proxy Server - [Bug 41876](https://bz.apache.org/bugzilla/show_bug.cgi?id=41876) - Add more options to control what the HTTP Proxy generates - [Bug 42158](https://bz.apache.org/bugzilla/show_bug.cgi?id=42158) - Improve support for multipart/form-data requests in HTTP Proxy server - [Bug 42173](https://bz.apache.org/bugzilla/show_bug.cgi?id=42173) - Let HTTP Proxy handle encoding of request, and undecode parameter values - [Bug 42674](https://bz.apache.org/bugzilla/show_bug.cgi?id=42674) - default to pre-emptive HTTP authorisation if not specified - Support "file" protocol in HTTP Samplers - Http Autoredirects are now enabled by default when creating new samplers - [Bug 40103](https://bz.apache.org/bugzilla/show_bug.cgi?id=40103) - various LDAP enhancements - [Bug 40369](https://bz.apache.org/bugzilla/show_bug.cgi?id=40369) - LDAP: Stable search results in sampler - [Bug 40381](https://bz.apache.org/bugzilla/show_bug.cgi?id=40381) - LDAP: more descriptive strings - BeanShell Post-Processor no longer ignores samples with zero-length result data - Added beanshell.init.file property to run a BeanShell script at startup - [Bug 39864](https://bz.apache.org/bugzilla/show_bug.cgi?id=39864) - BeanShell init files now found from current or bin directory - BeanShell elements now support ThreadListener and TestListener interfaces - BSF Sampler passes additional variables to the script - Added timeout for WebService (SOAP) Sampler - [Bug 40825](https://bz.apache.org/bugzilla/show_bug.cgi?id=40825) - Add JDBC prepared statement support - Extend JDBC Sampler: Commit, Rollback, AutoCommit - [Bug 41457](https://bz.apache.org/bugzilla/show_bug.cgi?id=41457) - Add TCP Sampler option to not re-use connections - [Bug 41522](https://bz.apache.org/bugzilla/show_bug.cgi?id=41522) - Use JUnit sampler name in sample results - [Bug 42223](https://bz.apache.org/bugzilla/show_bug.cgi?id=42223) - FTP Sampler can now upload files - [Bug 40804](https://bz.apache.org/bugzilla/show_bug.cgi?id=40804) - Change Counter default to max = Long.MAX_VALUE - Use property jmeter.home (if present) to override user.dir when starting JMeter - New -j option to easily change jmeter log file - HTTP Mirror Server Workbench element - [Bug 41253](https://bz.apache.org/bugzilla/show_bug.cgi?id=41253) - extend XPathExtractor to work with non-NodeList XPath expressions - [Bug 42088](https://bz.apache.org/bugzilla/show_bug.cgi?id=42088) - Add XPath Assertion for booleans - Added __V variable function to resolve nested variable names - [Bug 40369](https://bz.apache.org/bugzilla/show_bug.cgi?id=40369) - Equals Response Assertion - [Bug 41704](https://bz.apache.org/bugzilla/show_bug.cgi?id=41704) - Allow charset encoding to be specified for CSV DataSet - [Bug 41259](https://bz.apache.org/bugzilla/show_bug.cgi?id=41259) - Comment field added to all test elements - Add standard deviation to Summary Report - [Bug 41873](https://bz.apache.org/bugzilla/show_bug.cgi?id=41873) - Add name to AssertionResult and display AssertionResult in ViewResultsFullVisualizer - [Bug 36755](https://bz.apache.org/bugzilla/show_bug.cgi?id=36755) - Save XML test files with UTF-8 encoding - Use ISO date-time format for Tree View Listener (previously the year was not shown) - Improve loading of CSV files: if possible, use header to determine format; guess timestamp format if not milliseconds - [Bug 41913](https://bz.apache.org/bugzilla/show_bug.cgi?id=41913) - TransactionController now creates samples as sub-samples of the transaction - [Bug 42582](https://bz.apache.org/bugzilla/show_bug.cgi?id=42582) - JSON pretty printing in Tree View Listener - [Bug 40099](https://bz.apache.org/bugzilla/show_bug.cgi?id=40099) - Enable use of object variable in ForEachController - [Bug 39693](https://bz.apache.org/bugzilla/show_bug.cgi?id=39693) - View Result Table uses icon instead of check box - [Bug 39717](https://bz.apache.org/bugzilla/show_bug.cgi?id=39717) - use icons in the results tree - [Bug 42247](https://bz.apache.org/bugzilla/show_bug.cgi?id=42247) - improve HCI - Allow user to cancel out of Close dialogue ##### Non-functional improvements: - Functor calls can now be unit tested - Replace com.sun.net classes with javax.net - Extract external jar definitions into build.properties file - Use specific jar names in build classpaths so errors are detected sooner - Tidied up ORO calls; now only one cache, size given by oro.patterncache.size, default 1000 - [Bug 42326](https://bz.apache.org/bugzilla/show_bug.cgi?id=42326) - Order of elements in .jmx files changes ##### External jar updates: - Htmlparser 2.0-20060923 - xstream 1.2.1/xpp3_min-1.1.3.4.O - Batik 1.6 - BSF 2.4.0 - commons-collections 3.2 - commons-httpclient-3.1-rc1 - commons-jexl 1.1 - commons-lang-2.3 (added) - JUnit 3.8.2 - velocity 1.5 - commons-io 1.3.1 (added) ##### Bug fixes: - [Bug 39773](https://bz.apache.org/bugzilla/show_bug.cgi?id=39773) - NTLM now needs local host name - fix other call - [Bug 40438](https://bz.apache.org/bugzilla/show_bug.cgi?id=40438) - setting "httpclient.localaddress" has no effect - [Bug 40419](https://bz.apache.org/bugzilla/show_bug.cgi?id=40419) - Chinese messages translation fix - [Bug 39861](https://bz.apache.org/bugzilla/show_bug.cgi?id=39861) - fix typo - [Bug 40562](https://bz.apache.org/bugzilla/show_bug.cgi?id=40562) - redirects no longer invoke RE post processors - [Bug 40451](https://bz.apache.org/bugzilla/show_bug.cgi?id=40451) - set label if not set by sampler - Fix NPE in CounterConfig.java in Remote mode - [Bug 40791](https://bz.apache.org/bugzilla/show_bug.cgi?id=40791) - Calculator used by Summary Report - [Bug 40772](https://bz.apache.org/bugzilla/show_bug.cgi?id=40772) - correctly parse missing fields in CSV log files - [Bug 40773](https://bz.apache.org/bugzilla/show_bug.cgi?id=40773) - XML log file timestamp not parsed correctly - [Bug 41029](https://bz.apache.org/bugzilla/show_bug.cgi?id=41029) - JMeter -t fails to close input JMX file - [Bug 40954](https://bz.apache.org/bugzilla/show_bug.cgi?id=40954) - Statistical mode in distributed testing shows wrong results - Fix ClassCast Exception when using sampler that returns null, e..g TestAction - [Bug 41140](https://bz.apache.org/bugzilla/show_bug.cgi?id=41140) - Post-processors are run in reverse order - [Bug 41277](https://bz.apache.org/bugzilla/show_bug.cgi?id=41277) - add Latency and Encoding to CSV output - [Bug 41414](https://bz.apache.org/bugzilla/show_bug.cgi?id=41414) - Mac OS X may add extra item to -jar classpath - Fix NPE when saving thread counts in remote testing - [Bug 34261](https://bz.apache.org/bugzilla/show_bug.cgi?id=34261) - NPE in HtmlParser (allow for missing attributes) - [Bug 40100](https://bz.apache.org/bugzilla/show_bug.cgi?id=40100) - check FileServer type before calling close - [Bug 39887](https://bz.apache.org/bugzilla/show_bug.cgi?id=39887) - jmeter.util.SSLManager: Couldn't load keystore error message - [Bug 41543](https://bz.apache.org/bugzilla/show_bug.cgi?id=41543) - exception when webserver returns "500 Internal Server Error" and content-length is 0 - [Bug 41416](https://bz.apache.org/bugzilla/show_bug.cgi?id=41416) - don't use chunked input for text-box input in SOAP-RPC sampler - [Bug 39827](https://bz.apache.org/bugzilla/show_bug.cgi?id=39827) - SOAP Sampler content length for files - Fix Class cast exception in Clear.java - [Bug 40383](https://bz.apache.org/bugzilla/show_bug.cgi?id=40383) - don't set content-type if already set - Mailer Visualiser test button now works if test plan has not yet been saved - [Bug 36959](https://bz.apache.org/bugzilla/show_bug.cgi?id=36959) - Shortcuts "ctrl c" and "ctrl v" don't work on the tree elements - [Bug 40696](https://bz.apache.org/bugzilla/show_bug.cgi?id=40696) - retrieve embedded resources from STYLE URL() attributes - [Bug 41568](https://bz.apache.org/bugzilla/show_bug.cgi?id=41568) - Problem when running tests remotely when using a 'Counter' - Fixed various classes that assumed timestamps were always end time stamps: - SamplingStatCalculator - JTLData - RunningSample - [Bug 40325](https://bz.apache.org/bugzilla/show_bug.cgi?id=40325) - allow specification of proxyuser and proxypassword for WebServiceSampler - Change HttpClient proxy definition to use NTCredentials; added http.proxyDomain property for this - [Bug 40371](https://bz.apache.org/bugzilla/show_bug.cgi?id=40371) - response assertion "pattern to test" scrollbar problem - [Bug 40589](https://bz.apache.org/bugzilla/show_bug.cgi?id=40589) - Unescape XML entities in embedded URLs - [Bug 41902](https://bz.apache.org/bugzilla/show_bug.cgi?id=41902) - NPE in HTTPSampler when responseCode = -1 - [Bug 41903](https://bz.apache.org/bugzilla/show_bug.cgi?id=41903) - ViewResultsFullVisualizer : status column looks bad when you do copy and paste - [Bug 41837](https://bz.apache.org/bugzilla/show_bug.cgi?id=41837) - Parameter value corruption in proxy - [Bug 41905](https://bz.apache.org/bugzilla/show_bug.cgi?id=41905) - Can't cut/paste/select Header Manager fields in Java 1.6 - [Bug 41928](https://bz.apache.org/bugzilla/show_bug.cgi?id=41928) - Make all request headers sent by HTTP Request sampler appear in sample result - [Bug 41944](https://bz.apache.org/bugzilla/show_bug.cgi?id=41944) - Subresults not handled recursively by ResultSaver - [Bug 42022](https://bz.apache.org/bugzilla/show_bug.cgi?id=42022) - HTTPSampler does not allow multiple headers of same name - [Bug 42019](https://bz.apache.org/bugzilla/show_bug.cgi?id=42019) - Content type not stored in redirected HTTP request with subresults - [Bug 42057](https://bz.apache.org/bugzilla/show_bug.cgi?id=42057) - connection can be null if method is null - [Bug 41518](https://bz.apache.org/bugzilla/show_bug.cgi?id=41518) - JMeter changes the HTTP header Content Type for POST request - [Bug 42156](https://bz.apache.org/bugzilla/show_bug.cgi?id=42156) - HTTPRequest HTTPClient incorrectly urlencodes parameter value in POST - [Bug 42184](https://bz.apache.org/bugzilla/show_bug.cgi?id=42184) - Number of bytes for subsamples not added to sample when sub samples are added - [Bug 42185](https://bz.apache.org/bugzilla/show_bug.cgi?id=42185) - If a HTTP Sampler follows a redirect, and is set up to download images, then images are downloaded multiple times - [Bug 39808](https://bz.apache.org/bugzilla/show_bug.cgi?id=39808) - Invalid redirect causes incorrect sample time - [Bug 42267](https://bz.apache.org/bugzilla/show_bug.cgi?id=42267) - Concurrent GUI update failure in Proxy Recording - [Bug 30120](https://bz.apache.org/bugzilla/show_bug.cgi?id=30120) - Name of simple controller is resetted if a new simple controller is added as child - [Bug 41078](https://bz.apache.org/bugzilla/show_bug.cgi?id=41078) - merge results in name change of test plan - [Bug 40077](https://bz.apache.org/bugzilla/show_bug.cgi?id=40077) - Creating new Elements copies values from Existing elements - [Bug 42325](https://bz.apache.org/bugzilla/show_bug.cgi?id=42325) - Implement the "clear" method for the LogicControllers - [Bug 25441](https://bz.apache.org/bugzilla/show_bug.cgi?id=25441) - TestPlan changes sometimes detected incorrectly (isDirty) - [Bug 39734](https://bz.apache.org/bugzilla/show_bug.cgi?id=39734) - Listeners shared after copy/paste operation - [Bug 40851](https://bz.apache.org/bugzilla/show_bug.cgi?id=40851) - Loop controller with 0 iterations, stops evaluating the iterations field - [Bug 24684](https://bz.apache.org/bugzilla/show_bug.cgi?id=24684) - remote startup problems if spaces in the path of the jmeter - Use Listener configuration when loading CSV data files - Function methods setParameters() need to be synchronized - Fix CLI long optional argument to require "=" (as for short options) - Fix SlowSocket to work properly with Httpclient (both http and https) - [Bug 41612](https://bz.apache.org/bugzilla/show_bug.cgi?id=41612) - Loop nested in If Controller behaves erratically - [Bug 42232](https://bz.apache.org/bugzilla/show_bug.cgi?id=42232) - changing language clears UDV contents - Jexl function did not allow variables #### Version 2.2 ##### Incompatible changes: The time stamp is now set to the sampler start time (it was the end). To revert to the previous behaviour, change the property **sampleresult.timestamp.start** to false (or comment it) The JMX output format has been simplified and files are not backwards compatible The JMeter.BAT file no longer changes directory to JMeter home, but runs from the current working directory. The jmeter-n.bat and jmeter-t.bat files change to the directory containing the input file. Listeners are now started slightly later in order to allow variable names to be used. This may cause some problems; if so define the following in jmeter.properties: jmeterengine.startlistenerslater=false The GUI now expands the tree by default when loading a test plan. This can be disabled by setting the JMeter property **onload.expandtree=false** ##### Known problems: - Post-processors run in reverse order (see [Bug 41140](https://bz.apache.org/bugzilla/show_bug.cgi?id=41140)) - Module Controller does not work in non-GUI mode - Aggregate Report and some other listeners use increasing amounts of memory as a test progresses - Does not always handle non-default encoding properly - Spaces in the installation path cause problems for client-server mode - Change of Language does not propagate to all test elements - SamplingStatCalculator keeps a List of all samples for calculation purposes; this can cause memory exhaustion in long-running tests - Does not properly handle server certificates if they are expired or not installed locally ##### New functionality: - Report function - XPath Extractor Post-Processor. Handles single and multiple matches. - Simpler JMX file format (2.2) - BeanshellSampler code can update ResponseData directly - [Bug 37490](https://bz.apache.org/bugzilla/show_bug.cgi?id=37490) - Allow UDV as delay in Duration Assertion - Slow connection emulation for HttpClient - Enhanced JUnitSampler so that by default assert errors and exceptions are not appended to the error message. Users must explicitly check append in the sampler - Enhanced the documentation for webservice sampler to explain how it works with CSVDataSet - Enhanced the documentation for javascript function to explain escaping comma - Allow CSV Data Set file names to be absolute - Report Tree compiler errors better - Don't reset Regex Extractor variable if default is empty - includecontroller.prefix property added - Regular Expression Extractor sets group count - Can now save entire screen as an image, not just the right-hand pane - [Bug 38901](https://bz.apache.org/bugzilla/show_bug.cgi?id=38901) - Add optional SOAPAction header to SOAP Sampler - New BeanShell test elements: Timer, PreProcessor, PostProcessor, Listener - __split() function now clears next variable, so it can be used with ForEach Controller - [Bug 38682](https://bz.apache.org/bugzilla/show_bug.cgi?id=38682) - add CallableStatement functionality to JDBC Sampler - Make it easier to change the RMI/Server port - Add property jmeter.save.saveservice.xml_pi to provide optional xml processing instruction in JTL files - Add bytes and URL to items that can be saved in sample log files (XML and CSV) - The Post-Processor "Save Responses to a File" now saves the generated file name with the sample, and the file name can be included in the sample log file. - Change jmeter.bat DOS script so it works from any directory - New -N option to define nonProxyHosts from command-line - New -S option to define system properties from input file - [Bug 26136](https://bz.apache.org/bugzilla/show_bug.cgi?id=26136) - allow configuration of local address - Expand tree by default when loading a test plan - can be disabled by setting property onload.expandtree=false - [Bug 11843](https://bz.apache.org/bugzilla/show_bug.cgi?id=11843) - URL Rewriter can now cache the session id - Counter Pre-Processor now supports formatted numbers - Add support for HEAD PUT OPTIONS TRACE and DELETE methods - Allow default HTTP implementation to be changed - Optionally save active thread counts (group and all) to result files - Variables/functions can now be used in Listener file names - New __time() function; define START.MS/START.YMD/START.HMS properties and variables - Add Thread Name to Tree and Table Views - Add debug functions: What class, debug on, debug off - Non-caching Calculator - used by Table Visualiser to reduce memory footprint - Summary Report - similar to Aggregate Report, but uses less memory - [Bug 39580](https://bz.apache.org/bugzilla/show_bug.cgi?id=39580) - recycle option for CSV Dataset - [Bug 37652](https://bz.apache.org/bugzilla/show_bug.cgi?id=37652) - support for Ajp Tomcat protocol - [Bug 39626](https://bz.apache.org/bugzilla/show_bug.cgi?id=39626) - Loading SOAP/XML-RPC requests from file - [Bug 39652](https://bz.apache.org/bugzilla/show_bug.cgi?id=39652) - Allow truncation of labels on AxisGraph - Allow use of htmlparser 1.6 - [Bug 39656](https://bz.apache.org/bugzilla/show_bug.cgi?id=39656) - always use SOAP action if it is provided - Automatically include properties from user.properties file - Add __jexl() function - evaluates Commons JEXL expressions - Optionally load JMeter properties from user.properties and system properties from system.properties. - [Bug 39707](https://bz.apache.org/bugzilla/show_bug.cgi?id=39707) - allow Regex match against URL - Add start time to Table Visualiser - HTTP Samplers can now extract embedded resources for any required media types ##### Bug fixes: - Fix NPE when no module selected in Module Controller - Fix NPE in XStream when no ResponseData present - Remove ?xml prefix when running with Java 1.5 and no x-jars - [Bug 37117](https://bz.apache.org/bugzilla/show_bug.cgi?id=37117) - setProperty() function should return ""; added optional return of original setting - Fix CSV output time format - [Bug 37140](https://bz.apache.org/bugzilla/show_bug.cgi?id=37140) - handle encoding better in RegexFunction - Load all cookies, not just the first; fix class cast exception - Fix default Cookie path name (remove page name) - Fixed resultcode attribute name - [Bug 36898](https://bz.apache.org/bugzilla/show_bug.cgi?id=36898) - apply encoding to RegexExtractor - Add properties for saving subresults, assertions, latency, samplerData, responseHeaders, requestHeaders & encoding - [Bug 37705](https://bz.apache.org/bugzilla/show_bug.cgi?id=37705) - Synch Timer now works OK after run is stopped - [Bug 37716](https://bz.apache.org/bugzilla/show_bug.cgi?id=37716) - Proxy request now handles file Post correctly - HttpClient Sampler now saves latency - Fix NPE when using JavaScript function on Test Plan - Fix Base Href parsing in htmlparser - [Bug 38256](https://bz.apache.org/bugzilla/show_bug.cgi?id=38256) - handle cookie with no path - [Bug 38391](https://bz.apache.org/bugzilla/show_bug.cgi?id=38391) - use long when accumulating timer delays - [Bug 38554](https://bz.apache.org/bugzilla/show_bug.cgi?id=38554) - Random function now uses long numbers - [Bug 35224](https://bz.apache.org/bugzilla/show_bug.cgi?id=35224) - allow duplicate attributes for LDAP sampler - [Bug 38693](https://bz.apache.org/bugzilla/show_bug.cgi?id=38693) - Webservice sampler can now use https protocol - [Bug 38646](https://bz.apache.org/bugzilla/show_bug.cgi?id=38646) - Regex Extractor now clears old variables on match failure - [Bug 38640](https://bz.apache.org/bugzilla/show_bug.cgi?id=38640) - fix WebService Sampler pooling - [Bug 38474](https://bz.apache.org/bugzilla/show_bug.cgi?id=38474) - HTML Link Parser doesn't follow frame links - [Bug 36430](https://bz.apache.org/bugzilla/show_bug.cgi?id=36430) - Counter now uses long rather than int to increase the range - [Bug 38302](https://bz.apache.org/bugzilla/show_bug.cgi?id=38302) - fix XPath function - [Bug 38748](https://bz.apache.org/bugzilla/show_bug.cgi?id=38748) - JDBC DataSourceElement fails with remote testing - [Bug 38902](https://bz.apache.org/bugzilla/show_bug.cgi?id=38902) - sometimes -1 seems to be returned unnecessarily for response code - [Bug 38840](https://bz.apache.org/bugzilla/show_bug.cgi?id=38840) - make XML Assertion thread-safe - [Bug 38681](https://bz.apache.org/bugzilla/show_bug.cgi?id=38681) - Include controller now works in non-GUI mode - Add write(OS,IS) implementation to TCPClientImpl - Sample Result converter saves response code as "rc". Previously it saved as "rs" but read with "rc"; it will now also read with "rc". The XSL stylesheets also now accept either "rc" or "rs" - Fix counter function so each counter instance is independent (previously the per-user counters were shared between instances of the function) - Fix TestBean Examples so that they work - Fix JTidy parser so it does not skip body tags with background images - Fix HtmlParser parser so it catches all background images - [Bug 39252](https://bz.apache.org/bugzilla/show_bug.cgi?id=39252) set SoapSampler sample result from XML data - [Bug 38694](https://bz.apache.org/bugzilla/show_bug.cgi?id=38694) - WebServiceSampler not setting data encoding correctly - Result Collector now closes input files read by listeners - [Bug 25505](https://bz.apache.org/bugzilla/show_bug.cgi?id=25505) - First HTTP sampling fails with "HTTPS hostname wrong: should be 'localhost'" - [Bug 25236](https://bz.apache.org/bugzilla/show_bug.cgi?id=25236) - remove double scrollbar from Assertion Result Listener - [Bug 38234](https://bz.apache.org/bugzilla/show_bug.cgi?id=38234) - Graph Listener divide by zero problem - [Bug 38824](https://bz.apache.org/bugzilla/show_bug.cgi?id=38824) - clarify behaviour of Ignore Status - [Bug 38250](https://bz.apache.org/bugzilla/show_bug.cgi?id=38250) - jmeter.properties "language" now supports country suffix, for zh_CN and zh_TW etc - jmeter.properties file is now closed after it has been read - [Bug 39533](https://bz.apache.org/bugzilla/show_bug.cgi?id=39533) - StatCalculator added wrong items - [Bug 39599](https://bz.apache.org/bugzilla/show_bug.cgi?id=39599) - ConcurrentModificationException - HTTPSampler2 now handles Auto and Follow redirects correctly - [Bug 29481](https://bz.apache.org/bugzilla/show_bug.cgi?id=29481) - fix reloading sample results so subresults not counted twice - [Bug 30267](https://bz.apache.org/bugzilla/show_bug.cgi?id=30267) - handle AutoRedirects properly - [Bug 39677](https://bz.apache.org/bugzilla/show_bug.cgi?id=39677) - allow for space in JMETER_BIN variable - Use Commons HttpClient cookie parsing and management. Fix various problems with cookie handling. - [Bug 39773](https://bz.apache.org/bugzilla/show_bug.cgi?id=39773) - NTCredentials needs host name ##### Other changes - Updated to HTTPClient 3.0 (from 2.0) - Updated to Commons Collections 3.1 - Improved formatting of Request Data in Tree View - Expanded user documentation - Added MANIFEST, NOTICE and LICENSE to all jars - Extract htmlparser interface into separate jarfile to make it possible to replace the parser - Removed SQL Config GUI as no longer needed (or working!) - HTTPSampler no longer logs a warning for Page not found (404) - StringFromFile now callable as __StringFromFile (as well as _StringFromFile) - Updated to Commons Logging 1.1 --- #### Version 2.1.1 ##### New functionality: - New Include Controller allows a test plan to reference an external jmx file - New JUnitSampler added for using JUnit Test classes - New Aggregate Graph listener is capable of graphing aggregate statistics - Can provide additional classpath entries using the property user.classpath and on the Test Plan element ##### Bug fixes: - AccessLog Sampler and JDBC test elements populated correctly from 2.0 test plans - BSF Sampler now populates filename and parameters from saved test plan - [Bug 36500](https://bz.apache.org/bugzilla/show_bug.cgi?id=36500) - handle missing data more gracefully in WebServiceSampler - [Bug 35546](https://bz.apache.org/bugzilla/show_bug.cgi?id=35546) - add merge to right-click menu - [Bug 36642](https://bz.apache.org/bugzilla/show_bug.cgi?id=36642) - Summariser stopped working in 2.1 - [Bug 36618](https://bz.apache.org/bugzilla/show_bug.cgi?id=36618) - CSV header line did not match saved data - JMeter should now run under JVM 1.3 (but does not build with 1.3) #### Version 2.1 ##### New functionality: - New Test Script file format - smaller, more compact, more readable - New Sample Result file format - smaller, more compact - XSchema Assertion - XML Tree display - CSV DataSet Config item - New JDBC Connection Pool Config Element - Synchronisation Timer - setProperty function - Save response data on error - Ant JMeter XSLT now optionally shows failed responses and has internal links - Allow JavaScript variable name to be omitted - Changed following Samplers to set sample label from sampler name - All Test elements can be saved as a graphics image to a file - [Bug 35026](https://bz.apache.org/bugzilla/show_bug.cgi?id=35026) - add RE pattern matching to Proxy - [Bug 34739](https://bz.apache.org/bugzilla/show_bug.cgi?id=34739) - Enhance constant Throughput timer - [Bug 25052](https://bz.apache.org/bugzilla/show_bug.cgi?id=25052) - use response encoding to create comparison string in Response Assertion - New optional icons - Allow icons to be defined via property files - New stylesheets for 2.1 format XML test output - Save samplers, config element and listeners as PNG - Enhanced support for WSDL processing - New JMS sampler for topic and queue messages - How-to for JMS samplers - [Bug 35525](https://bz.apache.org/bugzilla/show_bug.cgi?id=35525) - Added Spanish localisation - [Bug 30379](https://bz.apache.org/bugzilla/show_bug.cgi?id=30379) - allow server.rmi.port to be overridden - enhanced the monitor listener to save the calculated stats - Functions and variables now work at top level of test plan ##### Bug fixes: - [Bug 34586](https://bz.apache.org/bugzilla/show_bug.cgi?id=34586) - XPath always remained as / - BeanShellInterpreter did not handle null objects properly - Fix Chinese resource bundle names - Save field names if required to CSV files - Ensure XML file is closed - Correct icons now displayed for TestBean components - Allow for missing optional jar(s) in creating menus - Changed Samplers to set sample label from sampler name as was the case for HTTP - Fix various samplers to avoid NPEs when incomplete data is provided - Fix Cookie Manager to use seconds; add debug - [Bug 35067](https://bz.apache.org/bugzilla/show_bug.cgi?id=35067) - set up filename when using -t option - Don't substitute TestElement.* properties by UDVs in Proxy - [Bug 35065](https://bz.apache.org/bugzilla/show_bug.cgi?id=35065) - don't save old extensions in File Saver - [Bug 25413](https://bz.apache.org/bugzilla/show_bug.cgi?id=25413) - don't enable Restart button unnecessarily - [Bug 35059](https://bz.apache.org/bugzilla/show_bug.cgi?id=35059) - Runtime Controller stopped working - Clear up any left-over connections created by LDAP Extended Sampler - [Bug 23248](https://bz.apache.org/bugzilla/show_bug.cgi?id=23248) - module controller didn't remember stuff between save and reload - Fix Chinese locales - [Bug 29920](https://bz.apache.org/bugzilla/show_bug.cgi?id=29920) - change default locale if necessary to ensure default properties are picked up when English is selected. - Bug fixes for Tomcat monitor captions - Fixed webservice sampler so it works with user defined variables - Fixed screen borders for LDAP config GUI elements - [Bug 31184](https://bz.apache.org/bugzilla/show_bug.cgi?id=31184) - make sure encoding is specified in JDBC sampler - TCP sampler - only share sockets with same host:port details; correct the manual - Extract src attribute for embed tags in JTidy and Html Parsers #### Version 2.0.3 ##### New functionality: - XPath Assertion and XPath Function - Switch Controller - ForEach Controller can now loop through sets of groups - Allow CSVRead delimiter to be changed (see jmeter.properties) - [Bug 33920](https://bz.apache.org/bugzilla/show_bug.cgi?id=33920) - allow additional property files - [Bug 33845](https://bz.apache.org/bugzilla/show_bug.cgi?id=33845) - allow direct override of Home dir ##### Bug fixes: - Regex Extractor nested constant not put in correct place [Bug 32395](https://bz.apache.org/bugzilla/show_bug.cgi?id=32395) - Start time reset to now if necessary so that delay works OK. - Missing start/end times in scheduler are assumed to be now, not 1970 - [Bug 28661](https://bz.apache.org/bugzilla/show_bug.cgi?id=28661) - 304 responses not appearing in listeners - DOS scripts now handle different disks better - [Bug 32345](https://bz.apache.org/bugzilla/show_bug.cgi?id=32345) - HTTP Rewriter does not work with HTTP Request default - Catch Runtime Exceptions so an error in one Listener does not affect others - [Bug 33467](https://bz.apache.org/bugzilla/show_bug.cgi?id=33467) - __threadNum() extracted number wrongly - [Bug 29186](https://bz.apache.org/bugzilla/show_bug.cgi?id=29186),33299 - fix CLI parsing of "-" in second argument - Fix CLI parse bug: -D arg1=arg2. Log more startup parameters. - Fix JTidy and HTMLParser parsers to handle form src= and link rel=stylesheet - JMeterThread now logs Errors to jmeter.log which were appearing on console - Ensure WhileController condition is dynamically checked - [Bug 32790](https://bz.apache.org/bugzilla/show_bug.cgi?id=32790) ensure If Controller condition is re-evaluated each time - [Bug 30266](https://bz.apache.org/bugzilla/show_bug.cgi?id=30266) - document how to display proxy recording responses - [Bug 33921](https://bz.apache.org/bugzilla/show_bug.cgi?id=33921) - merge should not change file name - Close file now gives chance to save changes - [Bug 33559](https://bz.apache.org/bugzilla/show_bug.cgi?id=33559) - fixes to Runtime Controller ##### Other changes: - To help with variable evaluation, JMeterThread sets "sampling started" a bit earlier (see jmeter.properties) - [Bug 33796](https://bz.apache.org/bugzilla/show_bug.cgi?id=33796) - delete cookies with null/empty values - Better checking of parameter count in JavaScript function - Thread Group now defaults to 1 loop instead of forever - All Beanshell access is now via a single class; only need BSH jar at run-time - [Bug 32464](https://bz.apache.org/bugzilla/show_bug.cgi?id=32464) - document Direct Draw settings in jmeter.bat - [Bug 33919](https://bz.apache.org/bugzilla/show_bug.cgi?id=33919) - increase Counter field sizes - [Bug 32252](https://bz.apache.org/bugzilla/show_bug.cgi?id=32252) - ForEach was not initialising counters #### Version 2.0.2 ##### New functionality: - While Controller - BeanShell initialisation scripts - Result Saver can optionally save failed results only - Display as HTML has option not to download frames and images etc - Multiple Tree elements can now be enabled/disabled/copied/pasted at once - __split() function added - [Bug 28699](https://bz.apache.org/bugzilla/show_bug.cgi?id=28699) allow Assertion to regard unsuccessful responses - e.g. 404 - as successful - [Bug 29075](https://bz.apache.org/bugzilla/show_bug.cgi?id=29075) Regex Extractor can now extract data out of http response header as well as the body - __log() functions can now write to stdout and stderr - URL Modifier can now optionally ignore query parameters ##### Bug fixes: - If controller now works after the first false condition [Bug 31390](https://bz.apache.org/bugzilla/show_bug.cgi?id=31390) - Regex GUI was losing track of Header/Body checkbox [Bug 29853](https://bz.apache.org/bugzilla/show_bug.cgi?id=29853) - Display as HTML now handles frames and relative images - Right-click open replaced by merge - Fix some drag and drop problems - Fixed foreach demo example so it works - [Bug 30741](https://bz.apache.org/bugzilla/show_bug.cgi?id=30741) SSL password prompt now works again - StringFromFile now closes files at end of test; start and end now optional as intended - [Bug 31342](https://bz.apache.org/bugzilla/show_bug.cgi?id=31342) Fixed text of SOAP Sampler headers - Proxy must now be stopped before it can be removed [Bug 25145](https://bz.apache.org/bugzilla/show_bug.cgi?id=25145) - Link Parser now supports BASE href [Bug 25490](https://bz.apache.org/bugzilla/show_bug.cgi?id=25490) - [Bug 30917](https://bz.apache.org/bugzilla/show_bug.cgi?id=30917) Classfinder ignores duplicate names - [Bug 22820](https://bz.apache.org/bugzilla/show_bug.cgi?id=22820) Allow Counter value to be cleared - [Bug 28230](https://bz.apache.org/bugzilla/show_bug.cgi?id=28230) Fix NPE in HTTP Sampler retrieving embedded resources - Improve handling of StopTest; catch and log some more errors - ForEach Controller no longer runs any samples if first variable is not defined - [Bug 28663](https://bz.apache.org/bugzilla/show_bug.cgi?id=28663) NPE in remote JDBC execution - [Bug 30110](https://bz.apache.org/bugzilla/show_bug.cgi?id=30110) Deadlock in stopTest processing - [Bug 31696](https://bz.apache.org/bugzilla/show_bug.cgi?id=31696) Duration not working correctly when using Scheduler - JMeterContext now uses ThreadLocal - should fix some potential NPE errors #### Version 2.0.1 Bug fix release. TBA. #### Version 2.0 - HTML parsing improved; now has choice of 3 parsers, and most embedded elements can now be detected and downloaded. - Redirects can now be delegated to URLConnection by defining the JMeter property HTTPSamper.delegateRedirects=true (default is false) - Stop Thread and Stop Test methods added for Samplers and Assertions etc. Samplers can call setStopThread(true) or setStopTest(true) if they detect an error that needs to stop the thread of the test after the sample has been processed - Thread Group Gui now has an extra pane to specify what happens after a Sampler error: Continue (as now), Stop Thread or Stop Test. This needs to be extended to a lower level at some stage. - Added Shutdown to Run Menu. This is the same as Stop except that it lets the Threads finish normally (i.e. after the next sample has been completed) - Remote samples can be cached until the end of a test by defining the property hold_samples=true when running the server. More work is needed to be able to control this from the GUI - Proxy server has option to skip recording browser headers - Proxy restart works better (stop waits for daemon to finish) - Scheduler ignores start if it has already passed - Scheduler now has delay function - added Summariser test element (mainly for non-GUI) testing. This prints summary statistics to System.out and/or the log file every so often (3 minutes by default). Multiple summarisers can be used; samples are accumulated by summariser name. - Extra Proxy Server options: Create all samplers with keep-alive disabled Add Separator markers between sets of samples Add Response Assertion to first sampler in each set - Test Plan has a comment field - Help Page can now be pushed to background - Separate Function help page - New / amended functions - New / amended Assertions - If Controller (not fully functional yet) - Transaction Controller (aggregates the times of its children) - New Samplers - Optionally start BeanShell server (allows remote access to JMeter variables and methods) #### Version 1.9.1 TBA #### Version 1.9 - Sample result log files can now be in CSV or XML format - New Event model for notification of iteration events during test plan run - New Javascript function for executing arbitrary javascript statements - Many GUI improvements - New Pre-processors and Post-processors replace Modifiers and Response-Based Modifiers. - Compatible with jdk1.3 - JMeter functions are now fully recursive and universal (can use functions as parameters to functions) - Integrated help window now supports hypertext links - New Random Function - New XML Assertion - New LDAP Sampler (alpha code) - New Ant Task to run JMeter (in extras folder) - New Java Sampler test implementation (to assist developers) - More efficient use of memory, faster loading of .jmx files - New SOAP Sampler (alpha code) - New Median calculation in Graph Results visualizer - Default config element added for developer benefit - Various performance enhancements during test run - New Simple File recorder for minimal GUI overhead during test run - New Function: StringFromFile - grabs values from a file - New Function: CSVRead - grabs multiple values from a file - Functions now longer need to be encoded - special values should be escaped with "\" if they are literal values - New cut/copy/paste functionality - SSL testing should work with less user-fudging, and in non-gui mode - Mailer Model works in non-gui mode - New Throughput Controller - New Module Controller - Tests can now be scheduled to run from a certain time till a certain time - Remote JMeter servers can be started from a non-gui client. Also, in gui mode, all remote servers can be started with a single click - ThreadGroups can now be run either serially or in parallel (default) - New command line options to override properties - New Size Assertion #### Version 1.8.1 - Bug Fix Release. Many bugs were fixed. - Removed redundant "Root" node from test tree. - Re-introduced Icons in test tree. - Some re-organization of code to improve build process. - View Results Tree has added option to view results as web document (still buggy at this point). - New Total line in Aggregate Listener (still buggy at this point). - Improvements to ability to change JMeter's Locale settings. - Improvements to SSL Manager. #### Version 1.8 - Improvement to Aggregate report's calculations. - Simplified application logging. - New Duration Assertion. - Fixed and improved Mailer Visualizer. - Improvements to HTTP Sampler's recovery of resources (sockets and file handles). - Improving JMeter's internal handling of test start/stop. - Fixing and adding options to behavior of Interleave and Random Controllers. - New Counter config element. - New User Parameters config element. - Improved performance of file opener. - Functions and other elements can access global variables. - Help system available within JMeter's GUI. - Test Elements can be disabled. - Language/Locale can be changed while running JMeter (mostly). - View Results Tree can be configured to record only errors. - Various bug fixes. #### Version 1.7.3 - New Functions that provide more ability to change requests dynamically during test runs. - New language translations in Japanese and German. - Removed annoying Log4J error messages. - Improved support for loading JMeter 1.7 version test plan files (.jmx files). - JMeter now supports proxy servers that require username/password authentication. - Dialog box indicating test stopping doesn't hang JMeter on problems with stopping test. - GUI can run multiple remote JMeter servers (fixes GUI bug that prevented this). - Dialog box to help created function calls in GUI. - New Keep-alive switch in HTTP Requests to indicate JMeter should or should not use Keep-Alive for sockets. - HTTP Post requests can have GET style arguments in Path field. Proxy records them correctly now. - New User-defined test-wide static variables. - View Results Tree now displays more information, including name of request (matching the name in the test tree) and full request and POST data. - Removed obsolete View Results Visualizer (use View Results Tree instead). - Performance enhancements. - Memory use enhancements. - Graph visualizer GUI improvements. - Updates and fixes to Mailer Visualizer. #### Version 1.7.2 - JMeter now notifies user when test has stopped running. - HTTP Proxy server records HTTP Requests with re-direct turned off. - HTTP Requests can be instructed to either follow redirects or ignore them. - Various GUI improvements. - New Random Controller. - New SOAP/XML-RPC Sampler. #### Version 1.7.1 - JMeter's architecture revamped for a more complete separation between GUI code and test engine code. - Use of Avalon code to save test plans to XML as Configuration Objects - All listeners can save data to file and load same data at later date. #### Version 1.7Beta - Better XML support for special characters (Tushar Bhatia) - Non-GUI functioning & Non-GUI test plan execution (Tushar Bhatia) - Removing Swing dependence from base JMeter classes - Internationalization (Takashi Okamoto) - AllTests bug fix (neth6@atozasia.com) - ClassFinder bug fix (neth6@atozasia.com) - New Loop Controller - Proxy Server records HTTP samples from browser (and documented in the user manual) - Multipart Form support - HTTP Header class for Header customization - Extracting HTTP Header information from responses (Jamie Davidson) - Mailer Visualizer re-added to JMeter - JMeter now url encodes parameter names and values - listeners no longer give exceptions if their gui's haven't been initialized - HTTPS and Authorization working together - New Http sampling that automatically parses HTML response for images to download, and includes the downloading of these images in total time for request (Neth neth6@atozasia.com) - HTTP responses from server can be parsed for links and forms, and dynamic data can be extracted and added to test samples at run-time (documented) - New Ramp-up feature (Jonathan O'Keefe) - New visualizers (Neth) - New Assertions for functional testing #### Version 1.6.1 - Fixed saving and loading of test scripts (no more extra lines) - Can save and load special characters (such as "&" and "<"). - Can save and load timers and listeners. - Minor bug fix for cookies (if you cookie value contained an "=", then it broke). - URL's can sample ports other than 80, and can test HTTPS, provided you have the necessary jars (JSSE) #### Version 1.6 Alpha - New UI - Separation of GUI and Logic code - New Plug-in framework for new modules - Enhanced performance - Layering of test logic for greater flexibility - Added support for saving of test elements - Added support for distributed testing using a single client #### Version 1.5.1 - Fixed bug that caused cookies not to be read if header name case not as expected. - Clone entries before sending to sampler - prevents relocations from messing up information across threads - Minor bug fix to convenience dialog for adding parameters to test sample. Bug prevented entries in dialog from appearing in test sample. - Added xerces.jar to distribution - Added junit.jar to distribution and created a few tests. - Started work on new framework. New files in cvs, but do not effect program yet. - Fixed bug that prevent HTTPJMeterThread from delaying according to chosen timer. #### Version 1.5 - Abstracted out the concept of the Sampler, SamplerController, and TestSample. A Sampler represents code that understands a protocol (such as HTTP, or FTP, RMI, SMTP, etc..). It is the code that actually makes the connection to whatever is being tested. A SamplerController represents code that understands how to organize and run a group of test samples. It is what binds together a Sampler and its test samples and runs them. A TestSample represents code that understands how to gather information from the user about a particular test. For a website, it would represent a URL and any information to be sent with the URL. - The UI has been updated to make entering test samples more convenient. - Thread groups have been added, allowing a user to setup multiple test to run concurrently, and to allow sharing of test samples between those tests. - It is now possible to save and load test samples. - … and many more minor changes/improvements … **Apache JMeter 1.4.1-dev** - Cleaned up URLSampler code after tons of patches for better readability. (SM) - Made JMeter send a special "user-agent" identifier. (SM) - Fixed problems with redirection not sending cookies and authentication info and removed a warning with jikes compilation. Thanks to Wesley Tanaka for the patches (SM) - Fixed a bug in the URLSampler that caused to skip one URL when testing lists of URLs and a problem with Cookie handling. Thanks to Graham Johnson for the patches (SM) - Fixed a problem with POST actions. Thanks to Stephen Schaub for the patch (SM) **Apache JMeter 1.4** - Jul 11 1999 - Fixed a problem with POST actions. Thanks to Brendan Burns for the patch (SM) - Added close button to the About box for those window managers who don't provide it. Thanks to Jan-Henrik Haukeland for pointing it out. (SM) - Added the simple Spline sample visualizer (JPN) **Apache JMeter 1.3** - Apr 16 1999 - Run the Garbage Collector and run finalization before starting to sampling to ensure same state every time (SM) - Fixed some NullPointerExceptions here and there (SM) - Added HTTP authentication capabilities (RL) - Added windowed sample visualizer (SM) - Fixed stupid bug for command line arguments. Thanks to Jorge Bracer for pointing this out (SM) **Apache JMeter 1.2** - Mar 17 1999 - Integrated cookie capabilities with JMeter (SM) - Added the Cookie manager and Netscape file parser (SD) - Fixed compilation error for JDK 1.1 (SD) **Apache JMeter 1.1** - Feb 24 1999 - Created the opportunity to create URL aliasing from the properties file as well as the ability to associate aliases to URL sequences instead of single URLs (SM) Thanks to Simon Chatfield for the very nice suggestions and code examples. - Removed the TextVisualizer and replaced it with the much more useful FileVisualizer (SM) - Added the known bug list (SM) - Removed the Java Apache logo (SM) - Fixed a couple of typos (SM) - Added UNIX makefile (SD) **Apache JMeter 1.0.1** - Jan 25 1999 - Removed pending issues doc issues (SM) - Fixed the unix script (SM) - Added the possibility of running the JAR directly using "java -jar ApacheJMeter.jar" with Java 2 (SM) - Some small updates: fixed Swing location after Java 2(tm) release, license update and small cleanups (SM) **Apache JMeter 1.0** - Dec 15 1998 - Initial version. (SM) {/* SYNCED-BODY:END */} --- Title: User's Manual: History/Future URL: https://docs.jmeter.ai/user-manual/history-future/ --- {/* SYNCED-BODY:START */} ## 25. History and Future ### 25.1 History Stefano Mazzocchi of the Apache Software Foundation was the original developer of JMeter. He wrote it primarily to test the performance of Apache JServ (a project that has since been replaced by the Apache Tomcat project). We redesigned JMeter to enhance the GUI and to add functional-testing capabilities. JMeter became a Top Level Apache project in November 2011, which means it has a Project Management Committee and a dedicated website. ### 25.2 The Future We hope to see JMeter's capabilities rapidly expand as developers take advantage of its pluggable architecture. The primary goal of further developments will be: - Support of HTTP/2 protocol - Possible rework of core architecture to introduce a pool of threads or switch to async model allowing us to take advantage of async io - Enhancements to Webservices protocols (REST / SOAP) - Enhancements to JMS protocol implementation - … :::note You can help us by contributing to JMeter through any piece of work, read [this document](/../building/) ::: {/* SYNCED-BODY:END */} --- Title: Building and Contributing to JMeter URL: https://docs.jmeter.ai/reference/building/ --- {/* SYNCED-BODY:START */} ## Building JMeter Before you can compile JMeter, you will need a few things: - a Java 17 compatible JDK (Java Development Kit) - Optional: [Gradle](https://gradle.org/) installation - the JMeter sources as shown in the next section #### Acquiring the source The official source releases of Apache JMeter can be downloaded from [download page](download_jmeter.cgi). #### Compiling and packaging JMeter using Gradle JMeter can be built entirely using Gradle. The basic command is: ``` ./gradlew build ``` See the list of available tasks via `./gradlew tasks` (or `./gradlew tasks --all`) for the other tasks that can be used. More detailed information about the available tasks can be found in [gradle.md](https://github.com/apache/jmeter/blob/master/gradle.md). #### Opening project via IntelliJ IDEA You require IntelliJ 2018.3.1 or newer. - Open the build.gradle.kts file with IntelliJ IDEA and choose "Open as Project" - Make sure "Create separate module per source set" is selected - Make sure "Use default gradle wrapper" is selected - In the "File already exists" dialogue, choose "Yes" to overwrite - In the "Open Project" dialogue, choose "Delete Existing Project and Import" #### Compiling and packaging JMeter using Eclipse ##### Option 1 : Importing Eclipse project via Eclipse's "import Gradle project" wizard Recent Eclipse versions can import Gradle projects automatically, so use **File → Import...** Then choose **Existing Gradle Project** and proceed with the import. ##### Option 2 : Setting up Eclipse project with Gradle task Once you have downloaded the sources, you can setup the Eclipse project by running: ``` ./gradlew eclipse ``` You can then import the project using **File → Import → Existing projects into Workspace** and select the folder containing JMeter sources. ## Contributing to JMeter ### We love contribution We are very grateful to you if you take some time to contribute to the project. If you have some time to spend on the project you can pick existing enhancement or bug from [Issues page](/reference/issues/). You can also contribute to translation, see [JMeter Localisation (Translator's Guide)](/localising/index/). ### Submitting a patch If you want to contribute to JMeter for a bug fix or enhancement, here is the procedure to follow: #### Check your patch Before submitting your patch ensure you do the following: Check that patch compiles and follows Tab space policy by running: ``` ./gradlew check ``` Check that patch does not break JUnit tests by running: ``` ./gradlew test ``` #### Create a pull request using Git - Fork [Apache JMeter mirror](https://www.github.com/apache/jmeter) - Clone your forked repository locally: ``` git clone https://github.com/yourid/jmeter.git ``` - Create a branch using for example issue id: ``` git branch gh123-thread-group-typo ``` (please refrain from using ``` master ``` and ``` main ``` branches for pull request) - Checkout the new branch: ``` git checkout gh123-thread-group-typo ``` - Commit your fix there: ``` git commit -m 'Fix to BUGID' list of files ``` - Please avoid creating merge commits in the PR. We embrace small changes, and merge commits are harder to review - Push it: ``` git push origin gh123-thread-group-typo ``` - Create a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) :::note Different operating systems have different defaults for end-of-line markers. Typical configuration is CRLF for Windows and LF for macOS and GNU/Linux. It is recommended to follow that configuration by appropriate settings of `core.autocrlf`. For Windows ``` git config --global core.autocrlf true ``` , and for macOS and GNU/Linux set ``` git config --global core.autocrlf input ``` Git will automatically recognize text files in the repository thanks to `.gitattributes`, and Git will convert line endings for text files to the appropriate platform-native format (according to `core.autocrlf`) Certain files (e.g. `*.sh` or `*.bat`) have predefined end of line policy no matter the configuration of the developer workstation. ::: #### Proposing a change with a patch If you cannot to create a pull request at GitHub, you might submit your changes as a unified diff patch on JMeter dev mailing list. - Checkout Apache JMeter source - Code your fix - Create your patch by Right clicking on Eclipse project and select **Team → Create Patch …** - Attach your patch to email message on JMeter dev list ## Automated builds ### Automated (nightly) builds As part of the development process, the JMeter project has access to various Continuous Integration (CI) server builds. The build output can be useful for testing recent changes to the code-base. Please note that the builds have not undergone any QA and should only be used for development testing. For further information, see the [Nightly builds for developers](/nightly/) page. ## Building Add-Ons ### Building Add-Ons There is no need to build JMeter if you just want to build an add-on. Just download the binary archive and add the jars to the classpath or use Maven artifacts to build your add-ons. You may want to also download the source so it can be used by the IDE. See the `extras/addons*` files in the source tree for some suggestions {/* SYNCED-BODY:END */} --- Title: User guide: Customizables templates URL: https://docs.jmeter.ai/reference/creating-templates/ --- {/* SYNCED-BODY:START */} ## Customizable template This document describes how to create a customizable template. ### 1 Folder structure The template feature uses the bin/templates folder which contains : - templates.xml, the file where you declare the templates you want to be able to use - some .jmx and .jmx.fmkr files which are the templates Here is how it looks like: ![Figure 1 - template folder](/images/screenshots/templates/template_folder.png) _Figure 1 - template folder_ ### 2 Template declaration #### 2.1 Basic template declaration First of all you must declare your template. To do that, look into the templates.xml file. This file respect a DTD Below is the already existing Recording template declaration inside the templates.xml : ![Figure 2 - recording template declaration](/images/screenshots/templates/templates_xml.png) _Figure 2 - recording template declaration_ A template declaration is made as follow : - `template` element which contains the information described in the following tags - `name` element which contains the template name the user will see - `fileName` element which contains the relative path of the template. - `description` element which uses html to describe the template - `optional` parameters tag (will be discussed later) #### 2.2 Customizable template declaration Let's say we want the exact same Recording template as in the 2.1 section, but we want to choose the name of the xml file where the recording of view result tree will be saved. To do so we will use the parameters tag to tell JMeter to ask the user about a name for the concerned file : ![Figure 3 - recording template with parameters](/images/screenshots/templates/templates_xml_parameters.png) _Figure 3 - recording template with parameters_ :::note You can put as many parameter tags as you want in the parameters tag. ::: Let's see what changed here. Firstly, customs templates are `.jmx.fmkr` files and not only `.jmx`. Lastly, we added a `parameters` tag. As you can see in the image, a `parameters` tag contains `parameter` tags. Parameter tags are empty and contains 2 attributes : - `key` is the name of the parameter you will ask the user to fill. - `defaultValue` is as its name says, the default value the user will see for the parameter. ### 3 Template file #### 3.1 Basic template file The template file is the one you used in the fileName tag when you declared your template. A template file is just the saving of a JMeter test plan. #### 3.2 Customizable template file In the 2.2 section we saw that a custom template file is a .jmx.fmkr file. The single difference between them is the .jmx.fmkr will be analyzed by JMeter to detect customs tag. If a custom tag is found, JMeter will try to replace it by the corresponding given value from the user. A custom tag is defined as follow : ``` [object Object] ``` This is based on [Freemarker alternative Interpolation syntax](https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html#dgui_misc_alternativesyntax_interpolation). Let's illustrate how it works with an example. Consider the following part of the recording.jmx template file : ![Figure 4 - recording.jmx save file](/images/screenshots/templates/template_recording_filename.png) _Figure 4 - recording.jmx save file_ The surrounded area correspond to the name of the xml file where the View Results Tree output will be saved. As it is, when you use the template you will always have the same saving filename : `recording.xml`. To make it customizable, change your recording template declaration in the templates.xml files by the one shown in the 2.2 section. Then, rename the recording.jmx file to recording.jmx.fmkr. When it's done, Change the above selected line by this one : ``` [object Object] ``` It's over ! With this configuration, if you chose to use the recording template, JMeter will ask you a xmlFileName (correspond to the key value in the declaration). ![Figure 5 - JMeter asks you the value you want to put for the key](/images/screenshots/templates/template_parameters_window.png) _Figure 5 - JMeter asks you the value you want to put for the key_ Then, you will find the expected value in the created template where you placed the [=xmlFileName] tag : ![Figure 6 - the value changed](/images/screenshots/templates/template_recording_retrieved_value.png) _Figure 6 - the value changed_ {/* SYNCED-BODY:END */} --- Title: Download Apache JMeter URL: https://docs.jmeter.ai/reference/download-jmeter/ --- {/* SYNCED-BODY:START */} ## Download Apache JMeter We recommend you use a mirror to download our release builds, but you **must** [verify the integrity](http://www.apache.org/info/verification.html) of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from all the mirrors. You are currently using **[preferred]**. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are _backup_ mirrors (at the end of the mirrors list) that should be available. Other mirrors: The `KEYS` link links to the code signing keys used to sign the product. The `PGP` link downloads the OpenPGP compatible signature from our main site. The `SHA-512` link downloads the sha512 checksum from the main site. Please [verify the integrity](http://www.apache.org/info/verification.html) of the downloaded file. For more information concerning Apache JMeter, see the [Apache JMeter](http://jmeter.apache.org/) site. [KEYS](https://www.apache.org/dist/jmeter/KEYS) ## Apache JMeter &release; (Requires Java 17+) ### Binaries | | | | | --- | --- | --- | | [apache-jmeter-&release;.zip]([preferred]/jmeter/binaries/apache-jmeter-&release;.zip) | [sha512](https://www.apache.org/dist/jmeter/binaries/apache-jmeter-&release;.zip.sha512) | [pgp](https://www.apache.org/dist/jmeter/binaries/apache-jmeter-&release;.zip.asc) | ### Source | | | | | --- | --- | --- | | [apache-jmeter-&release;_src.zip]([preferred]/jmeter/source/apache-jmeter-&release;_src.zip) | [sha512](https://www.apache.org/dist/jmeter/source/apache-jmeter-&release;_src.zip.sha512) | [pgp](https://www.apache.org/dist/jmeter/source/apache-jmeter-&release;_src.zip.asc) | ## Archives Older releases can be obtained from the archives. - [browse download area]([preferred]/jmeter/) - [Apache JMeter archives…](https://archive.apache.org/dist/jmeter/) - [Apache Jakarta JMeter archives…](https://archive.apache.org/dist/jakarta/jmeter/) ## Verification of downloads It is essential that you verify the integrity of the downloaded files using the PGP signature. Please read [Verifying Apache Software Foundation Releases](http://www.apache.org/info/verification.html) for more information on why you should verify our releases. {/* SYNCED-BODY:END */} --- Title: Security URL: https://docs.jmeter.ai/reference/security/ --- {/* SYNCED-BODY:START */} ## Security Model {/* CUSTOM-INTRO:START */} :::caution[Security-sensitive setting] Treat `.jmx` files and distributed workers as trusted execution inputs. Opening or running a test plan can execute code through configured elements or scripts. ::: {/* CUSTOM-INTRO:END */} The purpose of JMeter is to execute the workload specified in the input jmx file, which may include arbitrary code. As such, the JMeter security model assumes you trust jmx input files: even opening a jmx input file may in some cases trigger code execution. If you want to use JMeter to evaluate untrusted jmx files, it is up to you to provide the required isolation. Still in the area of security, when JMeter is used in distributed environment, we recommend setting up the security manager in order to avoid any execution of malicious code on the distributed architecture. See the [Security-Manager documentation](/./usermanual/remote-test/#security-manager) for its implementation. ## Reporting security issues We strongly encourage you to report potential security vulnerabilities to our private security mailing list, [security@apache.org](mailto:security@apache.org), before disclosing them in a public forum. Only use this list to report undisclosed security vulnerabilities in Apache projects and manage the process of fixing such vulnerabilities. We cannot accept regular bug reports or other security-related queries at these addresses. We will ignore mail sent to these addresses that does not relate to an undisclosed security problem in an Apache project. An overview of the vulnerability handling process is: - The reporter reports the vulnerability privately to Apache. - The appropriate project's security team works privately with the reporter to resolve the vulnerability. - The project creates a new release of the package the vulnerabilty affects to deliver its fix. - The project publicly announces the vulnerability and describes how to apply the fix. Committers should read a [more detailed description of the process](https://www.apache.org/security/committers.html). Reporters of security vulnerabilities may also find it useful. {/* SYNCED-BODY:END */} --- Title: Issues URL: https://docs.jmeter.ai/reference/issues/ --- {/* SYNCED-BODY:START */} ## Issue tracker JMeter uses GitHub Issues for issue tracking, i.e. for reporting bugs and requesting enhancements. Previously, the issues were tracked in [Bugzilla](https://bz.apache.org/bugzilla/describecomponents.cgi), and all the issues, comments, and attachments have been migrated to GitHub on 2022-09-22. ## Support Questions Please do not use GitHub Issues for asking questions. It is not a support forum. Instead, please [subscribe](/mail2/) to the JMeter user mailing list and ask there. The user mailing list has a bigger audience, and you are more likely to get an answer quickly. ## Known Bugs and enhancements - [Most voted issues](https://github.com/apache/jmeter/issues?q=is%3Aopen+sort%3Areactions-%2B1-desc) - [All open bugs and enhancements](https://github.com/apache/jmeter/issues?q=is%3Aopen) - [Open bugs (excluding enhancements)](https://github.com/apache/jmeter/issues?q=is%3Aissue+is%3Aopen+-label%3Aenhancement) - [Enhancements only](https://github.com/apache/jmeter/issues?q=is%3Aopen+label%3Aenhancement) ## Requesting an enhancement Please check if the same enhancement has already been requested previously. If you find a very similar request in the issues list, please refrain from adding "_I also need this_" comments to the issue. "_I also need this_" comments cause notifications, and the comment itself does not add much to the discussion. Instead, prefer adding reactions to the first comment of an existing issue, so the issues could be sorted (see [Most voted issues](https://github.com/apache/jmeter/issues?q=sort%3Areactions-%2B1-desc)). Please make sure that you describe the enhancement in sufficient detail. It might be a good idea to start with a use-case. There are several options to propose an enhancement request: **GitHub issue** : You could [file an issue on GitHub](https://github.com/apache/jmeter/issues/new/choose) to start a discussion and gather opinions. GitHub issues allow [basic formatting](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax), [advanced formatting](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting), [attaching files](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/attaching-files), [syntax highlight](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#quoting-code), [task lists](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-task-lists), reactions, [references to the other issues and the source code](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls#issues-and-pull-requests). When you create an issue at GitHub, it suggests one of the templates (e.g. "_Bug report_", "_Feedback about the manual_", "_Feature Request_", "_Regression_"), and it guides which information is required for each case. You could read more on [creating issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue) in GitHub documentation. **Mailing list discussion** : If you are not sure if something is an enhancement, or if you are unsure regarding the possible solutions, it might be a good idea to start a discussion on [JMeter dev mailing list](https://jmeter.apache.org/mail2.html#JMeterDev) **GitHub pull request** : If you are positive regarding the solution, you could start a discussion by creating a [pull request on GitHub](https://github.com/apache/jmeter/pulls). Pull requests are not much different from issues, however, sometimes it is easier to discuss with code at hand. For instance, if you fix a typo or make other small fixes, there's no need to create "_issue and PR_" for each change. The following [GitHub post](https://github.blog/2015-01-21-how-to-write-the-perfect-pull-request/) might be helpful for creating your perfect pull request. :::note There's no guarantee that your contribution will be accepted, so it might be wise to discuss your suggestions before you invest significant efforts on implementing the changes. ::: If you are providing a code patch, also provide a test case, and documentation on how to use the new feature (ideally as a documentation patch). ## Raising an Issue First check that the issue has not already been reported on [GitHub issues](https://github.com/apache/jmeter/issues) and [JMeter user mailing list](https://lists.apache.org/list.html?user@jmeter.apache.org)). If reporting a bug, are you sure it really is a bug in JMeter, not just a misunderstanding of how JMeter works? If you face a bug or regression, please create an [issue on GitHub](https://github.com/apache/jmeter/issues). In case you can't create an issue, you might send the bug report to [JMeter dev mailing list](https://jmeter.apache.org/mail2.html#JMeterDev). ## Required Information for bug reporting Please make sure you provide sufficient information for others to be able to make use of the report effectively. Use the checklist below to guide you. - JMeter version - Java version (output from `java -version`) - OS version - `jmeter.log` file (unlikely to contain sensitive information, but check before uploading) - JMX file if relevant (redact any sensitive information first), providing a simplified Test Plan (using [Debug Sampler](/user-manual/component-reference/#Debug_Sampler)) will ensure BUG is fixed much more rapidly than without it - Try to reproduce the bug without third-party plug-ins. Minimal JMX files should not contain third-party plug-ins, as it makes it harder to test them on a plain JMeter installation. - JTL file if relevant (may need to redact sensitive information) - For a suspected bug, describe what you did, what happened, and how this differs from what you expected to happen. Does it happen every time? - If you have error messages, that you wish to report, copy them as text into the issue, as it makes it easier to search for them and re-use the message in our research for the origin of the issue - When a bug is market as `need info`, please provide as soon as possible the required information so that bug can be understood and fixed. Be aware that if no information is provided after team requires more information and bug is not reproducible, then bug will be closed as `invalid`. You can always ask to reopen it later once you provide the required information. - Prefer using issue templates (e.g. "_Bug report_", "_Feedback about the manual_", "_Feature Request_", "_Regression_") - If you are providing a patch file to fix a bug, please ensure it is in unified diff format. If using Eclipse, please set the patch root to "`Project`", not the default "`Workspace`" which is harder to apply. - New source files can be provided as is; please ensure they have the standard Apache License header (as per other JMeter files). Please do not use `@author` tags (credit will be given in the changes file). - In the case of patches for new features, please also provide documentation patches if at all possible. Components are documented in `xdocs/usermanual/component_reference.xml`. See also the following [Bug writing guidelines](https://bz.apache.org/bugwritinghelp.html), also the terms and conditions noted on the [GitHub Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) {/* SYNCED-BODY:END */} --- Title: Mailing Lists URL: https://docs.jmeter.ai/reference/mail/ --- {/* SYNCED-BODY:START */} ## Mailing Lists - Guidelines A mailing list is an electronic discussion forum that anyone can subscribe to. When someone sends an email message to the mailing list, a copy of that message is broadcast to everyone who is subscribed to that mailing list. Mailing lists provide a simple and effective communication mechanism. With potentially thousands of subscribers, there is a common set of etiquette guidelines that you should observe. Please keep on reading. Please note that usage of these mailing lists is subject to the [Public Forum Archive Policy](http://www.apache.org/foundation/public-archives.html). **Respect the mailing list type** There are generally two types of lists. - The "User" lists where you can send questions and comments about configuration, setup, usage and other "user" types of questions. - The "Developer" lists where you can send questions and comments about the actual software source code and general "development" types of questions. Some questions are appropriate for posting on both the "user" and the "developer" lists. In this case, pick one and only one. Do not cross post. Asking a configuration question on the developers list is frowned upon because developers' time is as precious as yours. By contacting them directly instead of the user base you are abusing resources. In fact, it is unlikely that you will get a quicker answer, if at all. **Join the lists that are appropriate for your discussion.** Please make sure that you are joining the list that is appropriate for the topic or product that you would like to discuss. For example, please do not join the Regexp mailing list and ask questions about Tomcat. Instead, you should join the Tomcat User list and ask your questions there. **Ask smart questions.** Every volunteer project obtains its strength from the people involved in it. You are welcome to join any of our mailing lists. You can choose to lurk, or actively participate; it's up to you. The level of community responsiveness to specific questions is generally directly proportional to the amount of effort you spend formulating your question. Eric Raymond and Rick Moen have even written an essay entitled ["Asking Smart Questions"](http://www.catb.org/~esr/faqs/smart-questions.html) precisely on this topic. Although somewhat militant, it is definitely worth reading. **Note**: Please do NOT send your Java problems to the two authors. They welcome feedback on the FAQ's contents, but are simply not a Java help resource. Follow the essay's advice and [choose your forum](http://www.catb.org/~esr/faqs/smart-questions.html#forum) carefully. **Give feedback when you get a good answer.** If an answer given to you helped you solve your problem then send a mail saying so and don't forget to say **THANKS**. If you fixed the problem yourself then contribute to the mailing list by writing how you solved your issue. Giving feedback is useful to people who faced/will face same problems as you and will be your way to contribute to the project. Don't forget that people answering your questions are volunteers doing so on their personal time. **Keep your email short and to the point; use a suitable subject line.** If your email is more than about a page of text, chances are that it won't get read by very many people. It is much better to try to pack a lot of informative information (see above about asking smart questions) into as small of an email as possible. If you are replying to a previous email, it is a good idea to only quote the parts that you are replying to and to remove the unnecessary bits. This makes it easier for people to follow a thread as well as making the email archives easier to search and read. **Start a new thread for a new topic** When asking a new question, please start a new thread with an appropriate new subject line. This makes it easier to read, and to find later in the archives. Do your best to ensure that you are not sending HTML or "Stylized" email to the list. If you are using Outlook or Outlook Express or Eudora, chances are that you are sending HTML email by default. There is usually a setting that will allow you to send "Plain Text" email. If you are using Microsoft products to send email, there are several bugs in the software that prevent you from turning off the sending of HTML email. **Please don't send attachments or include large chunks of code** Attachments can be difficult to read and are rarely needed by all recipients. Some mailing lists are set up to drop them. If you need to send more than a few lines of code, ask first. Note that code is often mangled by word-wrapping, so it is better to provide a link to a downloadable file. If necessary, arrange with the person(s) responding to the posting how best to give access to the data, should it prove necessary. **Watch where you are sending email.** The majority of our mailing lists have set the Reply-To to go back to the list. That means that when you Reply to a message, it will go to the list and not to the original author directly. The reason is because it helps facilitate discussion on the list for everyone to benefit from. Be careful of this as sometimes you may intend to reply to a message directly to someone instead of the entire list. _ The appropriate contents of the Reply-To header is an age-old debate that should not be brought up on the mailing lists. You can examine opposing points of view [condemning](http://www.unicom.com/pw/reply-to-harmful.html) our convention and [condoning](http://www.metasystema.net/essays/reply-to.mhtml) it. Bringing this up for debate on a mailing list will add nothing new and is considered off-topic. _ **Do not cross post messages.** In other words, pick a mailing list and send your messages to that mailing list only. Do not send your messages to multiple mailing lists. The reason is that people may be subscribed to one list and not to the other. Therefore, some people will only see part of the conversation. ## Conclusion **Now that you have read the guidelines above**, [**here**](/./mail2/) is the page that gives you a listing of the different mailing lists that you can join. If you managed to find this without reading the above information, chances are you will be sent back here. You might as well read it now and save yourself the embarrassment. {/* SYNCED-BODY:END */} --- Title: Disclaimer URL: https://docs.jmeter.ai/legal/disclaimer/ --- Apache, Apache JMeter™, JMeter™, the Apache feather, and the Apache JMeter logo are trademarks of the Apache Software Foundation in the United States and/or other countries. **docs.jmeter.ai** is an independently operated resource created by NaveenKumar Namachivayam. The Apache Software Foundation has no affiliation with this site, and does not endorse, review, or take responsibility for the content provided here. For official Apache JMeter documentation, downloads, and project information, visit [jmeter.apache.org](https://jmeter.apache.org). --- Title: NOTICE URL: https://docs.jmeter.ai/legal/notice/ --- ```text Apache JMeter Copyright 1998-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). ``` This NOTICE file is reproduced verbatim from the upstream Apache JMeter project. It is maintained automatically via the [sync workflow](https://github.com/jmeter-docs/jmeter-docs/actions/workflows/sync-upstream.yml). --- Title: JMeter 6.0.0 Release Notes URL: https://docs.jmeter.ai/releases/6-0-0/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 6.0.0, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: :::tip[Highlights] - **Java 17 or later is now required** to run JMeter; Java 21 is recommended. Kotlin 1.9+ is required for Kotlin-based scripts. - **HiDPI mode is applied automatically** in the GUI, so the interface renders sharply on high-resolution displays. - HTTP sampler changes: the original HTTP method is preserved when following 307/308 redirects, and `; charset=` is no longer appended automatically to `multipart/form-data` requests. - JSON Extractor now supports trailing empty default values, so expressions like `${VAR:-}` are handled correctly. - Dependency refresh: Apache Tika 3.x, Groovy 5.x, Saxon-HE 12.x, Bouncy Castle 1.82, json-path 2.10.0, and the Rhino JavaScript engine 1.8.0. - New branding: the feather icon was replaced by an oak leaf in the JMeter logo. ::: ## Change summary | Section | Changes | | --- | --- | | Changes | 23 | | Bug fixes | 6 | ## Changes #### General - [PR#6220](https://github.com/apache/jmeter/pull/6220) Require Java 17 or later for running JMeter - [PR#6550](https://github.com/apache/jmeter/pull/6550) Require Kotlin 1.9 or later for running JMeter - [PR#6274](https://github.com/apache/jmeter/pull/6274) Change references to old MySQL driver to new class `com.mysql.cj.jdbc.Driver` - [Issue#6352](https://github.com/apache/jmeter/issues/6352) Calculate delays in Open Model Thread Group and Precise Throughput Timer relative to start of Thread Group instead of the start of the test. - [Issue#6357](https://github.com/apache/jmeter/issues/6357)[PR#6358](https://github.com/apache/jmeter/pull/6358) Ensure writable directories when copying template files while report generation. - [PR#6509](https://github.com/apache/jmeter/pull/6509)[PR#6675](https://github.com/apache/jmeter/pull/6675) Synchronize recent file menu across multiple JVMs. Contributed by Corneliu C (https://github.com/KingRabbid) - [PR#6596](https://github.com/apache/jmeter/pull/6596)Fallback to English locale when loading test plans that use string values for enum properties, so old sample plans load correctly even with non-English locales. #### HTTP Samplers and Test Script Recorder - [PR#5891](https://github.com/apache/jmeter/pull/5891)Skip Internet Explorer 6-9 conditional comment processing when fetching resource links - [Issue#5466](https://github.com/apache/jmeter/issues/5466)Allow enabling or disabling individual HTTP request arguments in the HTTP Sampler UI. Contributed by Pasquale Pochop (github.com/pochopsp) - [Issue#6250](https://github.com/apache/jmeter/issues/6250)Avoid adding "; charset=" automatically to `multipart/form-data` requests to align behavior with modern HTTP clients. - [Issue#6080](https://github.com/apache/jmeter/issues/6080)Preserve the original HTTP method when following 307 and 308 redirects according to the HTTP specification. Contributed by LeeJiWon (github.com/dlwldnjs1009) - [Issue#6267](https://github.com/apache/jmeter/issues/6267)[PR#6268](https://github.com/apache/jmeter/pull/6268)Add a space between key and value after `:` in View Results Tree > Sampler result tab for better readability. #### Timers, Assertions, Config, Pre- & Post-Processors - [Issue#6448](https://github.com/apache/jmeter/issues/6448)Support trailing empty default values in JSON Extractor so expressions like `\${VAR:-}` are handled correctly. Contributed by Raul Almeida (github.com/ratacolita) - [PR#6596](https://github.com/apache/jmeter/pull/6596)Add a schema for ConstantThroughputTimer and use it to ensure required properties are initialized properly. #### Non-functional changes - Update Apache Tika to 3.x from 1.x to use the latest parser engine. - Update Saxon-HE to 12.x from 11.x for XSLT and XQuery processing. - Update Groovy to 5.x for the Groovy-based scripting environment. - Update Bouncy Castle to 1.82 for cryptographic operations. - Update json-path to 2.10.0 for JSON query expressions. - Update Neo4j Java driver to 6.x for Bolt-based database tests. - Update Rhino JavaScript engine to 1.8.0 for JSR-223 JavaScript execution. #### UI - [PR#6333](https://github.com/apache/jmeter/pull/6333)Apply HiDPI mode automatically when setting up the GUI so JMeter looks sharp on high-resolution displays. Contributed by Gabriele Coletta (github.com/gdmg92) - [PR#6656](https://github.com/apache/jmeter/pull/6656)Replace the previous feather icon with the new oak leaf in the JMeter logo. ## Bug fixes #### General - [PR#6654](https://github.com/apache/jmeter/pull/6654)[Issue#6611](https://github.com/apache/jmeter/issues/6611)Support JDK 25 and above for result collectors with empty file names - Trim whitespace when parsing numeric JMeter properties so accidental spaces do not silently change configuration values. - [PR#6372](https://github.com/apache/jmeter/pull/6372)Fix KeyManager logging when using CLI mode so keystore passwords are not incorrectly reported as missing. Contributed by Patrick Uiterwijk (patrick at puiterwijk.org) - [Issue#5937](https://github.com/apache/jmeter/issues/5937)Remove deprecated Log4j package scanning and configure plugin metadata processing to improve startup time and avoid deprecation warnings. Contributed by Piotr P. Karwasz (github.com/piotrgithub) - [PR#6620](https://github.com/apache/jmeter/pull/6620)Fix report generation paths so dashboard output files are created in the correct location after internal refactoring. - [Bug 6456](https://bz.apache.org/bugzilla/show_bug.cgi?id=6456)Handle malformed percent-encoded URLs gracefully when recording HTTP traffic, logging a warning instead of failing the recording. ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Raul Almeida (github.com/ratacolita) - Pasquale Pochop (github.com/pochopsp) - Gabriele Coletta (github.com/gdmg92) - Patrick Uiterwijk (patrick at puiterwijk.org) - Piotr P. Karwasz (github.com/piotrgithub) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.6.2 Release Notes URL: https://docs.jmeter.ai/releases/5-6-2/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.6.2, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Bug fixes | 1 | ## Bug fixes #### General - [PR#6042](https://github.com/apache/jmeter/pull/6042)[Issue#6041](https://github.com/apache/jmeter/issues/6041)Fix compatibility with Maven's pom.xml parser by adding explicit versions for `com.google.auto.service:auto-service-annotations` (regression since 5.6) ## Thanks We thank all contributors mentioned in bug and improvement sections above: We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.6.1 Release Notes URL: https://docs.jmeter.ai/releases/5-6-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.6.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: :::tip[Highlights] - **UTF-8 became the default encoding** in the HTTP sampler, enabling parameter names and file names with unicode characters. - The **HTTP(S) Test Script Recorder uses UTF-8 by default**, inferring human-readable arguments rather than percent-encoded ones. - The default value of `sampleresult.default.encoding` changed to UTF-8 (inheriting the default HTTP encoding). - Regression fixes since 5.6: Thread Groups no longer run endlessly in non-GUI mode, and the Java Request sampler can be re-enabled after being disabled in the UI. ::: ## Change summary | Section | Changes | | --- | --- | | Improvements | 2 | | Bug fixes | 2 | | Non-functional changes | 8 | ## New and Noteworthy ## Improvements #### HTTP Samplers and Test Script Recorder - [PR#6010](https://github.com/apache/jmeter/pull/6010)Use UTF-8 as a default encoding in HTTP sampler. It enables sending parameter names, and filenames with unicode characters - [PR#6010](https://github.com/apache/jmeter/pull/6010)Test Recorder will use UTF-8 encoding by default, so it will infer human-readable arguments rather than percent-encoded ones ## Bug fixes #### Thread Groups - [PR#6011](https://github.com/apache/jmeter/pull/6011)Regression since 5.6: ThreadGroups are running endlessly in non-gui mode: use default value for LoopController.continue_forever rather than initializing it in the constructor #### Other Samplers - [PR#6012](https://github.com/apache/jmeter/pull/6012) Java Request sampler cannot be enabled again after disabling in UI (regression since 5.6) ## Non-functional changes - [PR#6000](https://github.com/apache/jmeter/pull/6000)Add release-drafter for populating GitHub releases info based on the merged PRs - [PR#5989](https://github.com/apache/jmeter/pull/5989)Use Gradle toolchains for JDK provisioning, enable building and testing with different JDKs, start testing with Java 21 - [PR#5991](https://github.com/apache/jmeter/pull/5991)Update jackson-core, jackson-databind, jackson-annotations to 2.15.2 (from 2.15.1) - [PR#5993](https://github.com/apache/jmeter/pull/5993)Update ph-commons to 10.2.5 (from 10.2.4) - [PR#6017](https://github.com/apache/jmeter/pull/6017)Update kotlin-stdlib to 1.8.22 (from 1.8.21) - [PR#6020](https://github.com/apache/jmeter/pull/6020)Update error_prone_annotations to 2.20.0 (from 2.19.1) - [PR#6023](https://github.com/apache/jmeter/pull/6023)Update checker-qual to 3.35.0 (from 3.34.0) #### Other Samplers - [PR#6028](https://github.com/apache/jmeter/pull/6028) Change default value for `sampleresult.default.encoding` to UTF-8 (it inherits default HTTP encoding which was modified in [PR#6010](https://github.com/apache/jmeter/pull/6010)) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Alex Schwartz, [@alexsch01](https://github.com/alexsch01) We also thank bug reporters who helped us improve JMeter. - David Getzlaff, [@dgetzlaf](https://github.com/dgetzlaf) - LeeBaul, [@libaolu](https://github.com/libaolu) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.6 Release Notes URL: https://docs.jmeter.ai/releases/5-6/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.6, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Improvements | 23 | | Bug fixes | 15 | | Non-functional changes | 43 | ## New and Noteworthy ## Improvements #### Thread Groups - [Issue#5682](https://github.com/apache/jmeter/issues/5682)[PR#717](https://github.com/apache/jmeter/pull/717) Open Model Thread Group: avoid skipping rows from CSV Data Set Config - Support custom thread group implementations in "Add think time" and "Save as test fragment" actions - Open Model Thread Group: interrupt pending HTTP requests and other `Interruptible` test elements on test stop #### HTTP Samplers and Test Script Recorder - [PR#5911](https://github.com/apache/jmeter/pull/5911) Use Caffeine for caching HTTP headers instead of commons-collections4 LRUMap - [PR#5947](https://github.com/apache/jmeter/pull/5947) Fetch resources referenced in `<link "rel"="preload"...>` elements - [PR#5869](https://github.com/apache/jmeter/pull/5869) Allow more templates to format sampler names in the recorder: `#{url}`, `#{method}`, `#{scheme}`, `#{host}`, `#{port}` #### Other samplers - [PR#5909](https://github.com/apache/jmeter/pull/5909) Use Caffeine for caching compiled scripts in JSR223 samplers instead of commons-collections4 LRUMap #### General - [PR#5792](https://github.com/apache/jmeter/pull/5792)Add KeyStroke for start_no_timers (Start no pauses: CRTL+SHIFT+n) - [PR#5899](https://github.com/apache/jmeter/pull/5899)Speed up CPU-bound tests by skipping `recoverRunningVersion` for elements that are shared between threads (the ones that implement `NoThreadClone`) - [PR#5914](https://github.com/apache/jmeter/pull/5914)Use `Locale.ROOT` instead of default locale for `toUpperCase`, and `toLowerCase` to avoid surprises with dotless I in `tr_TR` locale - [PR#5885](https://github.com/apache/jmeter/pull/5885)Use Java's `ServiceLoader` for loading plugins instead of classpath scanning. It enables faster startup - [PR#5788](https://github.com/apache/jmeter/pull/5788)`FunctionProperty` no longer caches the value. Previously it cached the values based on iteration number only which triggered wrong results on concurrent executions. The previous behavior can be temporary restored with `function.cache.per.iteration` property. - [PR#5920](https://github.com/apache/jmeter/pull/5920)Improve HTTP HeaderManager performance when it contains many headers: skip reinitialization on each iteration - [PR#5920](https://github.com/apache/jmeter/pull/5920)Use AtomicInteger and AtomicLong instead of synchronized primitives for JMeterContextService#numberOfThreads - [PR#5920](https://github.com/apache/jmeter/pull/5920)Cache bean properties in `TestBeanHelper` and avoid synchronization, so test plans with `TestBean`-based elements is faster - [PR#5920](https://github.com/apache/jmeter/pull/5920)Improve computation when many threads actively produce samplers by using `LongAdder` and similar concurrency classes to avoid synchronization in `Calculator` - [PR#5920](https://github.com/apache/jmeter/pull/5920)Reduce synchronization contention on `AbstractTestElement` that are shared between threads (the ones that implement `NoThreadClone`) - [PR#5934](https://github.com/apache/jmeter/pull/5934)Added caching for date formatters for `__time` function - [PR#710](https://github.com/apache/jmeter/pull/710)[Issue#5666](https://github.com/apache/jmeter/issues/5666)Added Shortcut key event for Reset search: `ctrl + alt + F`, `cmd + alt + F` - [PR#5959](https://github.com/apache/jmeter/pull/5959)`TestElement` has been migrated to Kotlin, so nullable types are annotated better - [PR#5944](https://github.com/apache/jmeter/pull/5944)Add PI for declaring `TestElement` schemas so element properties are easier to access in code (see `TestElementSchema`, `TestElement#getSchema()`, `TestElement#getProps()`) - [PR#5944](https://github.com/apache/jmeter/pull/5944)Enable usage of `\${...}` expressions for checkbox controls (see context menus for checkboxes, however, the individual components should be adapted individually) - [PR#678](https://github.com/apache/jmeter/pull/678)Experimental Kotlin and Java DSL for programmatic test plan generation (see [Creating a plan with Kotlin DSL](/usermanual/build-programmatic-test-plan/#treebuilder_kotlin_dsl)) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [PR#5901](https://github.com/apache/jmeter/pull/5901)Fix NumberFormatException when counter is empty or not a digit on Proxy Settings panel - [PR#5987](https://github.com/apache/jmeter/pull/5987)[Issue#4546](https://github.com/apache/jmeter/issues/4546)Encode unicode characters in filenames when sending files in HTTP Sampler #### Other Samplers - [PR#5736](https://github.com/apache/jmeter/pull/5736)[Issue#5733](https://github.com/apache/jmeter/issues/5733)Allow `SampleResult#setEndTime` be set in `JSR223Sampler` #### Listeners - [Issue#5740](https://github.com/apache/jmeter/issues/5740)[PR#5741](https://github.com/apache/jmeter/pull/5741)Fix Aggregated Graph component to cope with empty names of samplers - [Issue#5807](https://github.com/apache/jmeter/issues/5807)Fix an `ArrayIndexOutOfBoundsException` on HTTP parameters line on special case when key and value are empty, i.e.: "`k1=v1&=&k2=v2`" - [Issue#5654](https://github.com/apache/jmeter/issues/5654)[PR#5785](https://github.com/apache/jmeter/pull/5785) Fix `InfluxDBRawBackendListenerClient` missing data. Allow InfluxDB to insert multiple entries with the same `timestamp` but with different `threadName`. Contributed by Victor Peralta (vperaltac at github) #### Timers, Assertions, Config, Pre- & Post-Processors - [PR#5717](https://github.com/apache/jmeter/pull/5717)Add jsonpath string to JSON Path Assertion error message so the error is easier to understand - [PR#723](https://github.com/apache/jmeter/pull/723)Use correct number format on JSON Path Assertion. Contributed by andreaslind01 (andreaslind01 at gmail.com) #### Report / Dashboard - [Bug 66140](https://bz.apache.org/bugzilla/show_bug.cgi?id=66140)Guess the delimiter of the CSV source, when configured one seems wrong. This is in line with the behaviour of CSVSaveService. #### Documentation - [Issue#5694](https://github.com/apache/jmeter/issues/5694)Document changed formatter for [__time()](/user-manual/functions/#__time__). A warning will be logged, if the code `u` is found in the format string, as the meaning for that code has changed from _day-of-week_ to _year_. #### General - [Bug 66157](https://bz.apache.org/bugzilla/show_bug.cgi?id=66157)[PR#719](https://github.com/apache/jmeter/pull/719)Correct theme for darklaf on rsyntaxtextarea - [Issue#5872](https://github.com/apache/jmeter/issues/5872)[PR#5874](https://github.com/apache/jmeter/pull/5874)Trim name in Argument objects. - [PR#693](https://github.com/apache/jmeter/pull/693)Avoid wrong results when `Object.hashCode()` happen to collide. Use `IdentityHashMap` instead of `HashMap` when key is `TestElement` - Refresh UI when dragging JMeter window from one monitor to another, so rich syntax text areas are properly editable after window movement - [PR#5984](https://github.com/apache/jmeter/pull/5984)`AbstractTestElement#clone` might produce non-identical clones if element constructor adds a non-default property value ## Non-functional changes - [PR#725](https://github.com/apache/jmeter/pull/725)Add Chinese Simplified Translation for Open Model Thread Group - [PR#5710](https://github.com/apache/jmeter/pull/5710)Add GitHub Issue templates - [PR#5910](https://github.com/apache/jmeter/pull/5910)Use Caffeine for caching customizers in TestBeanGUI instead of commons-collections4 LRUMap - [PR#5713](https://github.com/apache/jmeter/pull/5713)[PR#5931](https://github.com/apache/jmeter/pull/5931)Update Spock to 2.3-groovy-3.0 (from 2.1-groovy-3.0) - [Issue#5718](https://github.com/apache/jmeter/issues/5718)Update Apache commons-text to 1.10.0 (from 1.9) - [PR#5731](https://github.com/apache/jmeter/pull/5731)Update docs for `changeCase` function. `UPPER` is the default - [PR#5924](https://github.com/apache/jmeter/pull/5924)Update Apache commons-io to 2.12.0 (from 2.11.0) - [PR#5921](https://github.com/apache/jmeter/pull/5921)Update Jackson Core to 2.15.1 (from 2.13.3) - [PR#5921](https://github.com/apache/jmeter/pull/5921)Update Jackson Databind to 2.15.1 (from 2.13.3) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update Tika Parser to 1.28.5 (from 1.28.3) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update JSoup to 1.16.1 (from 1.15.1) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update Apache commons-net to 3.9.0 (from 3.8.0) - [PR#5725](https://github.com/apache/jmeter/pull/5725)Update XStream to 1.4.20 (from 1.4.19) - [PR#5763](https://github.com/apache/jmeter/pull/5763)[PR#5814](https://github.com/apache/jmeter/pull/5814)Updated Gradle to 8.1.1 (from 7.2) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Added Apache Httpclient5 5.1.3 - [PR#5833](https://github.com/apache/jmeter/pull/5833)Update Apache Freemarker to 2.3.32 (from 2.3.31) - [PR#5830](https://github.com/apache/jmeter/pull/5830)Update Apache Groovy to 3.0.17 (from 3.0.11) - [PR#5862](https://github.com/apache/jmeter/pull/5862)Update Apache Httpclient to 4.5.14 (from 4.5.13) - [PR#5880](https://github.com/apache/jmeter/pull/5880)Update Apache Xalan to 2.7.3 (from 2.7.2) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Update Saxon-HE to 11.5 (from 11.5) - [PR#5840](https://github.com/apache/jmeter/pull/5840)[PR#5930](https://github.com/apache/jmeter/pull/5930)Update accessors-smart to 2.4.11 (from 2.4.8) - [PR#5837](https://github.com/apache/jmeter/pull/5837)Update asm to 9.5 (from 9.3) - [PR#5840](https://github.com/apache/jmeter/pull/5840)[PR#5930](https://github.com/apache/jmeter/pull/5930)Update json-smart to 2.4.11 (from 2.4.8) - [PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlin-stdlib to 1.8.21 (from 1.6.21) - [PR#5889](https://github.com/apache/jmeter/pull/5889)[PR#5918](https://github.com/apache/jmeter/pull/5918)[PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlinx-coroutines-core to 1.8.21 (from 1.6.21) - [PR#5889](https://github.com/apache/jmeter/pull/5889)[PR#5918](https://github.com/apache/jmeter/pull/5918)[PR#5814](https://github.com/apache/jmeter/pull/5814)Update kotlinx-coroutines-swing to 1.8.21 (from 1.6.21) - [PR#5907](https://github.com/apache/jmeter/pull/5907)Update lets-plot-batik to 3.2.0 (from 2.1.1) - [PR#5907](https://github.com/apache/jmeter/pull/5907)Update lets-plot-jvm to 4.3.0 (from 3.1.1) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-1.2-api to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-api to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-core to 2.20.0 (from 2.17.2) - [PR#5859](https://github.com/apache/jmeter/pull/5859)Update log4j-slf4j-impl to 2.20.0 (from 2.17.2) - [PR#5861](https://github.com/apache/jmeter/pull/5861)Update neo4j-java-driver to 4.4.11 (from 4.4.6) - [PR#5853](https://github.com/apache/jmeter/pull/5853)Update org.jetbrains:annotations to 24.0.1 (from 23.0.0) - [PR#5868](https://github.com/apache/jmeter/pull/5868)[PR#5886](https://github.com/apache/jmeter/pull/5886)Update ph-commons to 10.2.4 (from 10.1.6) - [PR#5861](https://github.com/apache/jmeter/pull/5861)Update reactive-streams to 1.0.4 (from 1.0.3) - [PR#5847](https://github.com/apache/jmeter/pull/5847)Update rsyntaxtextarea to 3.3.3 (from 3.2.0) - [PR#5839](https://github.com/apache/jmeter/pull/5839)Update svgSalamander to 1.1.4 (from 1.1.2.4) - [PR#5852](https://github.com/apache/jmeter/pull/5852)Update xmlgraphics-commons to 2.8 (from 2.7) - [PR#5854](https://github.com/apache/jmeter/pull/5854)Update xmlresolver to 4.6.4 (from 4.2.0) - [PR#693](https://github.com/apache/jmeter/pull/693)Added randomized test GitHub Actions matrix for better coverage of locales and time zones - [PR#5960](https://github.com/apache/jmeter/pull/5960)Add OpenJDK JMH for creating microbenchmarks in JMeter code - [Issue#5961](https://github.com/apache/jmeter/issues/5961)Deprecate TestElement.threadName as it is not related to TestElement ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Alex Schwartz, [@alexsch01](https://github.com/alexsch01) - Andreas Lind, [@andreaslind01](https://github.com/andreaslind01) - Arnout Engelen, [@raboof](https://github.com/raboof) - Clay Johnson, [@clayburn](https://github.com/clayburn) - David Getzlaff, [@dgetzlaf](https://github.com/dgetzlaf) - Kai Lehmann, [@lehmannk](https://github.com/lehmannk) - kaola89, [@kaola89](https://github.com/kaola89) - Matt Tansley, [@matthewt-assurity](https://github.com/matthewt-assurity) - Mohamed Ibrahim, [@rollno748](https://github.com/rollno748) - Ori Marko, [@orimarko](https://github.com/orimarko) - PJ Fanning, [@pjfanning](https://github.com/pjfanning) - Sandra Thieme, [@sandra-thieme](https://github.com/sandra-thieme) - Stefan Seide, [@sseide](https://github.com/sseide) - Victor Peralta, [@vperaltac](https://github.com/vperaltac) - Vincent DABURON, [@vdaburon](https://github.com/vdaburon) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.5 Release Notes URL: https://docs.jmeter.ai/releases/5-5/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.5, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Improvements | 21 | | Bug fixes | 32 | | Non-functional changes | 55 | ## New and Noteworthy JMeter now supports Java 17 JMeter 5.5 ships with log4j2 2.17.2 ### Open Model Thread Group New component: `[Open Model Thread Group](/./usermanual/component-reference/#Open_Model_Thread_Group)` allows creating load profiles with variable load. For example, if you need to gradually increase load from `0/sec` to `10/sec` during `minute` you could previously use `Thread Group + Timer` combinations. However, then you need to compute the expected number of threads, ensure they are created only when needed, and so on. With `Open Model Thread Group` you can configure the same load profile as `rate(0/sec) random_arrivals(1 minute) rate(10/sec)`. The thread group would spawn threads as needed to drive the configured load. The load profile can use properties, so you can launch the same script with slightly different load levels, however, the profile can't be updated while the test is running. The new thread group is experimental in JMeter 5.5, so please feel free to submit your feedback. ![Open Model Thread Group sample](/images/screenshots/open_model_thread_group.png) _Open Model Thread Group sample_ ### Preparing the deprecation of Oro Regex usage Another experimental feature in JMeter 5.5 is the ability to replace the Oro based Regex implementation by the built-in Java based one. To choose the Java based one, set the JMeter property `jmeter.regex.engine` to the value `java`. ### Core improvements Kotlin language is now used in some core classes and tests (e.g. Open Model Thread Group). JMeter is compiled with `apiTarget=1.5`, and it ships with `kotlin-stdlib` 1.6. [lets-plot-kotlin](https://github.com/JetBrains/lets-plot-kotlin) charting library is added, so it will be easier to refine and create new charts in UI in the future. ## Improvements #### Thread Groups - New component: `[Open Model Thread Group](/./usermanual/component-reference/#Open_Model_Thread_Group)` #### HTTP Samplers and Test Script Recorder - [Bug 65027](https://bz.apache.org/bugzilla/show_bug.cgi?id=65027)Detect mime-type for files automatically when adding files to HTTP Sampler - [Bug 65020](https://bz.apache.org/bugzilla/show_bug.cgi?id=65020)HTTP Sampler/Files upload tab - add missing buttons - [PR#650](https://github.com/apache/jmeter/pull/650)HTTP Sampler timestamp fix when exception is caught. Contributed by Konstantin Kalinin (konstantin at kkalinin.pro) - [Bug 65328](https://bz.apache.org/bugzilla/show_bug.cgi?id=65328)[PR#666](https://github.com/apache/jmeter/pull/666)HTTP 308 Permanent Redirect is not supported. Contributed by Baptiste Gaillard (baptiste.gaillard at gmail.com) #### Other samplers - [Bug 65149](https://bz.apache.org/bugzilla/show_bug.cgi?id=65149)[PR#644](https://github.com/apache/jmeter/pull/644)Encode the personal part of email addresses in SMTP Sampler - [PR#638](https://github.com/apache/jmeter/pull/638)Various additions to the Bolt Sampler. Added `transaction timeout`, `database` option required for Neo4j 4.x (with multi-database support) and `access mode` option, that allows running against a Neo4j Enterprise Causal Cluster. Contributed by David Pecollet (david.pecollet at gmail.com) #### Controllers - [PR#665](https://github.com/apache/jmeter/pull/665)Increase visible lines of code in `IfController` and `WhileController`. Based on an idea by David Getzlaff (david.getzlaff at t-systems.com>). #### Listeners - [Bug 64988](https://bz.apache.org/bugzilla/show_bug.cgi?id=64988)Sort properties and variables in a human expected order for DebugPostProcessor and DebugSampler - [Bug 63061](https://bz.apache.org/bugzilla/show_bug.cgi?id=63061)Sort View Results in Table in a human expected order - [PR#706](https://github.com/apache/jmeter/pull/706)Try to keep UI responsive when displaying large text results. Can be configured with the new property `view.results.tree.simple_view_limit` #### Timers, Assertions, Config, Pre- & Post-Processors - [PR#638](https://github.com/apache/jmeter/pull/638)Bolt Connection Configuration: added `ConnectionPoolMaxSize` parameter. Contributed by David Pecollet (david.pecollet at gmail.com) - [Bug 65515](https://bz.apache.org/bugzilla/show_bug.cgi?id=65515)Allow pooling of Prepared Statements in JDBC - [Bug 65299](https://bz.apache.org/bugzilla/show_bug.cgi?id=65299)JSONPathAssertion attributes are out of order/Compare JSON objects and not their string representations. #### Report / Dashboard - [Bug 65353](https://bz.apache.org/bugzilla/show_bug.cgi?id=65353)Make the estimator used for calculating percentiles on the dashboard configurable #### General - [Bug 61805](https://bz.apache.org/bugzilla/show_bug.cgi?id=61805)[PR#663](https://github.com/apache/jmeter/pull/663)Add simple HTTP request template. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 65611](https://bz.apache.org/bugzilla/show_bug.cgi?id=65611)[PR#673](https://github.com/apache/jmeter/pull/673)Add support for IPv6 addresses when specifying a remote worker node. Based on a patch by Peter Wong (peter.wong at csexperts.com) - Reduce memory consumption by the logging panel (disable undo events for it) - [Bug 63620](https://bz.apache.org/bugzilla/show_bug.cgi?id=63620)[PR#694](https://github.com/apache/jmeter/pull/694)Fix GUI freeze when viewing response body with long line breaks - [PR#699](https://github.com/apache/jmeter/pull/699)Add documentation for Graphite Backend Listener. Contributed by Ji Hun (jihunkimkw at gmail.com) - [Bug 57672](https://bz.apache.org/bugzilla/show_bug.cgi?id=57672)[PR#700](https://github.com/apache/jmeter/pull/700)Add a switch (`jmeter.regex.engine`) to replace Oro Regex implementation by the built-in Java one. ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 65310](https://bz.apache.org/bugzilla/show_bug.cgi?id=65310)Don't let users override `multipart/form-data` `content-type` header in HC4 sampler. - [Bug 65363](https://bz.apache.org/bugzilla/show_bug.cgi?id=65363)`NullPointerException` in `HTTPHC4Impl$ManagedCredentialsProvider.getAuthorizationForAuthScope` when `401` response from remote and `httpclient4.auth.preemptive=false` - [Bug 65692](https://bz.apache.org/bugzilla/show_bug.cgi?id=65692)HTTP(s) Test Script Recorder: Enable setting enabled cipher suite and enabled protocols on SSLContext/ Align SSL properties between Java and HC4 implementation - [Bug 65108](https://bz.apache.org/bugzilla/show_bug.cgi?id=65108)Support JMeter variables in [GraphQL HTTP Request](/./usermanual/component-reference/#HTTP_Request) - [Bug 65864](https://bz.apache.org/bugzilla/show_bug.cgi?id=65864)Catch `NullPointerException` from JSoup when recording a test plan #### Other Samplers - [Bug 65152](https://bz.apache.org/bugzilla/show_bug.cgi?id=65152)OS Process Sampler - Cannot `Add from Clipboard` Command parameters - [PR#638](https://github.com/apache/jmeter/pull/638)Bolt Sampler: fixed error displaying results when "Record Query Results" is enabled. Contributed by David Pecollet (david.pecollet at gmail.com) #### Controllers #### Listeners - [Bug 64962](https://bz.apache.org/bugzilla/show_bug.cgi?id=64962)Save CSV sub-results recursively from View Results Tree - [Bug 65784](https://bz.apache.org/bugzilla/show_bug.cgi?id=65784)No Graphs displayed in Aggregate Report/Response Time Graph - [Bug 65884](https://bz.apache.org/bugzilla/show_bug.cgi?id=65884)GUI doesn't display response for multipart request _manually_ encoded #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 65257](https://bz.apache.org/bugzilla/show_bug.cgi?id=65257)JMESPathExtractor writes error log entries if JMESPath filter returns empty result - [Bug 65259](https://bz.apache.org/bugzilla/show_bug.cgi?id=65259)JMESPathExtractor Attribute `Match No.` Required - [Bug 65269](https://bz.apache.org/bugzilla/show_bug.cgi?id=65269)JSON Extractor and JSON JMESPath Extractor ignore sub-samples - [Bug 65352](https://bz.apache.org/bugzilla/show_bug.cgi?id=65352)Warning logged when Boundary Extractor doesn't find any match - [Bug 65681](https://bz.apache.org/bugzilla/show_bug.cgi?id=65681)Use default values for `null` values when extracting with JSONPostProcessor - Allow setters in ConstantThroughputTimer to update the values during run time - [Bug 65782](https://bz.apache.org/bugzilla/show_bug.cgi?id=65782)Use correct message format for MessageFormat in HTMLAssertion - [Bug 65794](https://bz.apache.org/bugzilla/show_bug.cgi?id=65794)JSON Assertion always successful with indefinite paths #### Functions #### I18N #### Report / Dashboard #### Documentation - [PR#658](https://github.com/apache/jmeter/pull/658)Improve javadoc. Contributed by Ori Marko (orimarko at gmail.com) #### General - [Bug 64318](https://bz.apache.org/bugzilla/show_bug.cgi?id=64318)DNS Cache Manager - custom DNS resolver does not use system resolver by default - [PR#641](https://github.com/apache/jmeter/pull/641)[PR#698](https://github.com/apache/jmeter/pull/698)Updated xercesImpl to 2.12.2 (from 2.12.0). Based on patch by Stefan Seide (stefan at trilobyte-se.de). - [PR#645](https://github.com/apache/jmeter/pull/645)Add escaping for new lines in `AbstractInfluxdbMetricsSender`. Contributed by David Getzlaff (david.getzlaff at t-systems.com>) - [Bug 65198](https://bz.apache.org/bugzilla/show_bug.cgi?id=65198)Can't copy generated function from FunctionHelper - [PR#661](https://github.com/apache/jmeter/pull/661)Fix wording in doc. Contributed by BugKing (wangzhen at fit2cloud.com) - [PR#664](https://github.com/apache/jmeter/pull/664)Allow whitespace in path. Contributed by Till Neunast (github.com/tilln) - [Bug 65270](https://bz.apache.org/bugzilla/show_bug.cgi?id=65270)POST `application/x-www-form-urlencoded` cURL code generated from Postman is not imported correctly - Silence warnings of missing font Arial on startup under Linux - [Bug 65300](https://bz.apache.org/bugzilla/show_bug.cgi?id=65300)`IllegalAccessError` when opening file dialog with Java 16 - [Bug 65336](https://bz.apache.org/bugzilla/show_bug.cgi?id=65336)Blank labels when different elements had the same name - [Bug 65522](https://bz.apache.org/bugzilla/show_bug.cgi?id=65522)Restart doesn't work, when parameters contain spaces - [Bug 63914](https://bz.apache.org/bugzilla/show_bug.cgi?id=63914)Simplify `:src:dist:clean` configuration, ensure `/lib/junit/test.jar` is removed on clean - [PR#696](https://github.com/apache/jmeter/pull/696)Keep JSyntaxTextArea text value for use in headless mode. Contributed by Peter Paul Bakker (peter.paul.bakker at stokpop.nl) ## Non-functional changes - Added Kotlin 1.6.21 for JMeter engine implementation (apiVersion=1.5). The set of JSR 223 languages is intact. - [Bug 65128](https://bz.apache.org/bugzilla/show_bug.cgi?id=65128)[PR#643](https://github.com/apache/jmeter/pull/643)Add missing documentation about `Same user on each iteration` for Thread Groups. Contributed by njkuzas. - [PR#648](https://github.com/apache/jmeter/pull/648)Updated xmlgraphics-commons to 2.6 (from 2.3). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [PR#655](https://github.com/apache/jmeter/pull/655)[PR#667](https://github.com/apache/jmeter/pull/667)[PR#675](https://github.com/apache/jmeter/pull/675)[PR#698](https://github.com/apache/jmeter/pull/698)Updated x-stream to 1.4.19 (from 1.4.15). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [PR#656](https://github.com/apache/jmeter/pull/656)[PR#668](https://github.com/apache/jmeter/pull/668)Updated json-smart to 2.4.8 (from 2.3), accessors-smart to 2.4.8 (from 1.2) and asm 9.3 (from 9.0). Contributed by Stefan Seide (stefan at trilobyte-se.de) - [Bug 64831](https://bz.apache.org/bugzilla/show_bug.cgi?id=64831)Log truststore entries in debug level for logger `org.apache.jmeter.util.keystore.JmeterKeyStore` - [Bug 65232](https://bz.apache.org/bugzilla/show_bug.cgi?id=65232)Hide splash screen when an error is displayed because the test plan could not be parsed. - Updated Groovy to 3.0.11 (from 3.0.7). - Updated Darklaf to 2.7.3 (from 2.5.4). - Updated Apache ActiveMQ to 15.6.4 (from 15.6.0). - Updated Asm to 9.2 (from 9.1). - Updated Bouncycastle to 1.70 (from 1.67). - Updated Caffeine to 2.9.3 (from 2.8.8). - Updated Apache commons-dbcp2 to 2.9.0 (from 2.8.0). - Updated Apache commons-io to 2.11.0 (from 2.8.0). - Updated Apache commons-lang3 to 3.12.0 (from 3.11). - Updated Apache commons-net to 3.8.0 (from 3.7.2). - Updated Apache commons-pool2 to 2.11.1 (from 2.9.0). - Updated equalsverifier to 3.10 (from 3.4.2). - Updated Apache Freemarker to 2.3.31 (from 2.3.30). - Updated hsqldb to 2.5.2 (from 2.5.0). - Updated Apache HttpClient to 4.5.13 (from 4.5.12). - Updated Apache HttpCore to 4.4.15 (from 4.4.13). - Updated jacoco to 0.8.7 (from 0.8.5). - Updated json-path to 2.7.0 (from 2.4.0). - Updated jsoup to 1.15.1 (from 1.13.1). - Updated JUnit to 4.13.2 and 5.8.2 (from 4.13.1 and 5.7.0). - Updated Apache log4j2 to 2.17.2 (from 2.13.3). - Updated Miglayout to 5.3 (from 5.2). - Updated Neo4j Java driver to 4.4.6 (from 4.2.0). - Updated Objenesis to 3.2 (from 2.6). - Updated ktlint to 0.40.0 - Updated PH CSS and PH commons to 6.5.4 and 10.1.6 (from 6.2.3 and 9.5.1). - Updated RSyntaxTextArea to 3.2.0 (from 3.1.1). - Updated SLF4J to 1.7.36 (from 1.7.30). - Updated SvgSalamander to 1.1.2.4 (from 1.1.2.1). - [PR#698](https://github.com/apache/jmeter/pull/698)Updated Apache Tika to 1.28.3 (from 1.26). - Updated WireMock-JRE8 to 2.30.0 (from 2.24.1). - Updated com.github.vlsi.vlsi-release-plugins 1.76 (from 1.74). - Updated jackson to 2.13.3 (from 2.10.5) - Updated jmespath to 0.5.1 - Updated Saxon-HE to 11.2 (from 9.9.1-8) - Updated Apache xmlgraphics commons to 2.7 (from 2.6) - [PR#671](https://github.com/apache/jmeter/pull/671)Move example definition of property `jmeter.reportgenerator.statistic_window` to `user.properties`, as it is read from that place. Contributed by Rithvik Patibandla (rithvikp98 at gmail.com) - [Bug 65456](https://bz.apache.org/bugzilla/show_bug.cgi?id=65456)Updated commons-jexl 3 to 3.2.1 (from 3.1). Contributed by Ori Marko (orimarko at gmail.com>) - [PR#654](https://github.com/apache/jmeter/pull/654)Try do give better feedback while loading keystores - [PR#672](https://github.com/apache/jmeter/pull/672)Add more details to documentation for timeShift function. Contributed by Mariusz (mawasak at gmail.com) - Updated Gradle to 7.3 (from 7.2) - [PR#689](https://github.com/apache/jmeter/pull/689)Code clean up in StringFromFile. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#690](https://github.com/apache/jmeter/pull/690)Refactor a few unit tests. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#692>](https://github.com/apache/jmeter/pull/692>)Fix a few deprecation warnings for Gradle. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [PR#697>](https://github.com/apache/jmeter/pull/697>)Junit 5 tests to use asserts from Junit 5 API. Contributed by Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - [Bug 65983](https://bz.apache.org/bugzilla/show_bug.cgi?id=65983)[PR#707](https://github.com/apache/jmeter/pull/707)Use current screenshot for save-to-file listener in documentation. Based on patch by NaveenKumar Namachivayam (catch.nkn at gmail.com) - [PR#708](https://github.com/apache/jmeter/pull/708)Make errorprone happier. Based on patch by Wilson Kurniawan (wilson at visenze.com)> - Updated Rhino JavaScript to 1.7.14 (from 1.7.13) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Stefan Seide (stefan at trilobyte-se.de) - njzukas (github.com/njzukas) - David Getzlaff (david.getzlaff at t-systems.com>) - Konstantin Kalinin (konstantin at kkalinin.pro) - David Pecollet (david.pecollet at gmail.com) - Ori Marko (orimarko at gmail.com) - BugKing (wangzhen at fit2cloud.com) - Till Neunast (github.com/tilln) - Baptiste Gaillard (baptiste.gaillard at gmail.com) - Rithvik Patibandla (rithvikp98 at gmail.com) - Mariusz (mawasak at gmail.com) - peter.wong@csexperts.com - Woonsan Ko (woonsan.ko at bloomreach.com) - Chromico Rek (atech5122 at gmail.com) - Magnus Spångdal (magnus.spangdal as avanza.se) - Piotr Smietana (piotrsmietana1998 at gmail.com) - Sampath Kumar Krishnasamy (sampathkumar.krishnasamykuppusamy at aexp.com) - Ji Hun (jihunkimkw at gmail.com) - Peter Paul Bakker (peter.paul.bakker at stokpop.nl) - NaveenKumar Namachivayam (catch.nkn at gmail.com) - Wilson Kurniawan (wilson at visenze.com) We also thank bug reporters who helped us improve JMeter. - Nikola Aleksic (nalexic at gmail.com) - Vladimir Rosu (rosuvladimir at gmail.com) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.4.3 Release Notes URL: https://docs.jmeter.ai/releases/5-4-3/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.4.3, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Non-functional changes | 1 | ## Non-functional changes - Updated Apache log4j2 to 2.17.0 (from 2.16.0). ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.4.2 Release Notes URL: https://docs.jmeter.ai/releases/5-4-2/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.4.2, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Non-functional changes | 1 | ## Non-functional changes - Updated Apache log4j2 to 2.16.0 (from 2.13.3). ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.4.1 Release Notes URL: https://docs.jmeter.ai/releases/5-4-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.4.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 1 | | Improvements | 2 | | Bug fixes | 19 | | Non-functional changes | 13 | ## Incompatible changes - Restart after LAF change has been reinstated, it had been removed in JMeter 5.3 ## Improvements #### General - [Bug 65028](https://bz.apache.org/bugzilla/show_bug.cgi?id=65028)Add documentation for the property `client.rmi.localport` - [Bug 65012](https://bz.apache.org/bugzilla/show_bug.cgi?id=65012)Better handling of displaying long comments in the GUI ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64955](https://bz.apache.org/bugzilla/show_bug.cgi?id=64955)Keystore password not reset on reload - [Bug 65002](https://bz.apache.org/bugzilla/show_bug.cgi?id=65002)HTTP(S) Test Script recorder creates an invalid Basic authentication URL. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 65004](https://bz.apache.org/bugzilla/show_bug.cgi?id=65004)HTTP(S) Test Script recorder computes wrong HTTP Request breaking the application. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64543](https://bz.apache.org/bugzilla/show_bug.cgi?id=64543)On MacOSX, Darklaf- IntelliJ Theme throws NPE in javax.swing.ToolTipManager.initiateToolTip - [Bug 65024](https://bz.apache.org/bugzilla/show_bug.cgi?id=65024)Sending mime type with parameter throws IllegalArgumentException - [Bug 65029](https://bz.apache.org/bugzilla/show_bug.cgi?id=65029)Try harder to correctly guess the URL for applets, when download embedded URLs is enabled #### Other Samplers - [Bug 65034](https://bz.apache.org/bugzilla/show_bug.cgi?id=65034)Ignore `SocketTimeoutException` on `BinaryTCPClientImpl`, when no EOM Byte is set. Regression introduced by commit c190641e4f0474a34a366a72364b0a8dd25bfc81 which fixed [Bug 52104](https://bz.apache.org/bugzilla/show_bug.cgi?id=52104). That bug was bout handling the case of waiting for an EOM. #### Listeners - [Bug 64821](https://bz.apache.org/bugzilla/show_bug.cgi?id=64821)When importing XML formatted jtl files, sub samplers will get renamed - [Bug 65052](https://bz.apache.org/bugzilla/show_bug.cgi?id=65052)XPath2 Tester and JSON JMESPath Tester are missing in `view.results.tree.renderers_order` property #### Documentation - [Bug 64960](https://bz.apache.org/bugzilla/show_bug.cgi?id=64960)Change scheduler reference in Thread Group documentation. Contributed by Ori Marko - [Bug 65006](https://bz.apache.org/bugzilla/show_bug.cgi?id=65006)Illustration for completed HTTP Request Defaults element (Figure 4.4) contains misleading info #### General - [Bug 64957](https://bz.apache.org/bugzilla/show_bug.cgi?id=64957)When importing example test plan JMeter displays an NullPointerException - [Bug 64961](https://bz.apache.org/bugzilla/show_bug.cgi?id=64961)Darklaf: On Windows 7, NPE in BasicEditorPaneUI.cleanDisplayProperties with Darklaf Intellij - [Bug 64963](https://bz.apache.org/bugzilla/show_bug.cgi?id=64963)Blank comment tooltip is visible - [Bug 64969](https://bz.apache.org/bugzilla/show_bug.cgi?id=64969)RemoteJMeterEngineImpl#rexit doesn't unexport RemoteJMeterEngineImpl on exit. Contributed by luo_isaiah at qq.com - [Bug 64984](https://bz.apache.org/bugzilla/show_bug.cgi?id=64984)Darklaf LAF: Selecting a Test element does not work under certain screen resolutions on Windows. With the help of Jannis Weis - [Bug 65008](https://bz.apache.org/bugzilla/show_bug.cgi?id=65008)SampleResult.setIgnore() called from PostProcessor is not considered - [Bug 64993](https://bz.apache.org/bugzilla/show_bug.cgi?id=64993)Daklaf LAF: Menu navigation not working with keyboard shortcuts. With the help of Jannis Weis - [Bug 65013](https://bz.apache.org/bugzilla/show_bug.cgi?id=65013)POST multipart/form-data cURL code with quoted arguments is not imported correctly ## Non-functional changes - Updated SaxonHE to 9.9.1-8 (from 9.9.1-7) - Updated asm to 9.0 (from 7.3.1) - Updated bouncycastle to 1.67 (from 1.66) - Updated caffeine to 2.8.8 (from 2.8.0) - Updated commons-codec to 1.15 (from 1.14) - Updated commons-io to 2.8.0 (from 2.7) - Updated commons-net to 3.7.2 (from 3.7) - Updated jackson to 2.10.5 (from 2.10.3) - Updated junit to 4.13.1 (from 4.13) - Updated ph-commons to 9.5.1 (from 9.4.1) - Updated ph-css to 6.2.3 (from 6.2.1) - Updated groovy to 3.0.7 (from 3.0.5) - Updated xstream to 1.4.15 (from 1.4.14) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Ori Marko (orimarko at gmail.com) - 罗寅卓 (luo_isaiah at qq.com) - [Ubik Load Pack](https://ubikloadpack.com) - [Jannis Weis](https://github.com/weisJ/darklaf) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.4 Release Notes URL: https://docs.jmeter.ai/releases/5-4/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.4, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 1 | | Improvements | 13 | | Bug fixes | 24 | | Non-functional changes | 31 | ## New and Noteworthy ### UX improvements [Bug 62179](https://bz.apache.org/bugzilla/show_bug.cgi?id=62179)[Bug 64658](https://bz.apache.org/bugzilla/show_bug.cgi?id=64658)The splash screen is now application-modal rather than system-modal, so it does not block other applications when JMeter is starting up. ## Incompatible changes - Remove LogKit logger functionality from some classes. This was intended to completely remove `LoggingManager` class (it has been deprecated since JMeter 3.2), but as jmeter-plugins depended on it, `LoggingManager` and our `LogKit`-adapter will remain for this version (but is still deprecated). ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 53848](https://bz.apache.org/bugzilla/show_bug.cgi?id=53848)[Bug 63527](https://bz.apache.org/bugzilla/show_bug.cgi?id=63527)Implement a new setting to allow the exclusion of embedded URLs - [Bug 64696](https://bz.apache.org/bugzilla/show_bug.cgi?id=64696)[PR#571](https://github.com/apache/jmeter/pull/571)[PR#595](https://github.com/apache/jmeter/pull/595)Freestyle format for names in (Default)SamplerCreater. Based on a patch by Vincent Daburon (vdaburon at gmail.com) - [Bug 64752](https://bz.apache.org/bugzilla/show_bug.cgi?id=64752)Add GraphQL/HTTP Request Sampler. Contributed by woonsan. #### Other samplers - [Bug 64555](https://bz.apache.org/bugzilla/show_bug.cgi?id=64555)Set JMSType header field through JMSProperties. Contributed by Daniel van den Ouden #### Controllers #### Listeners - [PR#544](https://github.com/apache/jmeter/pull/544)Add BackendListener that sends "raw" results to InfluxDB. Contributed by Graham Russell (graham at ham1.co.uk) #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard - [Bug 64824](https://bz.apache.org/bugzilla/show_bug.cgi?id=64824)Dashboard/HTML Report: Rename `KO` to `FAIL` - [Bug 64936](https://bz.apache.org/bugzilla/show_bug.cgi?id=64936)Increase generate_report_ui.generation_timeout to 5 minutes to handle large performance test #### General - [Bug 64446](https://bz.apache.org/bugzilla/show_bug.cgi?id=64446)Better parse curl commands with backslash at line endings and support `PUT` method with data arguments - [PR#599](https://github.com/apache/jmeter/pull/599)Ensure all buttons added to the toolbar behave/look consistently. Contributed by Jannis Weis - [Bug 64581](https://bz.apache.org/bugzilla/show_bug.cgi?id=64581)Allow `SampleResult#setIgnore` to influence behaviour on Sampler Error - [Bug 64680](https://bz.apache.org/bugzilla/show_bug.cgi?id=64680)Fall back to `JMETER_HOME` on startup to detect JMeter's installation directory - [Bug 64787](https://bz.apache.org/bugzilla/show_bug.cgi?id=64787)[PR#630](https://github.com/apache/jmeter/pull/630)Add Korean translation. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 64776](https://bz.apache.org/bugzilla/show_bug.cgi?id=64776)Add the ability to install additional SecurityProvider. Contributed by Timo (ASF.Software.Timo at Leefers.eu) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64479](https://bz.apache.org/bugzilla/show_bug.cgi?id=64479)Regression: HTTP(s) Script Recorder prevents proper shutdown in non-GUI mode - [Bug 64653](https://bz.apache.org/bugzilla/show_bug.cgi?id=64653)Exclude Javascript and JSON from parsing for charsets from forms by proxy #### Other Samplers #### Controllers - [Bug 64795](https://bz.apache.org/bugzilla/show_bug.cgi?id=64795)Generate summary report may not output a summary line in the configured interval (`summariser.interval`): Clarify documentation #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64638](https://bz.apache.org/bugzilla/show_bug.cgi?id=64638)JSON JMESPath Assertion / JSON Assertion: Opening GUI shows a horizontal scrollbar that keeps sliding - [Bug 64915](https://bz.apache.org/bugzilla/show_bug.cgi?id=64915)JMeter Cache Manager misbehaving when "Use Cache-Control/Expires header" is checked #### Functions #### I18N #### Report / Dashboard - [Bug 64547](https://bz.apache.org/bugzilla/show_bug.cgi?id=64547)Report/Dashboard: Ensure graphs Response codes per second is not broken by empty response code in SampleResult. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64617](https://bz.apache.org/bugzilla/show_bug.cgi?id=64617)HTML report: In graph Response Time Percentiles Over Time 90,95,99th percentile correspond in reality to 0.90, 0.95 and 0.99 percentiles - [Bug 64553](https://bz.apache.org/bugzilla/show_bug.cgi?id=64553)When using Transaction Controller, send Bytes and Received Bytes are displayed as 0 in the influxdb(BackendListener) - [Bug 64624](https://bz.apache.org/bugzilla/show_bug.cgi?id=64624)Use less aggressive escaping for JSON Strings in reports error messages #### Documentation - [PR#571](https://github.com/apache/jmeter/pull/571)Correct documented name of generated CA when using proxy script recorder. Part of a bigger PR. Vincent Daburon (vdaburon at gmail.com) - Change documentation of the special header functionality of the mirror server to reflect the implementation. #### General - [Bug 64448](https://bz.apache.org/bugzilla/show_bug.cgi?id=64448)User Defined Variable Duplication in Right Click Context Menu - [Bug 64499](https://bz.apache.org/bugzilla/show_bug.cgi?id=64499)Exiting JMeter when `jmeterengine.stopfail.system.exit=true` takes too much time if threads are not stopped - [Bug 64510](https://bz.apache.org/bugzilla/show_bug.cgi?id=64510)Darklaf- IntelliJ Theme throws NPE in DarkTreeUI on MacOS - [Bug 64594](https://bz.apache.org/bugzilla/show_bug.cgi?id=64594)Unable to enter variable values instead of numeric values in components using PowerTableModel (Impacts 3rd party plugins like Throughput Shaping Timer) - [Bug 64475](https://bz.apache.org/bugzilla/show_bug.cgi?id=64475)Menu Generate HTML Report: When report generation fails due to timeout, error message is not explicit. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64627](https://bz.apache.org/bugzilla/show_bug.cgi?id=64627)Programmatic manipulation of the control flow via API methods of JMeterContext is not working as it used to before 5.0. Contributed by Till Neunast - [Bug 64647](https://bz.apache.org/bugzilla/show_bug.cgi?id=64647)groovy-dateutil is missing in distribution - [Bug 64640](https://bz.apache.org/bugzilla/show_bug.cgi?id=64640)Darklaf: NPE at com.github.weisj.darklaf.ui.DarkPopupFactory.getPopupType(DarkPopupFactory.java:96) - [Bug 64641](https://bz.apache.org/bugzilla/show_bug.cgi?id=64641)Darklaf: NPE at com.github.weisj.darklaf.ui.tree.DarkTreeUI.isChildOfSelectionPath(DarkTreeUI.java:603) ~[darklaf-core-2.4.2-SNAPSHOT.jar:2.4.2-SNAPSHOT] - [Bug 64453](https://bz.apache.org/bugzilla/show_bug.cgi?id=64453)Darklaf: Save Test Plan as New Folder failure - [Bug 64625](https://bz.apache.org/bugzilla/show_bug.cgi?id=64625)Darklaf: trying to select a folder in Browse leads to an error popup and stacktrace - [Bug 64711](https://bz.apache.org/bugzilla/show_bug.cgi?id=64711)Textarea Colors are not good in dark modes. Contributed by Jannis Weis - [Bug 64935](https://bz.apache.org/bugzilla/show_bug.cgi?id=64935)A broken plugin class should not prevent JMeter from starting ## Non-functional changes - Build system upgraded from Gradle to 6.7 (from 6.6) - [PR#594](https://github.com/apache/jmeter/pull/594)Updated neo4j-java-driver to 4.2.0 (from 1.7.5) - [Bug 64454](https://bz.apache.org/bugzilla/show_bug.cgi?id=64454)More precise error message, when no datasource value can be found in JDBC sampler - [Bug 64440](https://bz.apache.org/bugzilla/show_bug.cgi?id=64440)Log exeptions reported via `JMeterUtils#reportToUser` even when in GUI mode - [PR#591](https://github.com/apache/jmeter/pull/591)Remove deprecated sudo flag from travis file. Deng Liming (liming.d.pro at gmail.com) - Updated Darklaf to 2.4.10 (from 2.1.1) - Updated Groovy to 3.0.5 (from 3.0.3) - [PR#596](https://github.com/apache/jmeter/pull/596)Use neutral words in documentation - [Bug 63809](https://bz.apache.org/bugzilla/show_bug.cgi?id=63809)[PR#557](https://github.com/apache/jmeter/pull/557)Updated commons-collections to 4.4 (from 3.2.2) while keeping the jars for the old commons-collections 3.x for compatibility - [PR#598](https://github.com/apache/jmeter/pull/598)Add another option for creating diffs to the building page. Contributed by jmetertea (github.com/jmetertea) - [PR#609](https://github.com/apache/jmeter/pull/609)Make use of newer API for darklaf installation. Jannis Weis - [PR#612](https://github.com/apache/jmeter/pull/612)Correct typos in `README.md`. Based on patches by Pooja Chandak (poojachandak002 at gmail.com) - [PR#613](https://github.com/apache/jmeter/pull/613)Add documentation for Darklaf properties. Jannis Weis - Update SpotBugs to 4.1.2 (from 4.1.1), upgrade spotbugs-gradle-plugin to 4.5.0 (from 2.0.0) - Update org.sonarqube Gradle plugin to 3.0 (from 2.7.1) - Update Apache ActiveMQ to 5.16.0 (from 5.15.11) - Update Bouncycastle to 1.66 (from 1.64) - Update Apache commons-io to 2.7 (from 2.6) - Update Apache commons-lang3 to 3.11 (from 3.10) - Update Apache commons-net to 3.7 (from 3.6) - Update Apache commons-pool2 to 2.9.0 (from 2.8.0) - Update Apache commons-text to 1.9 (from 1.8) - Update equalsverifier to 3.4.2 (from 3.1.13) - Update junit5 to 5.6.2 (from 5.6.0) - Update Apache log4j2 to 2.13.3 (from 2.13.1) - Update rsyntaxtextarea to 3.1.1 (from 3.1.0) - Update JUnit5 to 5.7.0 (from 5.6.2) - Update Rhino to 1.7.13 (from 1.7.12) - Update XStream to 1.4.14 (from 1.4.14.1) - Update Apache commons-dbcp2 to 2.8.0 (from 2.7.0) - [PR#635](https://github.com/apache/jmeter/pull/635)Correct some image ratios in the documentation. Patch provided by Vincent Daburon (vdaburon at gmail.com) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Michael Weidmann (https://github.com/michaelweidmann) - Deng Liming (liming.d.pro at gmail.com) - jmetertea (https://github.com/jmetertea) - [Ubik Load Pack](https://ubikloadpack.com) - [Jannis Weis](https://github.com/weisJ/darklaf) - [Daniel van den Ouden](https://github.com/topicus-pw-dvdouden) - Till Neunast (https://github.com/tilln) - Pooja Chandak (poojachandak002 at gmail.com) - Vincent Daburon (vdaburon at gmail.com) - Woonsan Ko (woonsan at apache.org) - Timo (ASF.Software.Timo at Leefers.eu) - Graham Russell (graham at ham1.co.uk) We also thank bug reporters who helped us improve JMeter. - Hiroyoshi Mitsumori (mitsumori at mis.dev) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.3 Release Notes URL: https://docs.jmeter.ai/releases/5-3/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.3, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 2 | | Improvements | 27 | | Bug fixes | 19 | | Non-functional changes | 34 | ## New and Noteworthy ### UX improvements Added [Darklaf](https://github.com/weisJ/darklaf) look and feel that improves several components. Tree indentation level is easier to follow: ![JMeter tree with Darklaf Darcula theme](/images/screenshots/changes/5.3/tree_theme_darcula.png) _JMeter tree with Darklaf Darcula theme_ ![JMeter tree with Darklaf IntelliJ theme](/images/screenshots/changes/5.3/tree_theme_intellij.png) _JMeter tree with Darklaf IntelliJ theme_ New look and feel themes. Light: IntellJ, Solarized Light, HighContrast Light. Dark: OneDark, Solarized Dark, HighContrast Dark. When an element in tree is disabled, all its descendants are shown in gray. For instance, `While Contoller` is disabled in the following tree, so its children are gray. It is purely a UI change, and the behavior is not altered. ![While controller is disabled, so its children are gray](/images/screenshots/changes/5.3/disabled_subtree.png) _While controller is disabled, so its children are gray_ Tree context menu is shown even in case the node selection is changed. Previously the popup did disappear and it was required to select a node first and only then launch popup. Look and feel can now be updated without a restart Use `CTRL + ALT + wheel` for zooming fonts. Previous shortcut was `CTRL + SHIFT + wheel`, however, it conflicted with horizontal scrolling. In-app zoom is more consistent (e.g. sometimes not all the labels or even panels were scaled). For instance: log viewer, JSR223 code editor were not previously scaled with zoom-in/out feature Tree context menu is shown for the full row, not for the label only Undo and redo support for editable fields. Keystrokes are `CTRL + Z` / `CTRL + SHIFT + Z`, or `CMD + Z`/ `CMD + SHIFT + Z` depending on the operating system. Undo is implemented on a field level basis (each fields has its own history), and the history is invalidated when tree selection changes. Mark the currently selected language in the options menu. Mark the currently selected log level in the options menu. Rework of many Test Element UI (JUnit Request, ForEach Controller, If Controller, Throughput Controller, WhileController, Counter Config, XPath2 Extractor, Function Helper Dialog, Search popup, JMS Elements) ## Incompatible changes - Default value of `httpclient4.time_to_live` has been modified from `2000` to `60000`, this means HTTP connections will live longer than before. This has impact on connection creation and SSL handshake, see [Bug 64289](https://bz.apache.org/bugzilla/show_bug.cgi?id=64289) - The update to Groovy 3 ([PR#590](https://github.com/apache/jmeter/pull/590)) might break some old Groovy code of your tests. Have a look at [the update notes for Groovy 3](https://groovy-lang.org/releasenotes/groovy-3.0.html) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 64160](https://bz.apache.org/bugzilla/show_bug.cgi?id=64160)Test HTTP/S Test Script Recorder: Name transaction controller/ simple controller using prefix without "`-XXXX`" suffix - [Bug 64289](https://bz.apache.org/bugzilla/show_bug.cgi?id=64289)Make `httpclient4.time_to_live` to `60000` to be closer to typical browser behavior #### Other samplers - [Bug 64288](https://bz.apache.org/bugzilla/show_bug.cgi?id=64288)JUnit Request: Improve UX - [Bug 64407](https://bz.apache.org/bugzilla/show_bug.cgi?id=64407)Improve JMS Publisher UX. Contributed by Ubik Load Pack (https://ubikloadpack.com) - [Bug 64408](https://bz.apache.org/bugzilla/show_bug.cgi?id=64408)Improve JMS Subscriber UX. Contributed by Ubik Load Pack (https://ubikloadpack.com) #### Controllers - [Bug 64277](https://bz.apache.org/bugzilla/show_bug.cgi?id=64277)ForEach Controller: Improve UX - [Bug 64280](https://bz.apache.org/bugzilla/show_bug.cgi?id=64280)If Controller: Improve UX - [Bug 64282](https://bz.apache.org/bugzilla/show_bug.cgi?id=64282)Throughput Controller: Improve UX - [Bug 64287](https://bz.apache.org/bugzilla/show_bug.cgi?id=64287)WhileController: Improve UX #### Listeners - [Bug 64150](https://bz.apache.org/bugzilla/show_bug.cgi?id=64150)View Results Tree: Allow editing of response data in testers - [Bug 63822](https://bz.apache.org/bugzilla/show_bug.cgi?id=63822)View Results Tree: Keep position of split pane while switching renderer mode #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64091](https://bz.apache.org/bugzilla/show_bug.cgi?id=64091)Precise Throughput Timer schedule generation is improved significantly (e.g. 2 seconds for 10M samples) - [Bug 64281](https://bz.apache.org/bugzilla/show_bug.cgi?id=64281)Counter Config: Improve UX - [Bug 64283](https://bz.apache.org/bugzilla/show_bug.cgi?id=64283)XPath2 Extractor: Improve UX #### Functions - [Bug 64070](https://bz.apache.org/bugzilla/show_bug.cgi?id=64070)`_timeshift` function does not work with offset formatters - [Bug 64275](https://bz.apache.org/bugzilla/show_bug.cgi?id=64275)Function Helper Dialog: Improve UX #### I18N - [Bug 64102](https://bz.apache.org/bugzilla/show_bug.cgi?id=64102)Add Chinese translation for Tools menu. Contributed by Liu XP (liu_xp2003 at sina.com) #### Report / Dashboard - [Bug 64380](https://bz.apache.org/bugzilla/show_bug.cgi?id=64380)Add a '`Median`' field to the dashboard and make the response time percentile fields support floating-point numbers. Contributed by Keith Mo(https://github.com/keithmork) - [Bug 64378](https://bz.apache.org/bugzilla/show_bug.cgi?id=64378)HTML report generation should not fail if a plugin has registered a graph and is not more present in classpath, issue a warning instead #### General - [Bug 63458](https://bz.apache.org/bugzilla/show_bug.cgi?id=63458)[PR#551](https://github.com/apache/jmeter/pull/551)Add new template "Functional Testing Test Plan [01]". Contributed by Sebastian Boga (sebastian.boga at endava.com) - [Bug 64119](https://bz.apache.org/bugzilla/show_bug.cgi?id=64119)Use first renderer from `view.results.tree.renderers_order` property as default in View Results Tree - [Bug 64148](https://bz.apache.org/bugzilla/show_bug.cgi?id=64148)Use gray icons for disabled elements in the tree, display subtree as gray - [Bug 64198](https://bz.apache.org/bugzilla/show_bug.cgi?id=64198)Allow spaces in `\${...}` expressions around functions. - [Bug 64276](https://bz.apache.org/bugzilla/show_bug.cgi?id=64276)Search popup: Improve UX - [PR#573](https://github.com/apache/jmeter/pull/573)Improve the startup time: skip test plan UI initialization - [PR#585](https://github.com/apache/jmeter/pull/585)Added JEXL3 as a syntax alias for JSyntaxTextArea. Contributed by drivera-armedia (https://github.com/drivera-armedia) - [PR#590](https://github.com/apache/jmeter/pull/590)Update Groovy to 3.0.3. ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 64400](https://bz.apache.org/bugzilla/show_bug.cgi?id=64400)Make sorting recorded samples into transaction controllers more predictable - [Bug 64267](https://bz.apache.org/bugzilla/show_bug.cgi?id=64267)When preemptive auth is disabled HTTP Sampler does not automatically respond to Basic Auth challenge #### Other Samplers #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 64091](https://bz.apache.org/bugzilla/show_bug.cgi?id=64091)Precise Throughput Timer might produce less samples when low test duration is used - [Bug 64142](https://bz.apache.org/bugzilla/show_bug.cgi?id=64142)Presence of DebugPostProcessor in Test plan breaks ActiveThread Over time in report due to missing information - [Bug 64196](https://bz.apache.org/bugzilla/show_bug.cgi?id=64196)Recurse into sub samplers more deeply when checking assertions - [Bug 64196](https://bz.apache.org/bugzilla/show_bug.cgi?id=64196)Recurse into sampleResults for `AbstractScopedTestElement#getSampleList` - [Bug 64381](https://bz.apache.org/bugzilla/show_bug.cgi?id=64381)PreciseThroughputTimer: On termination, log message contains negative value #### Functions #### I18N #### Report / Dashboard - [Bug 64059](https://bz.apache.org/bugzilla/show_bug.cgi?id=64059)Response Time Percentiles Over Time, unable to change the percentiles #### Documentation - [PR#547](https://github.com/apache/jmeter/pull/547)Correct Log level documentation. Contributed by jmetertea - [PR#548](https://github.com/apache/jmeter/pull/548)Correct typos in documentation. Contributed by jmetertea - [Bug 64022](https://bz.apache.org/bugzilla/show_bug.cgi?id=64022)Correct Chinese translation for "Ignore Sub-Controller blocks". Provided by yangxiaofei77 (yangxiaofei77 at gmail.com) - [PR#552](https://github.com/apache/jmeter/pull/552)Fix `client.rmi.localport` port allocation description. Contributed by anant-93 - [PR#543](https://github.com/apache/jmeter/pull/543)Clarify documentation of `__StringToFile` function regarding default value of `Append to file?` parameter. Contributed by Ori Marko - [Bug 64302](https://bz.apache.org/bugzilla/show_bug.cgi?id=64302)Correct links to JMeter API in printable docs and BeanShell best practices and to JavaFX implementation website in all docs. Reported by 2477441814 (2477441814 at qq.com) #### General - [Bug 63945](https://bz.apache.org/bugzilla/show_bug.cgi?id=63945)NPE when opening a file after file system change - [Bug 64034](https://bz.apache.org/bugzilla/show_bug.cgi?id=64034)Shell scripts fail if space in `JAVA_HOME` path. Contributed by ray7219 (ray7219 at hotmail.com) - [Bug 63856](https://bz.apache.org/bugzilla/show_bug.cgi?id=63856)Set `connectTime` on parent samples when using a transaction controller - [Bug 64227](https://bz.apache.org/bugzilla/show_bug.cgi?id=64227)Error when loading Templates on Windows - TestPlan UI: skip adding the entry to the classpath if the user clicks cancel ## Non-functional changes - Build system upgraded from Gradle to 6.3 (from 6.1), Java 14 can be used now for the build - [Bug 63963](https://bz.apache.org/bugzilla/show_bug.cgi?id=63963)[PR#546](https://github.com/apache/jmeter/pull/546)Updated jackson to 2.10.3 (from 2.9.10) - [Bug 64120](https://bz.apache.org/bugzilla/show_bug.cgi?id=64120)Updated jsoup to 1.13.1 (from 1.12.1) - [Bug 63809](https://bz.apache.org/bugzilla/show_bug.cgi?id=63809)Updated commons-dbcp2 to 2.7.0 (from 2.5.0) - Updated Apache ActiveMQ to 5.15.11 (from 5.15.8) - Updated bouncycastle to 1.64 (from 1.60) - Updated asm to 7.3.1 (from 7.1) - Updated Apache commons-codec to 1.14 (from 1.13) - Updated Apache commons-pool to 2.8.0 (from 2.7.0) - Updated equalsverifier to 3.1.9 (from 3.1.12) - Updated Apache Groovy to 2.4.18 (from 2.4.16) - Updated hsqldb to 2.5.0 (from 2.4.1) - Updated hamcrest to 2.2 (from 2.1) - Updated Apache httpclient and httpmime to 4.5.12 (from 4.5.10) - Updated Apache httpcore and httpcore-nio to 4.4.13 (from 4.4.12) - Updated Apache Tika to 1.24.1 (from 1.22) - Updated jmespath to 0.5.0 (from 0.3.0) - Updated Apache log4j to 2.13.1 (from 2.12.1) - Updated junit4 to 4.13 (from 4.12) - Updated junit5 to 5.6.0 (from 5.5.1) - Updated slf4j to 1.7.30 (from 1.7.28) - Updated ph-commons to 9.4.1 (from 9.3.7) - Updated ph-css to 6.2.2 (from 6.2.0) - Updated rsyntaxtextarea to 3.1.0 (from 3.0.4) - Updated rhino to 1.7.12 (from 1.7.11) - Updated SaxonHE to 9.9.1-7 (from 9.9.1-5) - Updated cglib to 3.2.12 (from 3.2.9) - Updated commons-lang3 to 3.10 (from 3.9) - Updated freemarker to 2.3.30 (from 2.3.29) - Updated hamcrest-date to 2.0.7 (from 2.0.4) - Updated equalsverifier to 3.1.13 (from 3.1.12) - Updated xstream to 1.4.11.1 (from 1.4.11) - [PR#559](https://github.com/apache/jmeter/pull/559)Add a note to the source of TrustAllSSLSocketFactory, that it is not secure to trust everyone. Based on a PR from YYTVicky (yytvicky at github) - [PR#588](https://github.com/apache/jmeter/pull/588)Add documentation on usage of InfluxDB v2 for real-time results. Based on PR from Jakub Bednář (jakub.bednar at gmail.com) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Jannis Weis](https://github.com/weisJ/darklaf) - Stefan Seide (stefan at trilobyte-se.de) - jmetertea - ray7219 - Sebastian Boga (sebastian.boga at endava.com) - Liu XP (liu_xp2003 at sina.com) - anant-93 (https://github.com/anant-93) - Ori Marko (orimarko at gmail.com) - Keith Mo(https://github.com/keithmork) - drivera-armedia (https://github.com/drivera-armedia) - [Ubik Load Pack](https://ubikloadpack.com) - Jakub Bednář (jakub.bednar at gmail.com) We also thank bug reporters who helped us improve JMeter. - Michael McDermott (mcdermott.michaelj at gmail.com) - yangxiaofei77 (yangxiaofei77 at gmail.com) - Markus Wolf (wolfm at t-systems.com) - Pierre Astruc (pierre.astruc at evertest.com) - YYTVicky (yytvicky at github) - 2477441814 at qq.com Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.2.1 Release Notes URL: https://docs.jmeter.ai/releases/5-2-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.2.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Improvements | 1 | | Bug fixes | 3 | ## New and Noteworthy This release is a minor bugfix release. Please see the [Changes history page](/user-manual/changes-history/) to view the last release notes of version 5.2. ## Incompatible changes ## Improvements #### HTTP Samplers and Test Script Recorder #### Other samplers - [Bug 63926](https://bz.apache.org/bugzilla/show_bug.cgi?id=63926)JDBC Connection Configuration: Add ability to set connection properties #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard #### General ## Bug fixes #### HTTP Samplers and Test Script Recorder #### Other Samplers #### Controllers #### Listeners - [Bug 63906](https://bz.apache.org/bugzilla/show_bug.cgi?id=63906)NPE for InfluxDB backend listener during failover testing #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions #### I18N #### Report / Dashboard #### Documentation #### General - [Bug 63910](https://bz.apache.org/bugzilla/show_bug.cgi?id=63910)Broken maven poms in released 5.2 version - [Bug 63911](https://bz.apache.org/bugzilla/show_bug.cgi?id=63911)ApacheJMeter_config.jar content has changed (bin moved to run and missing files) ## Non-functional changes ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Vincent Lee](https://github.com/vincentclee) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.2 Release Notes URL: https://docs.jmeter.ai/releases/5-2/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.2, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 3 | | Improvements | 46 | | Bug fixes | 26 | | Non-functional changes | 8 | ## New and Noteworthy This release is a major release. Please see the [Changes history page](/user-manual/changes-history/) to view the last release notes of version 5.1.1. ## Incompatible changes - HTTP(S) Test Script Recorder now appends number at end of names, while previously it added it at beginning. See [Bug 63450](https://bz.apache.org/bugzilla/show_bug.cgi?id=63450) - When using XPath Assertion with an XPath expression returning a boolean, `True if nothing matches` had no effect and always returned true, see [Bug 63455](https://bz.apache.org/bugzilla/show_bug.cgi?id=63455) - XML parsing now refuses unsecure XML, this has impacts on the following features: - XMLAssertion - XMLSchemAssertion - XPath function - XPath 1 & 2 Extractors - XPath 1 & 2 Assertions ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 63450](https://bz.apache.org/bugzilla/show_bug.cgi?id=63450)HTTP(S) Test Script Recorder: Put number at end instead of beginning - [Bug 63790](https://bz.apache.org/bugzilla/show_bug.cgi?id=63790)Embedded Resources download: Optimize CSS parsing by removing source location #### Other samplers - [Bug 63406](https://bz.apache.org/bugzilla/show_bug.cgi?id=63406)JDBC connection configuration: new option for pre-initialize to initialize the connection pool. Contributed by Franz Schwab (franz.schwab at exasol.com) - [Bug 63561](https://bz.apache.org/bugzilla/show_bug.cgi?id=63561)JDBC Request: Allow to only fetch a certain number of rows. Contributed by Franz Schwab (franz.schwab at exasol.com) - [Bug 63801](https://bz.apache.org/bugzilla/show_bug.cgi?id=63801)Add Bolt protocol support for Neo4j database. Contributed by GraphAware (www.graphaware.com) #### Controllers - [Bug 63565](https://bz.apache.org/bugzilla/show_bug.cgi?id=63565)If Controller: GC issue with JMeter during the endurance run when using with "Interpret Condition as Variable Expression?" unchecked => Improve documentation #### Listeners - [Bug 63720](https://bz.apache.org/bugzilla/show_bug.cgi?id=63720)BackendListener: InfluxDBBackendListenerClient Add support for InfluxDB 2. Contributed by Jakub Bednář (https://github.com/bednar) - [Bug 63770](https://bz.apache.org/bugzilla/show_bug.cgi?id=63770)View Results Tree: Add JMESPath Tester. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62863](https://bz.apache.org/bugzilla/show_bug.cgi?id=62863)Enable PKCS11 keystores for usage with KeyStore Manager. Based on patch by Clifford Harms (clifford.harms at gmail.com). - [PR#457](https://github.com/apache/jmeter/pull/457)Slight performance improvement in PoissonRandomTimer by using ThreadLocalRandom. Based on a patch by Xia Li. - [Bug 62787](https://bz.apache.org/bugzilla/show_bug.cgi?id=62787)New `XPath2 Assertion` supporting XPath2 with better performances than `XPath Assertion`. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63643](https://bz.apache.org/bugzilla/show_bug.cgi?id=63643)Skip BOM on files opened through `FileServer` and use the BOM to detect the character encoding, if none is given explicitly. Reported by Havlicek Honza (havlicek.honza at gmail.com) - [Bug 63727](https://bz.apache.org/bugzilla/show_bug.cgi?id=63727)New `JMESPath Extractor` element to ease extraction from JSON using [JMESPath](http://jmespath.org) technology. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63763](https://bz.apache.org/bugzilla/show_bug.cgi?id=63763)New `JMESPath Assertion` element to ease assertion on JSON using [JMESPath](http://jmespath.org) technology. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63775](https://bz.apache.org/bugzilla/show_bug.cgi?id=63775)Allow Boundary Extractor to accept empty boundaries #### Functions - [Bug 63219](https://bz.apache.org/bugzilla/show_bug.cgi?id=63219)New function `__StringToFile` to save/append a string into a file. Contributed by Ubik Load Pack (support at ubikloadpack.com) - Use `AtomicInteger` for `__counter` instead of synchronization on our own #### I18N #### Report / Dashboard - [Bug 63471](https://bz.apache.org/bugzilla/show_bug.cgi?id=63471)`StringConverter`s used for report generation should ignore white space around numbers. #### General - [Bug 63396](https://bz.apache.org/bugzilla/show_bug.cgi?id=63396)JSR223 Test Elements: Description of Parameters is misleading, same for Script - [Bug 63480](https://bz.apache.org/bugzilla/show_bug.cgi?id=63480)XPathAssertion and XPathAssertion2: Improve test coverage for input coming from variable. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63452](https://bz.apache.org/bugzilla/show_bug.cgi?id=63452)Tools / Import from cURL: Complete coverage of all command line options that are valid in JMeter use case. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63419](https://bz.apache.org/bugzilla/show_bug.cgi?id=63419)Tools / Import from cURL: Add ability to import a set of cURL commands from a file. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63760](https://bz.apache.org/bugzilla/show_bug.cgi?id=63760)JOrphanUtils: add random alphanumeric password generator - [Bug 63355](https://bz.apache.org/bugzilla/show_bug.cgi?id=63355)View Results Tree: Browser view option is not Available since Java 11, document how to make it available, see [this](/./usermanual/hints-and-tips/#browser_renderer_view_results_tree) - [Bug 62861](https://bz.apache.org/bugzilla/show_bug.cgi?id=62861)Thread Group: Provide ability to configure whether a new iteration is a new user or same user (Would be applied on Cookie Manager, Cache Manager and httpclient.reset_state_on_thread_group_iteration). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63616](https://bz.apache.org/bugzilla/show_bug.cgi?id=63616)Fix Javadoc: ``` JMeterContext#getThreadNum() ``` starts at 0 and not 1. Contributed by Ori Marko (orimarko at gmail.com) - Updated to httpclient/httpmime 4.5.10 (from 4.5.7) - Updated to dnsjava 2.1.9 (from 2.1.8) - Updated to jsoup 1.12.1 (from 1.11.3) - Updated to rsyntaxtextarea 3.0.4 (from 3.0.2) - Updated to caffeine 2.8.0 (from 2.6.2) - Updated to commons-codec 1.13 (from 1.11) - Updated to commons-lang3 3.9 (from 3.8.1) - Updated to commons-pool 2.7 (from 2.6) - Updated to commons-text 1.8 (from 1.6) - Updated to freemarker 2.3.29 (from 2.3.28) - Updated to httpcore/httpcore-nio 4.12 (from 4.11) - Updated to jodd 5.0.13 (from 5.0.6) - Updated to log4j 2.12.1 (from 2.11.1) - Updated to ph-commons 9.3.7 (from 9.2.1) - Updated to ph-css 6.2.0 (from 6.1.1) - Updated to Mozilla Rhino 1.7.11 (from 1.7.10) - Updated to Saxon-HE 9.9.1-5 (from 9.9.1-1) - Updated to slf4j 1.7.28 (from 1.7.25) - Updated to tika-core and tika-parsers 1.22 (from 1.21) - Updated jackson-annotations, jackson-core and jackson-databind to 2.9.10 (from 2.9.8) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 63298](https://bz.apache.org/bugzilla/show_bug.cgi?id=63298)HTTP Requests with encoded URLs are being sent in decoded format - [Bug 63364](https://bz.apache.org/bugzilla/show_bug.cgi?id=63364)When setting `subresults.disable_renaming=true`, sub results are still renamed using their parent SampleLabel while they shouldn't. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63129](https://bz.apache.org/bugzilla/show_bug.cgi?id=63129)JMeter can not identify encoding during first time page submission. Based partly on analysis and PR made by Naveen Nandwani (naveen.nandwani at india.nec.com) - [Bug 62672](https://bz.apache.org/bugzilla/show_bug.cgi?id=62672)HTTP Request sends double requests when using proxy with authentication. Based on patch by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 63574](https://bz.apache.org/bugzilla/show_bug.cgi?id=63574)HTTP Cache Manager does not cache resource if `Cache-Control` header is missing. #### Other Samplers - [Bug 63442](https://bz.apache.org/bugzilla/show_bug.cgi?id=63442)Reduce scanning for `LogParser` implementations in AccessLogSamplerBeanInfo. - [Bug 63563](https://bz.apache.org/bugzilla/show_bug.cgi?id=63563)LdapExtSampler: When sampler fails with exception differing from NamingException, no SampleResult is generated - [Bug 63469](https://bz.apache.org/bugzilla/show_bug.cgi?id=63469)JMSPublisher: Race condition in jms.client.ClientPool#clearClient #### Controllers #### Listeners - [Bug 63319](https://bz.apache.org/bugzilla/show_bug.cgi?id=63319)`ArrayIndexOutOfBoundsException` in Aggregate Graph when selecting 90 % or 95 % columns - [Bug 63423](https://bz.apache.org/bugzilla/show_bug.cgi?id=63423)Selection of table rows in Aggregate Graph gets lost too often - [Bug 63347](https://bz.apache.org/bugzilla/show_bug.cgi?id=63347)View result tree: The search field is so small that even a single character is not visible on Windows 7 - [Bug 63433](https://bz.apache.org/bugzilla/show_bug.cgi?id=63433)ListenerNotifier: Detected problem in Listener NullPointerException if filename is null. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63674](https://bz.apache.org/bugzilla/show_bug.cgi?id=63674)Strip results with subresults deeper in their hierarchy when DataStripping is enabled #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 63455](https://bz.apache.org/bugzilla/show_bug.cgi?id=63455)XPath Assertion: `True if nothing matches` does not work if XPath expression returns a boolean. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Functions #### I18N #### Report / Dashboard #### Documentation - [Bug 63513](https://bz.apache.org/bugzilla/show_bug.cgi?id=63513)Add MariaDB examples to JDBC documentation. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 63484](https://bz.apache.org/bugzilla/show_bug.cgi?id=63484)Add notes to use Apache Velocity as JSR223 script language. Based on a patch by Ori Marko (orimarko at gmail.com) - [Bug 63519](https://bz.apache.org/bugzilla/show_bug.cgi?id=63519)[PR#471](https://github.com/apache/jmeter/pull/471)Use correct method `getLabelResource()` in JMeter tutorial. Contributed by Sun Tao (buzzerrookie at hotmail.com>) #### General - [Bug 63394](https://bz.apache.org/bugzilla/show_bug.cgi?id=63394)JMeter should fail with non-zero when test execution fails (due to missing test plan or other reason). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63464](https://bz.apache.org/bugzilla/show_bug.cgi?id=63464)image/svg+xml is wrongly considered as binary - [Bug 63490](https://bz.apache.org/bugzilla/show_bug.cgi?id=63490)At end of scheduler duration lots of Samplers gets executed at the same time - [PR#480](https://github.com/apache/jmeter/pull/480)[PR#482](https://github.com/apache/jmeter/pull/482)Fix a few typos in comments and log messages. Based on patch by Anass Benomar (anassbenomar at gmail.com) - [Bug 63751](https://bz.apache.org/bugzilla/show_bug.cgi?id=63751)Correct a typo in Chinese translations. Reported by Jinliang Wang (wjl31802 at 126.com) - [Bug 63723](https://bz.apache.org/bugzilla/show_bug.cgi?id=63723)Distributed testing: JMeter controller node ends distributed test though some threads still are active - [Bug 63614](https://bz.apache.org/bugzilla/show_bug.cgi?id=63614)Distributed testing: Unable to generate Dashboard report at end of load test - [Bug 63862](https://bz.apache.org/bugzilla/show_bug.cgi?id=63862) Search Dialog / Search in View Results Tree: Uncaught exception if regex is checked and regex is invalid - [Bug 63793](https://bz.apache.org/bugzilla/show_bug.cgi?id=63793)Fix unsecure XML Parsing ## Non-functional changes - Migrated from subversion to [Git](https://github.com/apache/jmeter) - [Bug 63630](https://bz.apache.org/bugzilla/show_bug.cgi?id=63630)Switch build from Apache Ant to Gradle - [Bug 63529](https://bz.apache.org/bugzilla/show_bug.cgi?id=63529)Add more unit tests for org.apache.jorphan.util.JOrphanUtils. Contributed by John Bergqvist(John.Bergqvist at diffblue.com) - Updated to latest checkstyle (version 8.22) - Clean-up of code in `CompareAssertion` and other locations. Based on patch by Graham Russell (graham at ham1.co.uk) - [PR#491](https://github.com/apache/jmeter/pull/491)Increase Graphite metrics coverage. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#520](https://github.com/apache/jmeter/pull/520)Replace anonymous classes with lambda expressions. Contributed by Graham Russell (graham at ham1.co.uk). - [PR#524](https://github.com/apache/jmeter/pull/524)Migration from JUnit 4 to JUnit 5. Contributed by Graham Russell (graham at ham1.co.uk). ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Clifford Harms (clifford.harms at gmail.com) - [Ubik Load Pack](https://ubikloadpack.com) - Xia Li - Naveen Nandwani (naveen.nandwani at india.nec.com) - Artem Fedorov (artem.fedorov at blazemeter.com) - Ori Marko (orimarko at gmail.com) - Sun Tao (buzzerrookie at hotmail.com) - John Bergqvist (John.Bergqvist at diffblue.com) - Franz Schwab (franz.schwab at exasol.com) - Graham Russell (graham at ham1.co.uk) - Anass Benomar (anassbenomar at gmail.com) - [Jakub Bednář](https://github.com/bednar) - Pascal Schumacher (pascalschumacher at apache.org) - [GraphAware](https://graphaware.com/) We also thank bug reporters who helped us improve JMeter. - Sergiy Iampol (sergiy.iampol at playtech.com) - Brian Tully (brian.tully at acquia.com) - Amer Ghazal (amerghazal at gmail.com) - Stefan Seide (stefan at trilobyte-se.de) - Havlicek Honza (havlicek.honza at gmail.com) - Pierre Astruc (pierre.astruc at evertest.com) - Jinliang Wang (wjl31802 at 126.com) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.1.1 Release Notes URL: https://docs.jmeter.ai/releases/5-1-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.1.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Improvements | 6 | | Bug fixes | 10 | | Non-functional changes | 4 | ## New and Noteworthy This release is mainly a bugfix release. Please see the [Changes history page](/user-manual/changes-history/) to view the last major behaviors with the version 5.1. ### Live Reporting and Web Report A new menu entry has been added to the **Tools** menu. It's allow to generate a results report from a previous CSV/JTL file. ![changes/5.1.1/01_menu_generate_report.png](/images/screenshots/changes/5.1.1/01_menu_generate_report.png) ![changes/5.1.1/02_windows_generate_report.png](/images/screenshots/changes/5.1.1/02_windows_generate_report.png) ## Incompatible changes ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62977](https://bz.apache.org/bugzilla/show_bug.cgi?id=62977)Allow sending HTTP requests without a default User-Agent header #### Other samplers - [Bug 63185](https://bz.apache.org/bugzilla/show_bug.cgi?id=63185)LDAP related elements: Add option to implicitly trust SSL/TLS connections/Disable hostname verification. Based on contribution by Brian Wolfe (wolfebrian2120 at gmail.com) #### Controllers #### Listeners #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 63178](https://bz.apache.org/bugzilla/show_bug.cgi?id=63178)CSS Selector Extractor: Improve performance of JODD (JoddExtractor) based implementation #### Functions #### I18N #### Report / Dashboard - [Bug 59896](https://bz.apache.org/bugzilla/show_bug.cgi?id=59896) Report / Dashboard: Add a menu entry to generate a report on demand from a CSV file. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [PR#444](https://github.com/apache/jmeter/pull/444)Update to latest Spock v1.2 (was 1.0). Contributed by Graham Russell (graham at ham1.co.uk) - [PR#446](https://github.com/apache/jmeter/pull/446)Improve Unit tests readability and use of Spock. Contributed by Graham Russell (graham at ham1.co.uk) ## Bug fixes #### HTTP Samplers and Test Script Recorder #### Other Samplers - [Bug 63202](https://bz.apache.org/bugzilla/show_bug.cgi?id=63202)JMS Publisher: ObjectMessageRenderer creates XStream instance with uninitialized security #### Controllers #### Listeners - [Bug 63204](https://bz.apache.org/bugzilla/show_bug.cgi?id=63204)`RenderAsJSON#prettyJSON`: `JSONParser#parse` cannot return JSONValue #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62446](https://bz.apache.org/bugzilla/show_bug.cgi?id=62446)Counter documentation is wrong in required fieds. Contributed by orimarko at gmail.com - [Bug 62327](https://bz.apache.org/bugzilla/show_bug.cgi?id=62327)TestPlan: In library table if path is modified and plan saved, the modification is lost on file reload #### Functions - [Bug 63241](https://bz.apache.org/bugzilla/show_bug.cgi?id=63241)`__threadGroupName` causes a NullPointerException if called from non Test threads #### I18N #### Report / Dashboard - [Bug 63198](https://bz.apache.org/bugzilla/show_bug.cgi?id=63198)Response Time Vs Request and Latency Vs Request graphs don't line up with throughput. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Documentation #### General - [Bug 63201](https://bz.apache.org/bugzilla/show_bug.cgi?id=63201)SearchTreeDialog disappears behind master JFrame. Contributed by Benoit Vatan (benoit.vatan at gmail.com) - [Bug 63220](https://bz.apache.org/bugzilla/show_bug.cgi?id=63220)`Function Helper Dialog`, `Export transactions for report` and `Import from cURL` disappear being master JFrame. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63207](https://bz.apache.org/bugzilla/show_bug.cgi?id=63207)java.lang.NullPointerException: null when run JMeter 5.1 with proxy options - [Bug 58183](https://bz.apache.org/bugzilla/show_bug.cgi?id=58183)Rampup may not be respected if thread take time to start leading to threads continuing to start post ramp up time ## Non-functional changes - [Bug 63203](https://bz.apache.org/bugzilla/show_bug.cgi?id=63203)Unit Tests: Replace use of `@Deprecated` by `@VisibleForTesting` for methods/constructors/classes made public for Unit Testing only - [PR#449](https://github.com/apache/jmeter/pull/449)Refactor and Test ResponseTimePercentilesOverTimeGraphConsumer. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#450](https://github.com/apache/jmeter/pull/450)Abstract graph consumer improvements. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#451](https://github.com/apache/jmeter/pull/451)Improve a few unit tests and classes. Contributed by Graham Russell (graham at ham1.co.uk) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](https://ubikloadpack.com) - Benoit Vatan (benoit.vatan at gmail.com) - Graham Russell (graham at ham1.co.uk) - Brian Wolfe (wolfebrian2120 at gmail.com) - orimarko at gmail.com We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.1 Release Notes URL: https://docs.jmeter.ai/releases/5-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | New and Noteworthy | 13 | | Incompatible changes | 4 | | Improvements | 29 | | Bug fixes | 39 | | Non-functional changes | 35 | ## New and Noteworthy ### Core improvements JDBC testing has been improved with ability to set init SQL statements and add compatibility with JDBC drivers that do not support QueryTimeout ![changes/5.1/jdbc-connection-config-init-request.png](/images/screenshots/changes/5.1/jdbc-connection-config-init-request.png) - Various bug fixes have been implemented, like gathering the correct headers when recording requests through the HTTP(S) Test Script Recorder using HTTPS - In version 5.0, JMeter was changed to rename Sub results using a custom Naming Policy ([Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550)). This change could be annoying for Functional Testing, a new property `subresults.disable_renaming=true` has been introduced to revert if needed to previous behaviour. An alternative is to check `Functional Test Mode` in Test Plan, see [Bug 63055](https://bz.apache.org/bugzilla/show_bug.cgi?id=63055) ### UX improvements Templates can provide parameters that are filled in on test plan generation, `Recording` template uses this feature ![changes/5.1/templates-parametes.png](/images/screenshots/changes/5.1/templates-parametes.png) A new `Tools` menu has been introduced to collect those entries, that are used for general usage around JMeter, like: - `Function Helper Dialog` - `Export transactions for report` - `Generate Schematic View` which provides an overview as HTML of the Test plan - `Import from cURL` which allows you to create or update your test plan by importing a cURL command - `Compile JSR223 Test Elements` - `Create a heap dump` - `Create a thread dump` ![changes/5.1/jmeter-new-menu-tools.png](/images/screenshots/changes/5.1/jmeter-new-menu-tools.png) ### Test Plan Ability to create a Test plan from a cURL command. ![changes/5.1/http-request-from-curl-request.png](/images/screenshots/changes/5.1/http-request-from-curl-request.png) ### Scripting / Debugging enhancements - A menu item to compile all JSR223 Elements is now available in `Tools` menu ### Live Reporting and Web Report - A JSON file containing summary of a load test statistics is now generated when using `-e` or `-g` options. - Percentiles computing graphed over time algorithm has been modified to restart for each time slot - More user-friendly behaviour when reporting folder does not exist or is not empty through `-f` command line option ## Incompatible changes - In `Response Time Percentiles Over Time (successful responses)` graph of the HTML report, before this version, percentile computation of each time slot used the percentile data of previous time slot as a base. Starting with this version, each time slot is independant. See [Bug 62883](https://bz.apache.org/bugzilla/show_bug.cgi?id=62883) - `ClientJMeterEngine#rsetProperties` signature has been changed to use `HashMap<String,String>` instead of Properties, see [Bug 63034](https://bz.apache.org/bugzilla/show_bug.cgi?id=63034) - A new Menu item `Tools` has been introduced, some menu items that were in `Help` menu are now under this new menu item. See [Bug 63094](https://bz.apache.org/bugzilla/show_bug.cgi?id=63094) - `slf4j-ext` has been removed from libraries (lib folder) and JMeter pom. It was not used by default and due to CVE-2018-8088 and unavailability of a stable version containing a fix to this issue, we decided to remove it. If you still needed, you can add it in lib folder. ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62840](https://bz.apache.org/bugzilla/show_bug.cgi?id=62840)HTTP Request: Add option `httpclient4.gzip_relax_mode` to avoid error when unzipping what seems to be invalid streams - [Bug 63025](https://bz.apache.org/bugzilla/show_bug.cgi?id=63025)Enhance Search & Replace functionality for HTTP Request to include port and protocol field. Initial code fix by Mohamed Ibrahim (rollno748 at gmail.com) #### Other samplers - [Bug 62934](https://bz.apache.org/bugzilla/show_bug.cgi?id=62934)Add compatibility for JDBC drivers that do not support QueryTimeout - [Bug 62935](https://bz.apache.org/bugzilla/show_bug.cgi?id=62935)Pass custom `mail.*` properties to Mail Reader Sampler. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 63055](https://bz.apache.org/bugzilla/show_bug.cgi?id=63055)Don't rename SampleResult Label when test is running in Functional mode or property `subresults.disable_renaming=true`. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. #### Controllers #### Listeners - [Bug 62822](https://bz.apache.org/bugzilla/show_bug.cgi?id=62822)[PR#407](https://github.com/apache/jmeter/pull/407)Render uninitialized min and max values in Summary Report as `#N/A` #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62766](https://bz.apache.org/bugzilla/show_bug.cgi?id=62766)Keystore Config: We should load all aliases by default. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62832](https://bz.apache.org/bugzilla/show_bug.cgi?id=62832)JDBC Connection Configuration: Be able to set init SQL statements. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Functions - [Bug 63037](https://bz.apache.org/bugzilla/show_bug.cgi?id=63037)When using `CSVRead` search the script base path for files, too. #### I18N #### Report / Dashboard - [Bug 62883](https://bz.apache.org/bugzilla/show_bug.cgi?id=62883)Report / Dashboard: Change the way percentiles are computed for Response Time Percentiles Over Time (successful responses) graph - [Bug 63060](https://bz.apache.org/bugzilla/show_bug.cgi?id=63060)Report Generator: A generator should only check for folder/files it generates and only delete those ones - [Bug 63059](https://bz.apache.org/bugzilla/show_bug.cgi?id=63059)Create a new JsonExporter that exports as JSON the content of data computed for HTML Dashboard Statistics table. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63081](https://bz.apache.org/bugzilla/show_bug.cgi?id=63081)Command line Option `-f` does not delete report folder when using generation only through command line option `-g`. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 62959](https://bz.apache.org/bugzilla/show_bug.cgi?id=62959)Ability to create a Test plan from a cURL command. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#394](https://github.com/apache/jmeter/pull/394)Allow `null` values in `FieldStringEditor`. Based on patch by Mingun (alexander_sergey at mail.ru) - [Bug 62826](https://bz.apache.org/bugzilla/show_bug.cgi?id=62826)When changing LAF, make JMeter restart if user clicks yes to popup - [Bug 62257](https://bz.apache.org/bugzilla/show_bug.cgi?id=62257)[PR#401](https://github.com/apache/jmeter/pull/401)Expand/Collapse short key (minus sign) on numpad doesn't work. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62752](https://bz.apache.org/bugzilla/show_bug.cgi?id=62752)Add to Documentation: `ctx.getThreadNum()` is zero-based while `\${__threadNum}` is one-based - [PR#411](https://github.com/apache/jmeter/pull/411)Use `SHA-1` instead of `SHA1` in `org.apache.jmeter.save.SaveService`. Contributed by Paco (paco.xu at daocloud.io) - [Bug 62914](https://bz.apache.org/bugzilla/show_bug.cgi?id=62914)Add a hint in Thread Group UI about duration of test - [Bug 62925](https://bz.apache.org/bugzilla/show_bug.cgi?id=62925)Add support for ThreadDump to the JMeter non-GUI - [Bug 62870](https://bz.apache.org/bugzilla/show_bug.cgi?id=62870)Templates: Add ability to provide parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62829](https://bz.apache.org/bugzilla/show_bug.cgi?id=62829)Allow specifying Proxy server scheme for HTTP request sampler, Advanced tab and command line option. Contributed by Hitesh Patel (hitesh.h.patel at gmail.com) - [Bug 59633](https://bz.apache.org/bugzilla/show_bug.cgi?id=59633)Menus `Save Test Plan as`, `Save as Test Fragment` and `Save Selection as ...` should use a new file name in File Dialog - [Bug 61486](https://bz.apache.org/bugzilla/show_bug.cgi?id=61486)Make jmeter-server and non GUI mode run headless - [Bug 63093](https://bz.apache.org/bugzilla/show_bug.cgi?id=63093)Add `Compile JSR223 Test Elements` menu item. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63094](https://bz.apache.org/bugzilla/show_bug.cgi?id=63094)Introduce a new Tools menu - [Bug 63101](https://bz.apache.org/bugzilla/show_bug.cgi?id=63101)Propose a menu item to generate readable overview of Test Plan - [Bug 63144](https://bz.apache.org/bugzilla/show_bug.cgi?id=63144)View listener tree take a long time to open response that has huge text. Contributed by Ubik Load Pack (support at ubikloadpack.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 62785](https://bz.apache.org/bugzilla/show_bug.cgi?id=62785)[PR#400](https://github.com/apache/jmeter/pull/400)Incomplete search path applied to the filenames used in the upload functionality of the HTTP sampler. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter. - [Bug 62842](https://bz.apache.org/bugzilla/show_bug.cgi?id=62842)HTTP(S) Test Script Recorder: Brotli compression is not supported leading to "`Content Encoding Error`" - [Bug 60424](https://bz.apache.org/bugzilla/show_bug.cgi?id=60424)Hessian Burlap application: JMeter inserts `0x0D` before `0x0A` automatically (http binary post data) - [Bug 62940](https://bz.apache.org/bugzilla/show_bug.cgi?id=62940)Use different `cn` and type of SAN extension when we are generating certificates based on IP addresses. - [Bug 62916](https://bz.apache.org/bugzilla/show_bug.cgi?id=62916)HTTP Test Script Recorder fails with UnsupportedOperationException if recording is started after a distributed test has been run - [Bug 62987](https://bz.apache.org/bugzilla/show_bug.cgi?id=62987)A TestBean element under HTTP(S) Test Script recorder does not work. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63015](https://bz.apache.org/bugzilla/show_bug.cgi?id=63015)Abnormal NoHttpResponseException when running request through proxy HTTP(S) Test Script Recorder after a first failing request. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62852](https://bz.apache.org/bugzilla/show_bug.cgi?id=62852)HTTP Request Header missing information when using a proxy. Thanks to Oleg Kalnichevski (olegk at apache.org) - [Bug 63048](https://bz.apache.org/bugzilla/show_bug.cgi?id=63048)JMeter does not retrieve link resources of type "shortcut icon" or "icon". Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Other Samplers - [Bug 62775](https://bz.apache.org/bugzilla/show_bug.cgi?id=62775)If many jars are in a folder referenced by `user.classpath`, startup can be extremely slow due to JUnit - [Bug 63031](https://bz.apache.org/bugzilla/show_bug.cgi?id=63031)Incorrect JDBC driver class: `org.firebirdsql.jdbc.FBDrivery`. Contributed by Sonali (arora.sonali99 at gmail.com) #### Controllers - [Bug 62806](https://bz.apache.org/bugzilla/show_bug.cgi?id=62806)ModuleController cloning by Run behaves differently whether in GUI or Non GUI mode. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62847](https://bz.apache.org/bugzilla/show_bug.cgi?id=62847)If Controller cannot use variable for index exposed by LoopController/WhileController/ForEachController - [Bug 63064](https://bz.apache.org/bugzilla/show_bug.cgi?id=63064)Ignore spaces at the end and beginning of expressions used in IfController #### Listeners - [Bug 62770](https://bz.apache.org/bugzilla/show_bug.cgi?id=62770)Aggregate Graph throws `ArrayIndexOutOfBoundsException` - [Bug 63069](https://bz.apache.org/bugzilla/show_bug.cgi?id=63069)ResultCollector does not write end of XML file if user exits while a Recording or a test is running. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 63138](https://bz.apache.org/bugzilla/show_bug.cgi?id=63138)InfluxDB BackendListenerClient: In case of error, log is in debug, it should be in error #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62774](https://bz.apache.org/bugzilla/show_bug.cgi?id=62774)XPath2Extractor: Scope variable is broken. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62860](https://bz.apache.org/bugzilla/show_bug.cgi?id=62860)JSON Extractor: Avoid NPE and noisy error message "`Error processing JSON content in`" when variable is not found #### Functions #### I18N #### Report / Dashboard - [Bug 62777](https://bz.apache.org/bugzilla/show_bug.cgi?id=62777)Web Report / Dashboard: Hide All in `Response Time Percentiles Over Time (successful responses)` fails. - [Bug 62780](https://bz.apache.org/bugzilla/show_bug.cgi?id=62780)Web Report / Dashboard: Display All in `Response Time Vs Request` fails. - [Bug 62781](https://bz.apache.org/bugzilla/show_bug.cgi?id=62781)Web Report / Dashboard: Display All in `Response Time Overview` fails. - [Bug 62782](https://bz.apache.org/bugzilla/show_bug.cgi?id=62782)Web Report / Dashboard: Remove duplicate/unused dependencies - [Bug 62894](https://bz.apache.org/bugzilla/show_bug.cgi?id=62894)Report / Dashboard: Throughput is in wrong column which is confusing as unit is millisecond - [Bug 63016](https://bz.apache.org/bugzilla/show_bug.cgi?id=63016)Empty HTML report if source csv contains labels with quotes. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Documentation - Change `Test Action` (old name) to `Flow Control Action` in Component Reference documentation. Contributed by Ori Marko (orimarko at gmail.com) #### General - [Bug 62745](https://bz.apache.org/bugzilla/show_bug.cgi?id=62745)Fix undefined disabled icon. Contributed by Till Neunast (https://github.com/tilln) - [Bug 62743](https://bz.apache.org/bugzilla/show_bug.cgi?id=62743)Client auth must be enabled on distributed testing - [Bug 62767](https://bz.apache.org/bugzilla/show_bug.cgi?id=62767)NPE when searching under certain conditions. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62790](https://bz.apache.org/bugzilla/show_bug.cgi?id=62790)`ArrayIndexOutOfBoundsException` when calling replace without selecting the first match - [Bug 62795](https://bz.apache.org/bugzilla/show_bug.cgi?id=62795)JMeter controller node sometimes ends distributed test even though some of the worker nodes have not finished - [Bug 62336](https://bz.apache.org/bugzilla/show_bug.cgi?id=62336)[PR#396](https://github.com/apache/jmeter/pull/396)Some shortcuts are not working correctly on windows. Contributed by Michael Pavlov (michael.paulau at gmail.com) - [Bug 62889](https://bz.apache.org/bugzilla/show_bug.cgi?id=62889)Format JSON Arrays when displayed with JSON Path Tester. - [Bug 62900](https://bz.apache.org/bugzilla/show_bug.cgi?id=62900)ObjectProperty#getStringValue() can throw NullPointerException - [Bug 63099](https://bz.apache.org/bugzilla/show_bug.cgi?id=63099)Escape commata in function helper dialog only outside of variable replacement structures. - [Bug 63105](https://bz.apache.org/bugzilla/show_bug.cgi?id=63105)Export Transactions for Report: fix 2 bugs - [Bug 63106](https://bz.apache.org/bugzilla/show_bug.cgi?id=63106)Apply naming policy does not refresh UI - [Bug 63180](https://bz.apache.org/bugzilla/show_bug.cgi?id=63180)Apply Naming Policy allows multi selection but only considers first node - [Bug 63090](https://bz.apache.org/bugzilla/show_bug.cgi?id=63090)Remove slf4j-ext due to CVE-2018-8088 ## Non-functional changes - [PR#408](https://github.com/apache/jmeter/pull/408)Log an informational message instead of an stack trace, when JavaFX is not found for the `RenderInBrowser` component. - [PR#412](https://github.com/apache/jmeter/pull/412)Update Chinese translation. Contributed by 刘士 (liushilive at outlook.com). - [PR#406](https://github.com/apache/jmeter/pull/406)Add a short paragraph on how to use a security manager with JMeter. - [Bug 62893](https://bz.apache.org/bugzilla/show_bug.cgi?id=62893)Use StringEscapeUtils from commons-text (version 1.6) instead of the deprecated ones from commons-lang3. - [Bug 62972](https://bz.apache.org/bugzilla/show_bug.cgi?id=62972)[PR#435](https://github.com/apache/jmeter/pull/435)Replace calls to deprecated method `Class#newInstance`. - [Bug 63034](https://bz.apache.org/bugzilla/show_bug.cgi?id=63034)ClientJMeterEngine: Make rsetProperties use `HashMap<String,String>` instead of Properties - Updated to httpclient/httpmime 4.5.7 (from 4.5.6) - Updated to httpcore 4.4.11 (from 4.4.10) - Updated to httpcore-nio 4.4.11 (from 4.4.10) - Updated to tika-core and tika-parsers 1.20 (from 1.18) - Updated to commons-dbcp2-2.5.0 (from commons-dbcp2-2.4.0) - Updated to commons-lang3-3.8.1 (from commons-lang3-3.8) - Updated to groovy-all-2.4.16 (from groovy-all-2.4.15) - Updated to httpasyncclient-4.1.4.jar (from 4.1.3) - Updated to jsoup-1.11.3 (from 1.11.2) - Updated to cglib-nodep-3.2.9 (from cglib-nodep-3.2.7) - Updated to ph-commons-9.2.1 (from ph-commons-9.1.2) - Updated to log4j-2.11.1 (from log4j-2.11.0) - Updated to xmlgraphics-commons 2.3 (from 2.2) - [Bug 63033](https://bz.apache.org/bugzilla/show_bug.cgi?id=63033)Updated to Saxon-HE 9.9.1-1 (from 9.8.0-12). Thanks at Saxonica - Updated to xstream 1.4.11 (from 1.4.10) - Updated to jodd 5.0.6 (from 4.1.4) - Updated to asm-7.0 (from 6.1) - Update to ActiveMQ 5.15.8 (from 5.5.16) - Updated to rsyntaxtextarea-3.0.2 (from 2.6.1) - Updated to apache-rat-0.13 (from 0.12) - Updated to jacocoant-0.8.3 (from 0.8.2) - Updated to hsqldb-2.4.1 (from 2.4.0) - Updated to mina-core-2.0.19 (from 2.0.16) - [Bug 62818](https://bz.apache.org/bugzilla/show_bug.cgi?id=62818)Updated to xercesImpl to 2.12.0 (from 2.11.0). Reported by Stefan Seide (stefan at trilobyte-se.de) - [Bug 62744](https://bz.apache.org/bugzilla/show_bug.cgi?id=62744)Upgrade jquery to version 3.3.1, jquery-ui to 1.12.1, bootstrap to 3.3.7 - [Bug 62821](https://bz.apache.org/bugzilla/show_bug.cgi?id=62821)[PR#405](https://github.com/apache/jmeter/pull/405)Use SHA-512 checksums instead of MD5 to verify jar downloads - [Bug 63053](https://bz.apache.org/bugzilla/show_bug.cgi?id=63053)Remove referrals to never implemented internals from user documentation. Reported by U. Poblotzki (u.poblotzki at thalia.de) - [Bug 63082](https://bz.apache.org/bugzilla/show_bug.cgi?id=63082)[PR#437](https://github.com/apache/jmeter/pull/437)Use utf-8 for properties files in source - [Bug 63177](https://bz.apache.org/bugzilla/show_bug.cgi?id=63177)Rename NON GUI mode into CLI Mode in documentation ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Oleg Kalnichevski (olegk at apache.org) - Till Neunast (https://github.com/tilln) - Mingun (alexander_sergey at mail.ru) - [Ubik Load Pack](https://ubikloadpack.com) - Artem Fedorov (artem.fedorov at blazemeter.com) - Stefan Seide (stefan at trilobyte-se.de) - 刘士 (liushilive at outlook.com) - Michael Pavlov (michael.paulau at gmail.com) - Ori Marko (orimarko at gmail.com) - Paco (paco.xu at daocloud.io) - Hitesh Patel (hitesh.h.patel at gmail.com) - Sonali (arora.sonali99 at gmail.com) - Mohamed Ibrahim (rollno748 at gmail.com) - U. Poblotzki (u.poblotzki at thalia.de) - [Saxonica](https://www.saxonica.com) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 5.0 Release Notes URL: https://docs.jmeter.ai/releases/5-0/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 5.0, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | New and Noteworthy | 3 | | Incompatible changes | 6 | | Improvements | 49 | | Bug fixes | 43 | | Non-functional changes | 21 | ## New and Noteworthy ### Core improvements Rest support has been improved in many fields - Multipart/form-data requests now work for `PUT`, `DELETE` … - It is now also possible to send a JSON Body with attached file - Parameters entered in Parameters Tab are now used in body instead of being ignored ![changes/5.0/jmeter_5_rest1.png](/images/screenshots/changes/5.0/jmeter_5_rest1.png) ![changes/5.0/jmeter_5_rest2.png](/images/screenshots/changes/5.0/jmeter_5_rest2.png) In distributed testing, JMeter now automatically prefixes thread names with engine host and port, this makes the counting of threads correct in the HTML report without any other configuration as it was required before ![changes/5.0/jmeter_5_distributed.png](/images/screenshots/changes/5.0/jmeter_5_distributed.png) XPath 2.0 is supported in a new element called `XPath2 extractor` providing easier XML namespaces handling, up to date XPath syntax and better performances ![changes/5.0/jmeter_5_xpath2_extractor.png](/images/screenshots/changes/5.0/jmeter_5_xpath2_extractor.png) ![changes/5.0/jmeter_5_xpath2_tester.png](/images/screenshots/changes/5.0/jmeter_5_xpath2_tester.png) Upgrade to HTTP Components 4.6 last APIs has been completed and JMeter does not rely anymore on deprecated APIs of this library It is now possible to control in an easier way Loop breaking and Loop switching to next iteration. This is available in `Flow Control Action` and `Result Status Action Handler` elements ![changes/5.0/jmeter_5_flow_control_action.png](/images/screenshots/changes/5.0/jmeter_5_flow_control_action.png) ![changes/5.0/jmeter_5_result_status_handler.png](/images/screenshots/changes/5.0/jmeter_5_result_status_handler.png) While Controller now exports a variable containing its current index named `__jm__<Name of your element>__idx`. So for example, if your While Controller is named WC, then you can access the looping index through `\${__jm__WC__idx}` ### Scripting / Debugging enhancements Search feature has been improved to allow you to iterate in the tree over search results and do necessary replacements through `Next`/`Previous`/`Replace`/`Replace/Find` buttons ![changes/5.0/jmeter_5_search_feature.png](/images/screenshots/changes/5.0/jmeter_5_search_feature.png) In View Results Tree, the request and response headers/body are clearly separated to allow you to better inspect requests and responses. You can also search in all those tabs for a particular value ![changes/5.0/jmeter_5_vrt_request_body.png](/images/screenshots/changes/5.0/jmeter_5_vrt_request_body.png) ![changes/5.0/jmeter_5_vrt_response_body.png](/images/screenshots/changes/5.0/jmeter_5_vrt_response_body.png) Recording feature has been improved to provide a popup that is always on top when you navigate in browser allowing you to name transactions while you navigate in your application. ![changes/5.0/jmeter_5_recording.png](/images/screenshots/changes/5.0/jmeter_5_recording.png) You can now restart JMeter from menu **File → Restart** ![changes/5.0/jmeter_5_restart.png](/images/screenshots/changes/5.0/jmeter_5_restart.png) ### Live Reporting and Web Report Reporting feature has been enhanced A new Graph Total Transactions per second has been added to the HTML Web Report ![changes/5.0/jmeter_5_total_trans_per_sec.png](/images/screenshots/changes/5.0/jmeter_5_total_trans_per_sec.png) It is now possible to graph over time custom metrics available as JMeter Variables through `sample_variables`. Those custom metrics graphs will be available in the HTML Report in `Custom Graphs section` ![changes/5.0/jmeter_5_custom_graphs.png](/images/screenshots/changes/5.0/jmeter_5_custom_graphs.png) Hits per second graph now takes into account the embedded resources ![changes/5.0/jmeter_5_hits_per_sec.png](/images/screenshots/changes/5.0/jmeter_5_hits_per_sec.png) In Live reporting, the sent and received bytes are now sent to Backends (InfluxDB or Graphite) ### Functions A New function `[__threadGroupName](/user-manual/functions/#__threadGroupName)` has been introduced to obtain ThreadGroup name. ## Incompatible changes - Since JMeter 5.0, when using default HC4 Implementation, JMeter will reset HTTP state (SSL State + Connections) on each thread group iteration. If you don't want this behaviour, set `httpclient.reset_state_on_thread_group_iteration=false` - Since JMeter 5.0, in relation to above remark, `https.use.cached.ssl.context` is deprecated and not used anymore. - Since JMeter 5.0, when using CSV output, sub results will now be also output to CSV file. To revert to previous behaviour set `jmeter.save.saveservice.subresults=false`, see [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470), [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917), [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550). - Since JMeter 5.0, `CSS/JQuery Extractor` has been renamed to `CSS Selector Extractor` - Since JMeter 5.0, `Test Action` has been renamed to `Flow Control Action` - Since JMeter 5.0, JMeter renames subResults to `parentName-N` where N is a number to ensure that Hits Per Second graph includes resources downloads, see [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550), [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470) and [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 62260](https://bz.apache.org/bugzilla/show_bug.cgi?id=62260)Improve Rest support. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 58757](https://bz.apache.org/bugzilla/show_bug.cgi?id=58757)HTTP Request : Updated deprecated methods of HttpComponents to last APIs of httpclient-4.5.X. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62212](https://bz.apache.org/bugzilla/show_bug.cgi?id=62212)Recorder : Improve UX by providing a popup above all windows to be able to change Transaction names and pauses while using Browser. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62248](https://bz.apache.org/bugzilla/show_bug.cgi?id=62248)HTTP Request : Parameters entered in Parameters Tab should be used in body instead of being ignored. Partly based on a patch by Artem Fedorov contributed by Blazemeter. - [Bug 60015](https://bz.apache.org/bugzilla/show_bug.cgi?id=60015)Multipart/form-data works only for `POST` using HTTPClient4 while it should for `PUT`, `DELETE`, … Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62317](https://bz.apache.org/bugzilla/show_bug.cgi?id=62317)HTTP(S) Test Script Recorder: allow to add ResultSaver to created sampler #### Other samplers - [PR#376](https://github.com/apache/jmeter/pull/376)JUnitSampler logs exceptions except assertion-failures from test cases as warnings. Contributed by Davide Angelocola (davide.angelocola at fisglobal.com) - [Bug 62244](https://bz.apache.org/bugzilla/show_bug.cgi?id=62244)Rename `Test Action` to `Flow Control Action` - [Bug 62302](https://bz.apache.org/bugzilla/show_bug.cgi?id=62302)Move JSR223 Sampler up the menu. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62595](https://bz.apache.org/bugzilla/show_bug.cgi?id=62595)SMTPSampler does not allow configuring the SSL/TLS protocols to be used on handshake. Contributed by Felipe Cuozzo (felipe.cuozzo at gmail.com) #### Controllers - [Bug 62237](https://bz.apache.org/bugzilla/show_bug.cgi?id=62237)While Controller : Export variable containing current index of iteration. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Listeners - [Bug 62195](https://bz.apache.org/bugzilla/show_bug.cgi?id=62195)Save Responses to a file : Improve component and UI. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62209](https://bz.apache.org/bugzilla/show_bug.cgi?id=62209)InfluxBackendListenerClient: First Assertion Failure Message must be sent if error code and response code are empty or OK - [Bug 62269](https://bz.apache.org/bugzilla/show_bug.cgi?id=62269)Bug 62269 - View Results Tree : Response and Request Tabs should contains Header and Body tabs. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62270](https://bz.apache.org/bugzilla/show_bug.cgi?id=62270)View Results Tree : Allow searching in Request headers, Response Headers, and Request body. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62276](https://bz.apache.org/bugzilla/show_bug.cgi?id=62276)InfluxDBBackendListenerClient / GraphiteBackendListenerClient : Add sent and received bytes to metrics. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 62320](https://bz.apache.org/bugzilla/show_bug.cgi?id=62320)Counter : Reference Name property is not clear - [Bug 60991](https://bz.apache.org/bugzilla/show_bug.cgi?id=60991)XPath Extractor : Implement XPath 2.0. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62593](https://bz.apache.org/bugzilla/show_bug.cgi?id=62593)Rename CSS/JQuery Extractor to CSS Selector Extractor. Contributed by Ori Marko (orimarko at gmail.com) #### Functions - [Bug 62178](https://bz.apache.org/bugzilla/show_bug.cgi?id=62178)Add default value to `[__V](/user-manual/functions/#__V)` function. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62178](https://bz.apache.org/bugzilla/show_bug.cgi?id=62178)Add function `[__threadGroupName](/user-manual/functions/#__threadGroupName)` function to obtain ThreadGroup name. Mainly contributed by Ori Marko (orimarko at gmail.com) - [Bug 62533](https://bz.apache.org/bugzilla/show_bug.cgi?id=62533)Allow use epoch time as Date String value in function `[__dateTimeConvert](/user-manual/functions/#__dateTimeConvert)` - [Bug 62541](https://bz.apache.org/bugzilla/show_bug.cgi?id=62541)Allow `[__jexl3](/user-manual/functions/#__jexl3)`, `[__jexl2](/user-manual/functions/#__jexl2)` functions to support new syntax as `var x;`. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 61834](https://bz.apache.org/bugzilla/show_bug.cgi?id=61834)Function Helper Dialog : Improve tests by showing variables and keeping them available between evaluations #### I18N #### Report / Dashboard - [Bug 62243](https://bz.apache.org/bugzilla/show_bug.cgi?id=62243)Dashboard : make option "`--forceDeleteResultFile`"/"`-f`" option delete folder referenced by "`-o`" option - [Bug 62367](https://bz.apache.org/bugzilla/show_bug.cgi?id=62367)HTML Report Generator: Add Graph Total Transactions per Second. Contributed mainly by Martha Laks (laks.martha at gmail.com) - [Bug 62166](https://bz.apache.org/bugzilla/show_bug.cgi?id=62166)Report/Dashboard: Provide ability to register custom graphs and metrics in the JMeter Dashboard. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62542](https://bz.apache.org/bugzilla/show_bug.cgi?id=62542)Report/Dashboard : Display more information on filters when graph is empty. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62426](https://bz.apache.org/bugzilla/show_bug.cgi?id=62426)Optimize performance of report generation. Based on feedback by Allen (444104595 at qq.com) - [Bug 62550](https://bz.apache.org/bugzilla/show_bug.cgi?id=62550)Modify SubResult Naming Policy - [Bug 60917](https://bz.apache.org/bugzilla/show_bug.cgi?id=60917)Load Test with embedded resources download : Hits per seconds does not take into account the downloaded resources #### General - [Bug 62684](https://bz.apache.org/bugzilla/show_bug.cgi?id=62684)Distributed Testing : Add automatically to thread name a prefix to identify engine. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62155](https://bz.apache.org/bugzilla/show_bug.cgi?id=62155)Search Feature: Make Search text field get focus - [Bug 62156](https://bz.apache.org/bugzilla/show_bug.cgi?id=62156)Search Feature : Distinguish between node that matches search and node that contains a child that matches search - [Bug 62234](https://bz.apache.org/bugzilla/show_bug.cgi?id=62234)Search/Replace Feature : Enhance UX and add Replace/Next/Previous/Replace & Find features. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62238](https://bz.apache.org/bugzilla/show_bug.cgi?id=62238)Add ability to Switch to next iteration of Current Loop. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62239](https://bz.apache.org/bugzilla/show_bug.cgi?id=62239)Add ability to Break Current Loop - [Bug 61635](https://bz.apache.org/bugzilla/show_bug.cgi?id=61635)Add a menu to restart JMeter - [Bug 62470](https://bz.apache.org/bugzilla/show_bug.cgi?id=62470)CSV Output : Enable logging of sub results when `jmeter.save.saveservice.subresults=true`. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62473](https://bz.apache.org/bugzilla/show_bug.cgi?id=62473)Setting "`saveservice_properties`" has counter intuitive behaviour - [Bug 62354](https://bz.apache.org/bugzilla/show_bug.cgi?id=62354)Correct calculation and usage of units for second per user (reported by jffagot05 at gmail.com) - [Bug 62700](https://bz.apache.org/bugzilla/show_bug.cgi?id=62700)Introduce `jsr223.init.file` to allow calling a JSR-223 script on JMeter startup - [Bug 62128](https://bz.apache.org/bugzilla/show_bug.cgi?id=62128)Try to guess `JMETER_HOME` correctly, when `jmeter.bat` is called from a batch file in another directory. Contributed by logox01 (logox01 at gmx.at) - [PR#386](https://github.com/apache/jmeter/pull/386)Add parameter support for RMI keystore creation scripts. Contributed by Logan Mauzaize (t524467 at airfrance.fr) - [Bug 62065](https://bz.apache.org/bugzilla/show_bug.cgi?id=62065)Use Maven artifact for JAF Module instead of embedded module - [Bug 61714](https://bz.apache.org/bugzilla/show_bug.cgi?id=61714)Update Real-time results documentation - [PR#382](https://github.com/apache/jmeter/pull/382)Correct typo in documentation. Reported by Perze Ababa (perze.ababa at gmail.com>) - [PR#392](https://github.com/apache/jmeter/pull/392)Correct typo in documentation. Reported by Aaron Levin - [PR#379](https://github.com/apache/jmeter/pull/379) Improve chinese translations. Contributed by XmeterNet ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 62114](https://bz.apache.org/bugzilla/show_bug.cgi?id=62114)HTTP(S) Test Script Recorder : Client certificate authentication uses the first SSLManager created. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61058](https://bz.apache.org/bugzilla/show_bug.cgi?id=61058)HTTP Request : Add option `httpclient4.deflate_relax_mode` to avoid "Unexpected end of ZLIB input stream" when deflating what seems to be invalid streams. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 43612](https://bz.apache.org/bugzilla/show_bug.cgi?id=43612)HTTP PUT does not honor request parameters. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 60190](https://bz.apache.org/bugzilla/show_bug.cgi?id=60190)Content-Type is added for `POST` unconditionally. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62462](https://bz.apache.org/bugzilla/show_bug.cgi?id=62462)[PR#387](https://github.com/apache/jmeter/pull/387)Make delegation of credentials in SPNEGO possible again. - [Bug 58807](https://bz.apache.org/bugzilla/show_bug.cgi?id=58807)`Reset SSL State on Thread Group iteration only (was https.use.cached.ssl.context=false` is broken) - [Bug 62716](https://bz.apache.org/bugzilla/show_bug.cgi?id=62716)When Recording, JMeter removes Authorization from generated Header Manager when using Bearer Token #### Other Samplers - [Bug 62235](https://bz.apache.org/bugzilla/show_bug.cgi?id=62235)Java 9 - illegal reflective access by org.apache.jmeter.util.HostNameSetter - [Bug 62464](https://bz.apache.org/bugzilla/show_bug.cgi?id=62464)Set start- and end-time on JMS publisher sampler, even if initialization fails. - [Bug 62616](https://bz.apache.org/bugzilla/show_bug.cgi?id=62616)FTPSampler: Upload file-size is not counted in sentBytes #### Controllers - [Bug 62265](https://bz.apache.org/bugzilla/show_bug.cgi?id=62265)ModuleController behaves strangely #### Listeners - [Bug 62097](https://bz.apache.org/bugzilla/show_bug.cgi?id=62097)Update JTable in Aggregate Report only when new data has arrived. That way selections of rows will be kept longer around. - [Bug 62203](https://bz.apache.org/bugzilla/show_bug.cgi?id=62203)Influxdb BackendListener client: store user tags to annotation and internal transaction. Contributed by Sergey Batalin (sergey_batalin at mail.ru) - [Bug 62251](https://bz.apache.org/bugzilla/show_bug.cgi?id=62251)TextGraphiteMetricsSender does not invalidate lost connections in case of network errors - [Bug 60705](https://bz.apache.org/bugzilla/show_bug.cgi?id=60705)Fix headers of Aggregate Reports and friends when columns are moved around. - [Bug 62463](https://bz.apache.org/bugzilla/show_bug.cgi?id=62463)Distributed client/server setup: use different RMI ports for the remote objects when using SSL #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61664](https://bz.apache.org/bugzilla/show_bug.cgi?id=61664)HTTP Authorization Manager : Digest works only with legacy [RFC 2069](https://tools.ietf.org/html/2069), [RFC 2617](https://tools.ietf.org/html/2617) is not implemented. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62252](https://bz.apache.org/bugzilla/show_bug.cgi?id=62252)HTTP header merging logic does not correspond to the documentation - [Bug 62554](https://bz.apache.org/bugzilla/show_bug.cgi?id=62554)BoundaryExtractor : Field to check is not reset - [Bug 62553](https://bz.apache.org/bugzilla/show_bug.cgi?id=62553)Random element might return same value even if property "Per thread user (User)" is set to TRUE - [Bug 62637](https://bz.apache.org/bugzilla/show_bug.cgi?id=62637)Take scheduler into account when calcuting delay for Synchronizing Timer #### Functions #### I18N - [Bug 62310](https://bz.apache.org/bugzilla/show_bug.cgi?id=62310)French translation of Precise Throughput Timer label #### Report / Dashboard - [Bug 62333](https://bz.apache.org/bugzilla/show_bug.cgi?id=62333)Report Dashboard - When one series contains no value, the graph colors logic is wrong. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62283](https://bz.apache.org/bugzilla/show_bug.cgi?id=62283)Report Dashboard - Date is not correctly displayed on chart when granularity is ≤ 1 day - [Bug 62520](https://bz.apache.org/bugzilla/show_bug.cgi?id=62520)The tool-tip text when we hover on the point in 'Latency Vs Request' graph should be 'Median Latency' #### Documentation - [Bug 62211](https://bz.apache.org/bugzilla/show_bug.cgi?id=62211)Fix HTTP Request Server Documentation. Contributed by Ori Marko (orimarko at gmail.com) - [PR#388](https://github.com/apache/jmeter/pull/388)Fix a typo. Contributed by Giancarlo Romeo (giancarloromeo at gmail.com) #### General - [Bug 62107](https://bz.apache.org/bugzilla/show_bug.cgi?id=62107)JMeter fails to start under Windows when `JM_LAUNCH` contains spaces - [Bug 62110](https://bz.apache.org/bugzilla/show_bug.cgi?id=62110)A broken JUnit class (due to missing dependency) breaks JMeter menus. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#377](https://github.com/apache/jmeter/pull/377)Small fix of the docs. Contributed by Peter Doornbosch (peter.doornbosch at luminis.eu) - [Bug 62124](https://bz.apache.org/bugzilla/show_bug.cgi?id=62124)Recording templates : Add more exclusions and use Transaction Name by default - [Bug 62127](https://bz.apache.org/bugzilla/show_bug.cgi?id=62127)Store filename as String instead of File in FileEditor. This will prevent conversion of filenames from Unix style path separators to Windows style when used for example in CSV Data Set Config. - [Bug 56150](https://bz.apache.org/bugzilla/show_bug.cgi?id=56150)Keep the index right, when scrolling through the menu items. - [Bug 62240](https://bz.apache.org/bugzilla/show_bug.cgi?id=62240)If SampleMonitor implementation is a TestBean if will not be initialized correctly - [Bug 62295](https://bz.apache.org/bugzilla/show_bug.cgi?id=62295)Correct order of elements when duplicating a selection of multiple elements. - [Bug 62397](https://bz.apache.org/bugzilla/show_bug.cgi?id=62397)Don't break lines at commata when using JSON Path Tester - [Bug 62281](https://bz.apache.org/bugzilla/show_bug.cgi?id=62281)Prevent NPE in MapProperty. Patch by belugabehr (dam6923 at gmail.com) - [Bug 62457](https://bz.apache.org/bugzilla/show_bug.cgi?id=62457)In usermanual, the UUID Function's example is wrong. Contributed by helppass (onegaicimasu at hotmail.com) - [Bug 62478](https://bz.apache.org/bugzilla/show_bug.cgi?id=62478)Escape commata in parameters when constructing function strings in the GUI function helper. Reported by blue414 (blue414 at 163.com) - [Bug 62463](https://bz.apache.org/bugzilla/show_bug.cgi?id=62463)Fix usage of ports, when `client.rmi.localport` is set for distributed runs. - [Bug 62545](https://bz.apache.org/bugzilla/show_bug.cgi?id=62545)Don't use a colon as part of the "tab" string when indenting JSON in RenderAsJSON. - Part of [Bug 62637](https://bz.apache.org/bugzilla/show_bug.cgi?id=62637) Avoid Integer overrun when dealing with very large values in `TimerService#adjustDelay` - [Bug 62683](https://bz.apache.org/bugzilla/show_bug.cgi?id=62683)Error dialog has no text when user opens completely invalid test plan. ## Non-functional changes - [PR#358](https://github.com/apache/jmeter/pull/358)[PR#365](https://github.com/apache/jmeter/pull/365)[PR#366](https://github.com/apache/jmeter/pull/366)[PR#375](https://github.com/apache/jmeter/pull/375)Updated to latest checkstyle (v8.8). Expanded Checkstyle to files in `src` and `test`; fixed newly checked files. Based on contribution by Graham Russell (graham at ham1.co.uk) - [Bug 62095](https://bz.apache.org/bugzilla/show_bug.cgi?id=62095)Correct description for right boundary parameter in Boundary Extractor. Contributed by Ori Marko (orimarko at gmail.com) - [Bug 62113](https://bz.apache.org/bugzilla/show_bug.cgi?id=62113)Updated to latest Bouncycastle (v1.60). Based on contribution by Olaf Flebbe (oflebbe at apache.org) - [Bug 62171](https://bz.apache.org/bugzilla/show_bug.cgi?id=62171)Remove `.md5` checksums and keep only `.sha512` checksums for source and binary archives - Updated to groovy-all-2.4.15 (from groovy-all-2.4.13) - Updated to asm-6.1 (from 6.0) - Updated to tika-core and tika-parsers 1.18 (from 1.17) - [Bug 62482](https://bz.apache.org/bugzilla/show_bug.cgi?id=62482)Sync documentation to the implementation of the ForEachController. Based on contribution by Ori Marko (orimarko at gmail.com) - [Bug 62529](https://bz.apache.org/bugzilla/show_bug.cgi?id=62529)Updated to httpclient-4.5.6 (from httpclient 4.5.5) and updated to freemarker-2.3.28 (from freemarker-2.3.23). Based on patch by Ori Marko (orimarko at gmail.com) - Updated to httpmime-4.5.6 (from httpmime-4.5.5) - Updated to caffeine-2.6.2 (from caffeine-2.6.1) - Updated to cglib-nodep-3.2.7 (from cglib-nodep-3.2.6) - Updated to commons-dbcp2-2.4.0 (from commons-dbcp2-2.2.0) - Updated to commons-pool2-2.6.0 (from commons-pool2-2.5.0) - Updated to httpcore-4.4.10 (from httpcore-4.4.9) - Updated to httpcore-nio-4.4.10 (from httpcore-nio-4.4.9) - Updated to log4j-2.11.0 (from log4j-2.10.0) - Updated to ph-css-6.1.1 (from ph-css-6.0.0) - Updated to ph-commons-9.1.2 (from ph-commons-9.0.0) - Updated to rhino-1.7.10 (from +rhino-1.7.7.2) - Updated to commons-lang3-3.8 (from commons-lang3-3.7) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Graham Russell (graham at ham1.co.uk) - Ori Marko (orimarko at gmail.com) - Davide Angelocola (davide.angelocola at fisglobal.com) - [Ubik Load Pack](https://ubikloadpack.com) - Olaf Flebbe (oflebbe at apache.org) - Peter Doornbosch (peter.doornbosch at luminis.eu) - logox01 (logox01 at gmx.at) - Sergey Batalin (sergey_batalin at mail.ru) - [XMeter](https://www.xmeter.net) - Imane Ankhila (iankhila at ahlane.net) - jffagot05 (jffagot05 at gmail.com) - Perze Ababa (perze.ababa at gmail.com) - Martha Laks (laks.martha at gmail.com) - Logan Mauzaize (t524467 at airfrance.fr) - belugabehr (dam6923 at gmail.com) - Giancarlo Romeo (giancarloromeo at gmail.com) - helppass (onegaicimasu at hotmail.com) - blue414 (blue414 at 163.com) - Aaron Levin - Allen (444104595 at qq.com) - Felipe Cuozzo (felipe.cuozzo at gmail.com) - bangnab (ambrosetti.nicola at gmail.com) We also thank bug reporters who helped us improve JMeter. Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 4.0 Release Notes URL: https://docs.jmeter.ai/releases/4-0/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 4.0, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | New and Noteworthy | 6 | | Incompatible changes | 14 | | Improvements | 75 | | Bug fixes | 26 | | Non-functional changes | 35 | ## New and Noteworthy ### Core improvements JMeter now supports JAVA 9. New [`Boundary Extractor`](/usermanual/component-reference/#Boundary_Extractor) element available which provides easy extraction with better performances ![changes/4.0/boundary_extractor.png](/images/screenshots/changes/4.0/boundary_extractor.png) New [`JSON Assertion`](/usermanual/component-reference/#JSON_Assertion) element available to assert on JSON responses. ![changes/4.0/json_assertion.png](/images/screenshots/changes/4.0/json_assertion.png) New [`Precise Throughput Timer`](/usermanual/component-reference/#Precise_Throughput_Timer) element available which produces Poisson arrivals with given constant throughput. ![changes/4.0/precise_throughput_timer.png](/images/screenshots/changes/4.0/precise_throughput_timer.png) JMS Point-to-Point sampler has been enhanced with `read`, `browse`, `clear` options. ![changes/4.0/jmsptp_communication_styles.png](/images/screenshots/changes/4.0/jmsptp_communication_styles.png) Best property values are now selected on many Test Elements to ensure best practices are the defaults: - Newly added `If Controller` now uses by default Expression which is the most performing option. ![changes/4.0/if_controller_condition.png](/images/screenshots/changes/4.0/if_controller_condition.png) ![changes/4.0/if_controller_expression.png](/images/screenshots/changes/4.0/if_controller_expression.png) - Newly added JSR223 Test Element now cache compiled script by default if language used provides this feature. ![changes/4.0/jsr223_cache_compilation.png](/images/screenshots/changes/4.0/jsr223_cache_compilation.png) [`Loop controller`](/usermanual/component-reference/#Loop_Controller) and [`ForEach Controller`](/usermanual/component-reference/#ForEach_Controller) now expose their current iteration as a variable named `__jm__<Name of your element>__idx` that you can use like this for example for a Loop Controller named `MyLoopController`: ```bash \${__jm__MyLoopController__idx} ``` . See [Bug 61802](https://bz.apache.org/bugzilla/show_bug.cgi?id=61802) Cookies are now shown in View Results Tree during recording. They were previously always shown as empty. [`Response Assertion`](/usermanual/component-reference/#Response_Assertion) now allows you to customize assertion message and assert on Request Data. ![changes/4.0/response_assertion_enhancements.png](/images/screenshots/changes/4.0/response_assertion_enhancements.png) ### UX improvements JMeter now uses [Darcula LAF](https://github.com/bulenkov/Darcula) by default Workbench has been dropped from UI, you can now use Non Test Elements as immediate children of Test Plan. ![changes/4.0/goodbye_workbench.png](/images/screenshots/changes/4.0/goodbye_workbench.png) Menu UX have been improved to make most used elements available more rapidly. ![changes/4.0/menu_organization.png](/images/screenshots/changes/4.0/menu_organization.png) HTTP(S) Test Script Recorder now allows you to name your transactions while recording in a more human readable way. ![changes/4.0/recorder_naming_samplers.png](/images/screenshots/changes/4.0/recorder_naming_samplers.png) UX improvements made on, among the most notable : - Module Controller informs user at least one Controller is required - Function Helper Dialog (The wizard that helps using and testing functions) has been improved in many fields. ![changes/4.0/function_helper_dialog_enhancements.png](/images/screenshots/changes/4.0/function_helper_dialog_enhancements.png) - Switch Controller trims text to avoid issues when a space is introduced before/after name - Test Plan is now saved before running the test plan ### Functions New Function [`__digest`](/usermanual/functions/#__digest) provides easy computing of SHA-XXX, MDX hashes: ```bash \${__digest(MD5,Apache JMeter 4.0 rocks !,,,)} ``` will return `0e16c3ce9b6c9971c69ad685fd875d2b` New Function [`__dateTimeConvert`](/usermanual/functions/#__dateTimeConvert) provides easy conversion between date formats: ```bash \${__dateTimeConvert(01 Jan 2017,dd MMM yyyy,dd/MM/yyyy,)} ``` will return `01/01/2017` New Function [`__changeCase`](/usermanual/functions/#__changeCase) provides ability to switch to Upper / Lower / Capitalized cases ```bash \${__changeCase(Avaro omnia desunt\, inopi pauca\, sapienti nihil,UPPER,)} ``` will return `AVARO OMNIA DESUNT, INOPI PAUCA, SAPIENTI NIHIL` New Functions [`__isVarDefined`](/usermanual/functions/#__isVarDefined) and [`__isPropDefined`](/usermanual/functions/#__isPropDefined) provide testing of properties and variables availability ```bash \${__isPropDefined(START.HMS)} ``` will return `true` ```bash \${__isVarDefined(JMeterThread.last_sample_ok)} ``` will return `true` ### Scripting and Plugin Development You can now call `SampleResult#setIgnore()` if you don't want your sampler to be visible in results `JavaSamplerContext` used by `AbstractJavaSamplerClient` has been enhanced with new methods to easy plugin development. JMeter now distributes additional Maven sources and javadoc artifacts into [Maven repository](https://repo1.maven.org/maven2/org/apache/jmeter/ApacheJMeter_core/4.0/) Plugins can now register listeners to be notified when a Test Plan is opened/closed ### Live Reporting and Web Report InfluxDB backend listener now allows you to add custom tags by adding them with prefix `TAG_`, see [Bug 61794](https://bz.apache.org/bugzilla/show_bug.cgi?id=61794) In Web Report responseTime distribution graph is more precise Some bugfixes have been made on report generation, see [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900), [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900)61956, [Bug 61899](https://bz.apache.org/bugzilla/show_bug.cgi?id=61899). Graphs _Latency Vs Request_ and _Response Time Vs Request_ did not exceed 1000 RPS due to [Bug 61962](https://bz.apache.org/bugzilla/show_bug.cgi?id=61962) ### Configuration of JMeter environment JVM settings for the JMeter start scripts can be placed in a separate file (`bin/setenv.sh` on Unix and `bin\setenv.bat` on Windows), that gets called on startup. The startup script itself does not have to be edited anymore. ## Incompatible changes - `Start time` and `End date` of Thread Group have been removed, see [Bug 61549](https://bz.apache.org/bugzilla/show_bug.cgi?id=61549) - In distributed testing, mode `Hold` has been removed. Use alternative and more efficient modes - For 3rd party plugins, the following method in `org.apache.jmeter.gui.tree.JMeterTreeNode` has been dropped for migration to Java 9 ([Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529)) ```java public Enumeration<JMeterTreeNode> children() ``` - `tearDown Thread Group` will now run on stop and shutdown of a test by default. If you don't want this behaviour, uncheck `Run tearDown Thread Groups after shutdown of main threads` on `Test Plan` element, see [Bug 61656](https://bz.apache.org/bugzilla/show_bug.cgi?id=61656) - Properties `sampleresult.getbytes.headers_size` and `sampleresult.getbytes.body_real_size` have been dropped, see [Bug 61587](https://bz.apache.org/bugzilla/show_bug.cgi?id=61587) - JMeter will now save your test plan whenever you run it. This behaviour can be controlled by property `save_automatically_before_run`, see [Bug 61731](https://bz.apache.org/bugzilla/show_bug.cgi?id=61731) - Workbench element has been dropped, you now directly add `Non Test Element` as children of Test Plan. When loading a Test Plan that contains the element JMeter will move the `Mirror Server`, `Property Display` and HTTP(s) `Test Script Recorder` elements as direct children of Test Plan. For any other element, it will create a `Test Fragment` element called `Workbench Test Fragment and move the elements in it`. - Following classes have been dropped (`org.apache.jmeter.functions.util.ArgumentEncoder`, `org.apache.jmeter.functions.util.ArgumentDecoder`), see [PR#335](https://github.com/apache/jmeter/pull/335) - In JMS Point-to-Point sampler, setting timeout to 0 will now mean infinite timeout while previously it would be switched to 2000 ms, see [Bug 61829](https://bz.apache.org/bugzilla/show_bug.cgi?id=61829) - When Assertions are at different scopes, they are executed starting with the most OUTER one to the most INNER one. See [Bug 61846](https://bz.apache.org/bugzilla/show_bug.cgi?id=61846) - JMeter now starts by default using English locale. This change is due to missing translations in many supported languages. You can change locale by modifying in jmeter and jmeter.bat (or preferably setenv.sh/setenv.bat) the `JVM_ARGS` system property values. We'd also be very grateful if you can contribute translations in supported languages. - SwitchController now trims by default the content of switch to avoid issue related to unwanted spaces. See [Bug 61771](https://bz.apache.org/bugzilla/show_bug.cgi?id=61771) - JMeter JVM heap settings have changed from `-Xms512m -Xmx512m` to `-Xms1g -Xmx1g` - Beanshell version has been upgraded to bsh-2.0b6 which introduces breaking changes and more strict parsing rules ## Improvements #### HTTP Samplers and Test Script Recorder - [PR#316](https://github.com/apache/jmeter/pull/316)Warn about empty truststore loading. Contributed by Vincent Herilier (https://github.com/vherilier) - [Bug 61639](https://bz.apache.org/bugzilla/show_bug.cgi?id=61639)HTTP(S) Test Script Recorder: In request filtering tab, uncheck by default "Notify Child Listeners of filtered samplers" - [Bug 61672](https://bz.apache.org/bugzilla/show_bug.cgi?id=61672)HTTP(S) Test Script Recorder: Have the ability to choose the sampler name while keeping the ability to just add a prefix - [Bug 53957](https://bz.apache.org/bugzilla/show_bug.cgi?id=53957)HTTP Request: In Parameters tab, allow pasting of content coming from Firefox and Chrome (unparsed) - [Bug 61587](https://bz.apache.org/bugzilla/show_bug.cgi?id=61587)Drop properties `sampleresult.getbytes.headers_size` and `sampleresult.getbytes.body_real_size` - [Bug 61843](https://bz.apache.org/bugzilla/show_bug.cgi?id=61843)HTTP(S) Test Script Recorder: Add SAN to JMeter generated CA Certificate. Contributed by Matthew Buckett - [Bug 61901](https://bz.apache.org/bugzilla/show_bug.cgi?id=61901)Support for `https.cipherSuites` System property. Contributed by Jeremy Arnold (jeremy at arnoldzoo.org) #### Other samplers - [Bug 61544](https://bz.apache.org/bugzilla/show_bug.cgi?id=61544)JMS Point-to-Point Sampler: Enhance communication styles with read, browse, clear. Based on a contribution by Benny van Wijngaarden (benny at smaragd-it.nl) - [Bug 61829](https://bz.apache.org/bugzilla/show_bug.cgi?id=61829)JMS Point-to-Point: If Receive Queue is empty and a timeout is set, it is not taken into account. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61739](https://bz.apache.org/bugzilla/show_bug.cgi?id=61739)Java Request / JavaSamplerClient: Improve `org.apache.jmeter.protocol.java.sampler.JavaSamplerContext` - [Bug 61762](https://bz.apache.org/bugzilla/show_bug.cgi?id=61762)Start Next Thread Loop should be used everywhere #### Controllers - [Bug 61675](https://bz.apache.org/bugzilla/show_bug.cgi?id=61675)If Controller: Use expression by default and add a warning when the other mode is used. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61770](https://bz.apache.org/bugzilla/show_bug.cgi?id=61770)Module Controller: Inform user in UI that he needs to have at least one Controller in his plan. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61771](https://bz.apache.org/bugzilla/show_bug.cgi?id=61771)SwitchController: Switch field should be trimmed by safety #### Listeners - [Bug 57760](https://bz.apache.org/bugzilla/show_bug.cgi?id=57760)View Results Tree: Cookie Header is wrongly shown as empty (no cookies) when viewing a recorder Sample Result. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61769](https://bz.apache.org/bugzilla/show_bug.cgi?id=61769)View Results Tree: Use syntax highlighter in XPath Tester, JSON Path Tester and CSS/JQuery Tester. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61776](https://bz.apache.org/bugzilla/show_bug.cgi?id=61776)View Results Tree: Expansion of `Add expand/collapse all` menu in render XML view. Contributed by Maxime Chassagneux and Graham Russell - [Bug 61852](https://bz.apache.org/bugzilla/show_bug.cgi?id=61852)View Results Tree: Add a Boundary Extractor Tester - [Bug 61794](https://bz.apache.org/bugzilla/show_bug.cgi?id=61794)Influxdb backend: Add as many custom tags as wanted by just create new lines and prefix theirs name by "`TAG_`" on the GUI backend listener #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60213](https://bz.apache.org/bugzilla/show_bug.cgi?id=60213)New component: Boundary based extractor - [Bug 61845](https://bz.apache.org/bugzilla/show_bug.cgi?id=61845)New Component JSON Assertion based on AtlanBH JSON Path Assertion donated to JMeter-Plugins and migrated into JMeter core by Artem Fedorov (artem at blazemeter.com) - [Bug 61931](https://bz.apache.org/bugzilla/show_bug.cgi?id=61931)New Component: Precise Throughput Timer, timer that produces Poisson arrivals with given constant throughput. Contributed by Vladimir Sitnikov (sitnikov.vladimir at gmail.com) - [Bug 61644](https://bz.apache.org/bugzilla/show_bug.cgi?id=61644)HTTP Cache Manager: "Use Cache-Control/Expires header when processing GET requests" should be checked by default - [Bug 61645](https://bz.apache.org/bugzilla/show_bug.cgi?id=61645)Response Assertion: Add ability to assert on Request Data - [Bug 51140](https://bz.apache.org/bugzilla/show_bug.cgi?id=51140)Response Assertion: add ability to set a specific error/failure message that is later shown in the Assertion Result. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61534](https://bz.apache.org/bugzilla/show_bug.cgi?id=61534)Convert AssertionError to a failed assertion, allowing users to use assert in their code. Fixing a regression introduced in 3.2 - [Bug 61756](https://bz.apache.org/bugzilla/show_bug.cgi?id=61756)Extractors: Improve label name "Reference name" to make it clear what it makes - [Bug 61758](https://bz.apache.org/bugzilla/show_bug.cgi?id=61758)`Apply to:` field in Extractors, Assertions: When entering a value in `JMeter Variable Name`, the radio box `JMeter Variable Name` should be selected by default. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61846](https://bz.apache.org/bugzilla/show_bug.cgi?id=61846)Scoped Assertion should follow same order of evaluation as Post Processors #### Functions - [Bug 61724](https://bz.apache.org/bugzilla/show_bug.cgi?id=61724)Add `__digest` function to provide computing of Hashes (SHA-XXX, MDX). Based on a contribution by orimarko at gmail.com - [Bug 61735](https://bz.apache.org/bugzilla/show_bug.cgi?id=61735)Add `__dateTimeConvert` function to provide date formats conversions. Based on a contribution by orimarko at gmail.com - [Bug 61760](https://bz.apache.org/bugzilla/show_bug.cgi?id=61760)Add `__isPropDefined` and `__isVarDefined` functions to know if property or variable exist. Contributed by orimarko at gmail.com - [Bug 61759](https://bz.apache.org/bugzilla/show_bug.cgi?id=61759)Add `__changeCase` function to change different cases of a string. Based on a contribution by orimarko at gmail.com - [Bug 61561](https://bz.apache.org/bugzilla/show_bug.cgi?id=61561)Function helper dialog should display exception in result - [Bug 61738](https://bz.apache.org/bugzilla/show_bug.cgi?id=61738)Function Helper Dialog: Add Copy in Generate and clarify labels. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 62027](https://bz.apache.org/bugzilla/show_bug.cgi?id=62027)Help: Introduce property `help.local` to allow choosing between local (offline) documentation and online documentation - [Bug 61593](https://bz.apache.org/bugzilla/show_bug.cgi?id=61593)Remove Detail, Add, Add from Clipboard, Delete buttons in Function Helper GUI #### I18N - [Bug 61606](https://bz.apache.org/bugzilla/show_bug.cgi?id=61606)Translate button `Browse…` in some elements (which use FileEditor class) - [Bug 61747](https://bz.apache.org/bugzilla/show_bug.cgi?id=61747)HTTP(S) Test Script Recorder: add the missing doc to "Create transaction after request (ms)" #### Report / Dashboard - [Bug 61871](https://bz.apache.org/bugzilla/show_bug.cgi?id=61871)Reduce jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity default value from 500ms to 100ms - [Bug 61879](https://bz.apache.org/bugzilla/show_bug.cgi?id=61879)Remove useless files in HTML report template #### General - [Bug 61591](https://bz.apache.org/bugzilla/show_bug.cgi?id=61591)Drop Workbench from test tree. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61549](https://bz.apache.org/bugzilla/show_bug.cgi?id=61549)Thread Group: Remove start and end date - [Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529)Migration to Java 9. Partly contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61709](https://bz.apache.org/bugzilla/show_bug.cgi?id=61709)SampleResult: Add a method `setIgnore()` to make JMeter ignore the SampleResult and not send it to listeners - [Bug 61806](https://bz.apache.org/bugzilla/show_bug.cgi?id=61806)Allow to use `SampleResult#setIgnore()` in post-processors and assertions script (JSR223 elements) - [Bug 61607](https://bz.apache.org/bugzilla/show_bug.cgi?id=61607)Add browse button in all BeanShell elements to select BeanShell script - [Bug 61627](https://bz.apache.org/bugzilla/show_bug.cgi?id=61627)Don't clear LogView anymore when clicking on Warning/Errors Indicator - [Bug 61629](https://bz.apache.org/bugzilla/show_bug.cgi?id=61629)Add Think Times to Children menu should not consider disabled elements - [Bug 61655](https://bz.apache.org/bugzilla/show_bug.cgi?id=61655)SampleSender: Drop HoldSampleSender implementation - [Bug 61656](https://bz.apache.org/bugzilla/show_bug.cgi?id=61656)`tearDown Thread Group` should run by default at stop or shutdown of test - [Bug 61659](https://bz.apache.org/bugzilla/show_bug.cgi?id=61659)`JMeterVariables#get()` should apply `toString()` on non string objects - [Bug 61555](https://bz.apache.org/bugzilla/show_bug.cgi?id=61555)Metaspace should be restricted as default - [Bug 61693](https://bz.apache.org/bugzilla/show_bug.cgi?id=61693)JMeter aware of Docker (`-XX:+UnlockExperimentalVMOptions` `-XX:+UseCGroupMemoryLimitForHeap`) - [Bug 61694](https://bz.apache.org/bugzilla/show_bug.cgi?id=61694)Add `-server` option in `jmeter.bat` - [Bug 61697](https://bz.apache.org/bugzilla/show_bug.cgi?id=61697)Introduce Darcula Look And Feel to make JMeter UI more attractive - [Bug 61704](https://bz.apache.org/bugzilla/show_bug.cgi?id=61704)Toolbar: Improve a bit the right part - [Bug 61731](https://bz.apache.org/bugzilla/show_bug.cgi?id=61731)Enhance Test plan Backup with option to save before run. Based on a contribution by orimarko at gmail.com - [Bug 61640](https://bz.apache.org/bugzilla/show_bug.cgi?id=61640)JSR223 Test Elements: Enable by default caching. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61785](https://bz.apache.org/bugzilla/show_bug.cgi?id=61785)Add **Help → Useful links** to create issues and download nightly build - [Bug 61808](https://bz.apache.org/bugzilla/show_bug.cgi?id=61808)Fix main frame position. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61802](https://bz.apache.org/bugzilla/show_bug.cgi?id=61802)Loop / ForEach Controller should expose a variable for current iteration. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [PR#349](https://github.com/apache/jmeter/pull/349)Add i18n resources(zh_CN). Contributed by Helly Guo (https://github.com/hellyguo) - [PR#351](https://github.com/apache/jmeter/pull/351)Fixed about dialog position on first view. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#352](https://github.com/apache/jmeter/pull/352)Menu bar - added mnemonics to more menu items. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#353](https://github.com/apache/jmeter/pull/353)Re-wrote some existing tests in Spock. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61919](https://bz.apache.org/bugzilla/show_bug.cgi?id=61919)UX: Reorder Menus. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61920](https://bz.apache.org/bugzilla/show_bug.cgi?id=61920)Plugins: Add ability to listen to Test Plan loading/closing. Contributed by Peter Doornbosch (https://bitbucket.org/pjtr/) - [Bug 61935](https://bz.apache.org/bugzilla/show_bug.cgi?id=61935)Plugins: Let GUI component (dynamically) decide whether it can be added via the menu or not. Contributed by Peter Doornbosch (https://bitbucket.org/pjtr/) - [Bug 61969](https://bz.apache.org/bugzilla/show_bug.cgi?id=61969)When changing LAF through GUI, user should be informed that it is better to restart - [Bug 61970](https://bz.apache.org/bugzilla/show_bug.cgi?id=61970)JMeter now uses English as default locale to avoid missing translations in some locales make UI look weird - [Bug 56368](https://bz.apache.org/bugzilla/show_bug.cgi?id=56368)Create and Deploy source artifacts to Maven central - [Bug 61973](https://bz.apache.org/bugzilla/show_bug.cgi?id=61973)Create and Deploy javadoc artifacts to Maven central - [PR#371](https://github.com/apache/jmeter/pull/371)Fix example in documentation for [XPath Assertion](/user-manual/component-reference/#XPath_Assertion). Contributed by Konstantin Kalinin (kkalinin at hotmail.com) - [Bug 62039](https://bz.apache.org/bugzilla/show_bug.cgi?id=62039)Distributed testing: Provide ability to use SSL ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 61569](https://bz.apache.org/bugzilla/show_bug.cgi?id=61569)JMS Point-to-Point Test Plan: Synchronization issue when putting reply. Contributed by Igor Panainte (panainte.i at gmail.com) #### Other Samplers - [Bug 61698](https://bz.apache.org/bugzilla/show_bug.cgi?id=61698)Test Action: It stop is selected, samplers following Test Action can run - [Bug 61707](https://bz.apache.org/bugzilla/show_bug.cgi?id=61707)Test Action: Target is ignored when pause is selected, so it should be disabled - [Bug 61827](https://bz.apache.org/bugzilla/show_bug.cgi?id=61827)JMSPublisher: Don't add new line at the end of the file. Contributed by Graham Russell (graham at ham1.co.uk) #### Controllers - [Bug 61556](https://bz.apache.org/bugzilla/show_bug.cgi?id=61556)Clarify in documentation performance impacts of `\${}` var usage in IfController and groovy. Contributed by Justin McCartney (be_strew at yahoo.co.uk) - [Bug 61713](https://bz.apache.org/bugzilla/show_bug.cgi?id=61713)Test Fragment has option to Change Controller and Insert Parent. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61965](https://bz.apache.org/bugzilla/show_bug.cgi?id=61965)Module and Include Controller should not allow to add meaningless elements in their context. - [Bug 62062](https://bz.apache.org/bugzilla/show_bug.cgi?id=62062)ThroughputController: StackOverFlowError triggered when throughput=0 (Total Executions or Percentage Executions) Partly implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter Ltd. #### Listeners - [Bug 61742](https://bz.apache.org/bugzilla/show_bug.cgi?id=61742)BackendListener: fix default value for `backend_graphite.send_interval` - [Bug 61878](https://bz.apache.org/bugzilla/show_bug.cgi?id=61878)BackendListener: NPE if BackendListenerClient#getDefaultParameters returns null - [Bug 61950](https://bz.apache.org/bugzilla/show_bug.cgi?id=61950)View Results Tree: Content-Type `audio/mpegurl` is wrongly considered as binary #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61716](https://bz.apache.org/bugzilla/show_bug.cgi?id=61716)Header Manager: When pasting Headers from Firefox or Chrome spaces are introduced as first character of value #### Functions - [Bug 61588](https://bz.apache.org/bugzilla/show_bug.cgi?id=61588)Better log message for [__RandomDate()](/user-manual/functions/#__RandomDate__) function - [Bug 61619](https://bz.apache.org/bugzilla/show_bug.cgi?id=61619)In Function Helper Dialog, the 1st function doesn't display default parameters - [Bug 61628](https://bz.apache.org/bugzilla/show_bug.cgi?id=61628)If split string has empty separator default separator is not used - [Bug 61752](https://bz.apache.org/bugzilla/show_bug.cgi?id=61752)`__RandomDate`: Function does not allow missing last parameter used for variable name #### I18N #### Report / Dashboard - [Bug 61807](https://bz.apache.org/bugzilla/show_bug.cgi?id=61807)Web Report: fix error in `getTop5ErrorMetrics`. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61900](https://bz.apache.org/bugzilla/show_bug.cgi?id=61900)Report Generator: Report generation fails if separator is a regex reserved char like `|` - [Bug 61925](https://bz.apache.org/bugzilla/show_bug.cgi?id=61925)CsvSampleReader does not increment row in nextSample(). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61956](https://bz.apache.org/bugzilla/show_bug.cgi?id=61956)Report Generation: `-f` of `-forceDeleteResultFile` option does not work. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61899](https://bz.apache.org/bugzilla/show_bug.cgi?id=61899)Report Generation: When `jmeter.save.saveservice.print_field_names` is false and `sample_variables` are set report generation fails. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61962](https://bz.apache.org/bugzilla/show_bug.cgi?id=61962)Latency Vs Request and Response Time Vs Request graphs do not exceed 1000 RPS. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 61661](https://bz.apache.org/bugzilla/show_bug.cgi?id=61661)Avoid startup/shutdown problems due to 3rd party Thread Listener plugins throwing RuntimeException - [Bug 61625](https://bz.apache.org/bugzilla/show_bug.cgi?id=61625)File Editor used in BeanInfo behaves strangely under all LAFs with impact on CSVDataSet, JSR223, BSF, Beanshell Element - [Bug 61844](https://bz.apache.org/bugzilla/show_bug.cgi?id=61844)Maven pom.xml: Libraries used in testing should have scope test - [Bug 61842](https://bz.apache.org/bugzilla/show_bug.cgi?id=61842)Saving with no changes causes a save and duplicate, identical backup file ## Non-functional changes - Updated to bsh-2.0b6 (from bsh-2.0b5) - Updated to groovy-all-2.4.13 (from groovy-all-2.4.12) - Updated to rhino-1.7.7.2 (from rhino-1.7.7.1) - Updated to tika-core and tika-parsers 1.17 (from 1.16) - Updated to commons-dbcp2-2.2.0 (from 2.1.1) - Updated to caffeine 2.6.1 (from 2.5.5) - Updated to commons-codec-1.11 (from 1.10) - Updated to commons-io-2.6 (from 2.5) - Updated to commons-lang3-3.7 (from 3.6) - Updated to commons-pool2-2.5.0 (from 2.4.2) - Updated to asm-6.0 (from 5.2) - Updated to jsoup-1.11.2 (from 1.10.3) - Updated to cglib-nodep-3.2.6 (from 3.2.5) - Updated to ph-css 6.0.0 (from 5.0.4) - Updated to ph-commons 9.0.0 (from 8.6.6) - Updated to log4j2 2.10.0 (from 2.8.2) - Updated to httpcore 4.4.9 (from 4.4.7) - Updated to httpclient 4.5.5 (from 4.5.3) - Updated to jodd 4.1.4 (from 3.8.6) - [Bug 61642](https://bz.apache.org/bugzilla/show_bug.cgi?id=61642)Improve FTP test coverage - [Bug 61641](https://bz.apache.org/bugzilla/show_bug.cgi?id=61641)Improve JMS test coverage - [Bug 61651](https://bz.apache.org/bugzilla/show_bug.cgi?id=61651)Improve TCP test coverage - [Bug 61651](https://bz.apache.org/bugzilla/show_bug.cgi?id=61651)Improve OS test coverage. Partly contributed by Aleksei Balan (abalanonline at gmail.com) - [PR#319](https://github.com/apache/jmeter/pull/319)Removed commented out code. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#322](https://github.com/apache/jmeter/pull/322)General JavaDoc cleanup. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#323](https://github.com/apache/jmeter/pull/323)Extracted method and used streams to improve readability. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#324](https://github.com/apache/jmeter/pull/324)Save backup refactor. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#327](https://github.com/apache/jmeter/pull/327)Utilising more modern Java, simplifying code and formatting code and comments. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#332](https://github.com/apache/jmeter/pull/332)Add the spock framework for groovy unit tests. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#334](https://github.com/apache/jmeter/pull/334)Enable running of JUnit tests from within IntelliJ with default config. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#335](https://github.com/apache/jmeter/pull/335)Removed `functions.util.*` as they don't seem to be used (for many years). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61867](https://bz.apache.org/bugzilla/show_bug.cgi?id=61867)[PR#345](https://github.com/apache/jmeter/pull/345)Updated to latest checkstyle (v8.5), Added many more rules to checkstyle, Included checking of test files and more file types. Contributed by Graham Russell (graham at ham1.co.uk) - [PR#350](https://github.com/apache/jmeter/pull/350)Parallelised unit tests. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 61966](https://bz.apache.org/bugzilla/show_bug.cgi?id=61966)Setup Test Results Analyzer in jenkins - [PR#343](https://github.com/apache/jmeter/pull/343)Reduce the size of some images in the documentation. Contributed by Graham Russell (graham at ham1.co.uk) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Igor Panainte (panainte.i at gmail.com) - Emilian Bold (emi at apache.org) - [Ubik Load Pack](https://ubikloadpack.com) - Justin McCartney (be_strew at yahoo.co.uk) - Vincent Herilier (https://github.com/vherilier) - Aleksei Balan (abalanonline at gmail.com) - Graham Russell (graham at ham1.co.uk) - orimarko at gmail.com - Artem Fedorov (artem at blazemeter.com) - [BlazeMeter Ltd](https://www.blazemeter.com) - Benny van Wijngaarden (benny at smaragd-it.nl) - Matthew Buckett (https://github.com/buckett) - Helly Guo (https://github.com/hellyguo) - Peter Doornbosch (https://bitbucket.org/pjtr/) - Jeremy Arnold (jeremy at arnoldzoo.org) - Vladimir Sitnikov (sitnikov.vladimir at gmail.com) - Konstantin Kalinin (kkalinin at hotmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - user7294900 on Stackoverflow (orimarko at gmail.com) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 3.3 Release Notes URL: https://docs.jmeter.ai/releases/3-3/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 3.3, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | New and Noteworthy | 2 | | Incompatible changes | 5 | | Improvements | 25 | | Bug fixes | 36 | | Non-functional changes | 15 | ## New and Noteworthy :::note JMeter does not yet support JAVA 9, next JMeter version will support it, you can help and follow progress on this item in [Bug 61529](https://bz.apache.org/bugzilla/show_bug.cgi?id=61529). ::: :::note Using last minor version of JAVA 8 is advised to avoid facing any JDK bug. ::: ### Core improvements HTTP Sampler now supports Brotli decompression. CacheManager now completely supports Vary header. InfluxDB BackendListener now supports sending results to InfluxDB through UDP protocol. ![changes/3.3/influxdb_udp.png](/images/screenshots/changes/3.3/influxdb_udp.png) It has also been enhanced to send number of errors by response code and message for each transaction TCP Sampler now computes latency, see [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156) Upgraded dependencies to last available versions bringing performance improvements and bug fixes Continued to improve the quality of our code and tests coverage. See [Quality report](https://builds.apache.org/analysis/overview?id=12927) ### UX improvements More work has been done to better support HiDPI. Some bugs, that crept in with the work on lowering the memory usage of View Results Tree, were fixed. The constant `DEFAULT_IMPLEMENTATION` was removed from CookieManager, as it lost it purpose with the removal of the alternate HTTP Client implementation in the last release JDBC Sampler UX has been improved by adding select boxes for drivers and validation queries. ![changes/3.3/jdbc_config_validation_driver_url.png](/images/screenshots/changes/3.3/jdbc_config_validation_driver_url.png) ![changes/3.3/jdbc_config_validation_query.png](/images/screenshots/changes/3.3/jdbc_config_validation_query.png) If Controller and While Controller UX have been improved ![changes/3.3/jmeter_if_controller.png](/images/screenshots/changes/3.3/jmeter_if_controller.png) ### Report/Dashboard improvements A new Help menu item has been added to simplify configuration of report generation. ![changes/3.3/jmeter_export_transactions_menu.png](/images/screenshots/changes/3.3/jmeter_export_transactions_menu.png) ![changes/3.3/jmeter_export_transactions_result.png](/images/screenshots/changes/3.3/jmeter_export_transactions_result.png) ### Documentation improvements Incorporated feedback about unclear documentation. ### Functions Function Helper Dialog: a new field that shows execution result has been added. ![changes/3.3/jmeter_function_result.png](/images/screenshots/changes/3.3/jmeter_function_result.png) New functions: - `[__timeShift](/user-manual/functions/#__timeShift)` - return a date in various formats with the specified amount of seconds/minutes/hours/days added. ![changes/3.3/jmeter_function_add_time.png](/images/screenshots/changes/3.3/jmeter_function_add_time.png) - `[__RandomDate](/user-manual/functions/#__RandomDate)` - generate random date within a specific date range. ![changes/3.3/jmeter_function_random_date.png](/images/screenshots/changes/3.3/jmeter_function_random_date.png) ## Incompatible changes - In InfluxDbBackendListenerClient, `statut` property has been renamed to `status` - In CookieManager, `DEFAULT_POLICY` and `DEFAULT_IMPLEMENTATION` constants are now private. :::note If you're using `ignorecookies` with HC3CookieHandler (< JMeter 3.1) configuration will be reset, ensure you put it back. ::: - JMeter will not truncate anymore by default responses exceeding 10 MB. If you want to enable this truncation, see property `httpsampler.max_bytes_to_store_per_request` - `org.apache.jmeter.protocol.tcp.sampler.TCPClient.read(InputStream)` has been deprecated in favor or org.apache.jmeter.protocol.tcp.sampler.TCPClient.read(InputStream, SampleResult), ensure you update your implementation to be able to compute latency, see [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156) #### Removed elements or functions - `_StringFromFile` function has been dropped, use `[__StringFromFile](/user-manual/functions/#__StringFromFile)` instead ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 61056](https://bz.apache.org/bugzilla/show_bug.cgi?id=61056)HTTP : Support brotli decoding - [Bug 61135](https://bz.apache.org/bugzilla/show_bug.cgi?id=61135)CookieManager : Drop Implementation select box and cleanup class - [Bug 61492](https://bz.apache.org/bugzilla/show_bug.cgi?id=61492)HTTP(S) Test Script Recorder : Add the possibility to change the value of proxy.pause in the GUI #### Other samplers - [Bug 61320](https://bz.apache.org/bugzilla/show_bug.cgi?id=61320)Test Action : Set duration to `0` by default - [Bug 61504](https://bz.apache.org/bugzilla/show_bug.cgi?id=61504)JDBC Connection Configuration : Set Max Number of Connections to `0` by default - [Bug 61505](https://bz.apache.org/bugzilla/show_bug.cgi?id=61505)JDBC Connection Configuration : Set "Validation Query" to `empty` by default to use `isValid` method of JDBC driver - [Bug 61506](https://bz.apache.org/bugzilla/show_bug.cgi?id=61506)JDBC Connection Configuration : Add a list for main databases validation queries for "Validation Query" attribute - [Bug 61507](https://bz.apache.org/bugzilla/show_bug.cgi?id=61507)JDBC Connection Configuration : Add a list for main databases JDBC driver class name for "JDBC Driver class" attribute - [Bug 61525](https://bz.apache.org/bugzilla/show_bug.cgi?id=61525)OS Process Sampler : Add browser button to Command and Working directory fields - [Bug 60156](https://bz.apache.org/bugzilla/show_bug.cgi?id=60156)TCPSampler : Latency is not measured for TCP Sampler. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61039](https://bz.apache.org/bugzilla/show_bug.cgi?id=61039)CSV data set config : Add browser button to Filename field - [Bug 61527](https://bz.apache.org/bugzilla/show_bug.cgi?id=61527)CSV data set config : Add a list for main file encoding values for File encoding attribute #### Controllers - [Bug 61131](https://bz.apache.org/bugzilla/show_bug.cgi?id=61131)IfController and WhileController : Improve UX #### Listeners - [Bug 61167](https://bz.apache.org/bugzilla/show_bug.cgi?id=61167)InfluxdbBackendListener : add number of errors by response code and message for each transaction - [Bug 61068](https://bz.apache.org/bugzilla/show_bug.cgi?id=61068)Introduce property `resultcollector.action_if_file_exists` to control the popup "File already exists" when starting a test - [Bug 61457](https://bz.apache.org/bugzilla/show_bug.cgi?id=61457)InfluxDB backend listener client : Support sending result to InfluxDB through UDP protocol. Partly based on [PR#302](https://github.com/apache/jmeter/pull/302) by Junlong Wu (github id mybreeze77) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 61176](https://bz.apache.org/bugzilla/show_bug.cgi?id=61176)[PR#298](https://github.com/apache/jmeter/pull/298) Cache responses that have `vary` header in the `CacheManager`. #### Functions - [Bug 61040](https://bz.apache.org/bugzilla/show_bug.cgi?id=61040)Add a time shifting function - [Bug 61126](https://bz.apache.org/bugzilla/show_bug.cgi?id=61126)Function Helper Dialog : Add a field that shows execution result - [Bug 61508](https://bz.apache.org/bugzilla/show_bug.cgi?id=61508)Add a random date within a specific date range function #### I18N - [Bug 61509](https://bz.apache.org/bugzilla/show_bug.cgi?id=61509)Better label/translation/documentation for labels start and max for Counter element #### Report / Dashboard - [Bug 61481](https://bz.apache.org/bugzilla/show_bug.cgi?id=61481)Help Menu Item to export transaction for Web report #### General - When looking for classes in `ActionRouter`, fall back to location of the jar, where `ActionRouter` is loaded from. Provided by Emilian Bold (emi at apache.org) - [Bug 61510](https://bz.apache.org/bugzilla/show_bug.cgi?id=61510)Set 'Max Number of Connections' to `0` into 'JDBC Connection Configuration' for the 'JDBC Load Test template' - [Bug 61399](https://bz.apache.org/bugzilla/show_bug.cgi?id=61399)Make some bin and extras scripts Shellcheck compatible. Contributed by Wolfgang Wagner (internetwolf2000 at hotmail.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 61384](https://bz.apache.org/bugzilla/show_bug.cgi?id=61384)Don't set the charset on enclosing `multipart/form-data` header. It irritates some servers. The charset was added sometime back while refactoring to use a newer API of http client. See [Bug 56141](https://bz.apache.org/bugzilla/show_bug.cgi?id=56141) for more info. - [Bug 61456](https://bz.apache.org/bugzilla/show_bug.cgi?id=61456)`java.lang.ArrayIndexOutOfBoundsException` when recording with JMeter and weird Basic Auth Authorization header - [Bug 61395](https://bz.apache.org/bugzilla/show_bug.cgi?id=61395)Large server response truncation can impact recording #### Other Samplers - [Bug 60889](https://bz.apache.org/bugzilla/show_bug.cgi?id=60889)JMeter JDBC sample calls `SELECT USER()` when testing with MySQL JDBC due to `Connection#toString` call for response headers. - [Bug 61259](https://bz.apache.org/bugzilla/show_bug.cgi?id=61259)JDBC Request : since JMeter 3.0, when JDBC auto-commit is `false`, a rollback statement happens each time a Request is executed. Partly contributed by Liu XP (liu_xp2003 at sina.com) - [Bug 61319](https://bz.apache.org/bugzilla/show_bug.cgi?id=61319)Fix regression: SMTP Sampler could not send mails, when no attachments were specified. #### Controllers - [Bug 61375](https://bz.apache.org/bugzilla/show_bug.cgi?id=61375)Use system DNS resolver as last resort, when resolving entries in the static host table. #### Listeners - [Bug 61005](https://bz.apache.org/bugzilla/show_bug.cgi?id=61005)View Results Tree - Browser Response Data is not clearing - [Bug 61121](https://bz.apache.org/bugzilla/show_bug.cgi?id=61121)InfluxdbBackendListenerClient: Only all percentiles are sent, not `KO` and `OK` - [Bug 60961](https://bz.apache.org/bugzilla/show_bug.cgi?id=60961)Try to keep status of selected and expanded elements in View Results Tree when new elements are added. - [Bug 61198](https://bz.apache.org/bugzilla/show_bug.cgi?id=61198)Backend Listener does not work properly in main script when included scripts also contain Backend Listener - [Bug 61493](https://bz.apache.org/bugzilla/show_bug.cgi?id=61493)Max/Min threads are interchanged in Graphite and InfluxDB backend listener #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58743](https://bz.apache.org/bugzilla/show_bug.cgi?id=58743)[PR#293](https://github.com/apache/jmeter/pull/293) TableEditor can't be saved, when using two or more instances. Bugfix provided by Emilian Bold (emi at apache.org) - [Bug 61314](https://bz.apache.org/bugzilla/show_bug.cgi?id=61314)HTTP URL Re-writing Modifier doesn't replace existing `jsessionid` in http sampler, but adds it to the end - [Bug 61336](https://bz.apache.org/bugzilla/show_bug.cgi?id=61336)BeanShell Assertion : mistake in Chinese translation #### Functions - [Bug 61258](https://bz.apache.org/bugzilla/show_bug.cgi?id=61258)StringFromFile function is mentioned twice in the Function helper dialog - [Bug 61260](https://bz.apache.org/bugzilla/show_bug.cgi?id=61260)`[__XPath](/user-manual/functions/#__XPath)` function returns null despite XPath checker founds matches - [Bug 58876](https://bz.apache.org/bugzilla/show_bug.cgi?id=58876)TestPlanName function returns `null` for a newly saved Test Plan and uses previously opened one for a new one #### I18N #### Report / Dashboard - [Bug 61129](https://bz.apache.org/bugzilla/show_bug.cgi?id=61129)Report/Dashboard : If response code is empty but a `failureMessage` is present, Errors and Top 5 Errors are not accurate. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 61151](https://bz.apache.org/bugzilla/show_bug.cgi?id=61151)Report/Dashboard : Top 5 Errors by Sampler and Errors : If assertion contains html code, the html part is hidden #### General - [Bug 60743](https://bz.apache.org/bugzilla/show_bug.cgi?id=60743)Stopping / Shutting down Test might create a deadlock due to HTTPCORE-446, fixed by HttpCore upgrade to 4.4.7 - [Bug 60994](https://bz.apache.org/bugzilla/show_bug.cgi?id=60994)Fix some typo in comments or log messages. [PR#289](https://github.com/apache/jmeter/pull/289) and [PR#290](https://github.com/apache/jmeter/pull/290) - [Bug 61011](https://bz.apache.org/bugzilla/show_bug.cgi?id=61011)Replace occurrences count is not correct (Path and Host replacement are counted twice) - [Bug 61026](https://bz.apache.org/bugzilla/show_bug.cgi?id=61026)Cannot run program "keytool": CreateProcess error=2 when starting JMeter 3.2 in GUI mode - [Bug 61054](https://bz.apache.org/bugzilla/show_bug.cgi?id=61054)Endless loop in `JOrphanUtils#replaceAllWithRegex` when regex is contained in replacement - [Bug 60995](https://bz.apache.org/bugzilla/show_bug.cgi?id=60995)HTTP Test Script Recorder: Port field is very small under some L&F - [Bug 61073](https://bz.apache.org/bugzilla/show_bug.cgi?id=61073)HTTP(S) Test Script Recorder panel have some fields with bad size on HiDPI screen or GTK+ L&F on Linux/XWayland - [Bug 57958](https://bz.apache.org/bugzilla/show_bug.cgi?id=57958)Fix transaction sample not generated if thread stops/restarts. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 61050](https://bz.apache.org/bugzilla/show_bug.cgi?id=61050)Handle uninitialized RessourceBundle more gracefully, when calling `JMeterUtils#getResString`. - [Bug 61100](https://bz.apache.org/bugzilla/show_bug.cgi?id=61100)Invalid GC Log Filename on Windows - [Bug 57962](https://bz.apache.org/bugzilla/show_bug.cgi?id=57962)Allow to use variables (from User Defined Variables only) in all listeners in worker node mode - [Bug 61270](https://bz.apache.org/bugzilla/show_bug.cgi?id=61270)Fixed width fonts too small in text areas to read under HiDPI (user manual bug) - [Bug 61292](https://bz.apache.org/bugzilla/show_bug.cgi?id=61292)Make processing of samples in reporter more robust. - [Bug 61359](https://bz.apache.org/bugzilla/show_bug.cgi?id=61359)When cutting an element from Tree, Test plan is not marked as dirty - [Bug 61380](https://bz.apache.org/bugzilla/show_bug.cgi?id=61380)JMeter shutdown using timers releases thundering herd of interrupted samplers - [Bug 57055](https://bz.apache.org/bugzilla/show_bug.cgi?id=57055)CheckDirty.doAction should clear previousGuiItems for `SUB_TREE_SAVED` ## Non-functional changes - Updated to groovy 2.4.12 (from 2.4.10) - Updated to caffeine 2.5.5 (from 2.4.0) - Updated to commons-jexl3 3.1 (from 3.0) - Updated to ph-css 5.0.4 (from 5.0.3) - Updated to ph-commons 8.6.6 (from 8.6.0) - Updated to log4j2 2.8.2 (from 2.8.1) - Updated to xmlgraphics-commons 2.2 (from 2.1) - Updated to jodd 3.8.6 (from 3.8.1) - Updated to xstream 1.4.10 (from 1.4.9) - Updated to Apache Tika 1.16 (from 1.14) - Updated to jsoup-1.10.3 (from 1.10.2) - Updated to commons-lang3 3.6 (from 3.5) - Updated to json-path 2.4.0 (from 2.2.0) - Updated to httpcore 4.4.7 (from 4.4.6) - [Bug 61438](https://bz.apache.org/bugzilla/show_bug.cgi?id=61438)Change the cryptographic signature of packages from sha-1 to sha-512 ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Anass Benomar (abenomar at umanis.com, Mithrandir0407 at github) - Anthony Kearns (anthony.kearns atrightside.co) - Emilian Bold (emi at apache.org) - Liu XP (liu_xp2003 at sina.com) - [Ubik Load Pack](http://ubikloadpack.com) - Wolfgang Wagner (internetwolf2000 at hotmail.com) - Junlong Wu (github id mybreeze77) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Liu XP (liu_xp2003 at sina.com) - Alexander Podelko (apodelko at yahoo.com) Apologies if we have omitted anyone else. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 3.2 Release Notes URL: https://docs.jmeter.ai/releases/3-2/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 3.2, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 20 | | Improvements | 56 | | Bug fixes | 41 | | Non-functional changes | 18 | ## New and Noteworthy ## Incompatible changes - JMeter requires now at least a Java 8 version to run. - JMeter logging has been migrated to SLF4J and Log4j 2, this involves changes in the way configuration is done. JMeter now relies on standard [Log4j 2 configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html) in file `log4j2.xml` See `Logging changes` section below for further details. - The following jars have been removed after migration from LogKit to SLF4J (see [Bug 60589](https://bz.apache.org/bugzilla/show_bug.cgi?id=60589)): - ApacheJMeter_slf4j_logkit.jar - avalon-framework-4.1.4.jar - commons-logging-1.2.jar - excalibur-logger-1.1.jar - logkit-2.0.jar - The `commons-httpclient-3.1.jar` has been removed after drop of HC3.1 support(see [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727)) - JMeter now sets through `-Djava.security.egd=file:/dev/urandom` the algorithm for secure random - Process Sampler now returns error code 500 when an error occurs. It previously returned an empty value. - In `org.apache.jmeter.protocol.http.sampler.HTTPHCAbstractImpl` two protected static fields (`localhost` and `nonProxyHostSuffixSize`) have been renamed to (`LOCALHOST` and `NON_PROXY_HOST_SUFFIX_SIZE`) to follow static fields naming convention - JMeter now uses by default Oracle Nashorn engine instead of Mozilla Rhino for better performances. This should not have an impact unless you use some advanced features. You can revert back to Rhino by settings property `javascript.use_rhino=true`. You can read this [migration guide](https://wiki.openjdk.java.net/display/Nashorn/Rhino+Migration+Guide) for more details on Nashorn. See [Bug 60672](https://bz.apache.org/bugzilla/show_bug.cgi?id=60672) - [Bug 60729](https://bz.apache.org/bugzilla/show_bug.cgi?id=60729)The Random Variable Config Element now allows minimum==maximum. Previous versions logged an error when minimum==maximum and did not set the configured variable. - [Bug 60730](https://bz.apache.org/bugzilla/show_bug.cgi?id=60730)The JSON PostProcessor now sets the `_ALL` variable (assuming `Compute concatenation var` was checked) even if the JSON path matches only once. Previous versions did not set the `_ALL` variable in this case. #### Removed elements or functions - SOAP/XML-RPC Request has been removed as part of [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727). Use HTTP Request element as a replacement. See [Building a WebService Test Plan](/./usermanual/build-ws-test-plan/) - [Bug 60423](https://bz.apache.org/bugzilla/show_bug.cgi?id=60423)Drop Monitor Results listener - Drop deprecated class `org.apache.jmeter.protocol.system.NativeCommand` - Drop deprecated class `org.apache.jmeter.protocol.http.config.gui.MultipartUrlConfigGui` - Drop deprecated class `org.apache.jmeter.testelement.TestListener` - Drop deprecated class `org.apache.jmeter.reporters.FileReporter` - Drop deprecated class `org.apache.jmeter.protocol.http.modifier.UserSequence` - Drop deprecated class `org.apache.jmeter.protocol.http.parser.HTMLParseError` - Drop unused methods `org.apache.jmeter.protocol.http.control.HeaderManager#getSOAPHeader` and `org.apache.jmeter.protocol.http.control.HeaderManager#setSOAPHeader(Object)` - `org.apache.jmeter.protocol.http.util.Base64Encode` has been deprecated, you can use `java.util.Base64` as a replacement #### Logging changes JMeter logging has been migrated to SLF4J and Log4j 2. This affects logging configuration and 3rd party plugins (if they use JMeter logging). The following sections describe what changes need to be made. ##### Setting the logging level and log file The default logging level can be changed on the command-line using the `-L` parameter. Likewise the `-l` parameter can be used to change the name of the log file. However the `log_level` properties no longer work. The default logging levels and file name are defined in the `log4j2.xml` configuration file in the launch directory (usually `JMETER_HOME/bin`) :::note If you need to change the level programmatically from Groovy code or Beanshell, you need to do the following: ```java import org.apache.logging.log4j.core.config.Configurator; ⋮ final String loggerName = te.getClass().getName(); // te being a JMeter class Configurator.setAllLevels(loggerName, Level.DEBUG); ``` ::: ##### Changes to 3rd party plugin logging :::note 3rd party plugins should migrate their logging code from logkit to slf4j. This is fairly easy and can be done by replacing: ```java import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; ⋮ private static final Logger log = LoggingManager.getLoggerForClass(); ``` By: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; ⋮ private static final Logger log = LoggerFactory.getLogger(YourClassName.class); ``` ::: ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 59934](https://bz.apache.org/bugzilla/show_bug.cgi?id=59934)Fix race-conditions in CssParser. Based on a patch by Jerome Loisel (loisel.jerome at gmail.com) - [Bug 60543](https://bz.apache.org/bugzilla/show_bug.cgi?id=60543)HTTP Request / Http Request Defaults UX: Move to advanced panel Timeouts, Implementation, Proxy. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60548](https://bz.apache.org/bugzilla/show_bug.cgi?id=60548)HTTP Request : Allow Upper Panel to be collapsed - [Bug 57242](https://bz.apache.org/bugzilla/show_bug.cgi?id=57242)HTTP Authorization is not pre-emptively set with HttpClient4 - [Bug 60727](https://bz.apache.org/bugzilla/show_bug.cgi?id=60727)Drop commons-httpclient-3.1 and related elements. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60790](https://bz.apache.org/bugzilla/show_bug.cgi?id=60790)HTTP(S) Test Script Recorder : Improve information on certificate expiration and have better UX for Start/Stop - [Bug 60888](https://bz.apache.org/bugzilla/show_bug.cgi?id=60888)HttpRequest : Add option to allow retrial of all requests including NON Idempotent HTTP methods - [Bug 60896](https://bz.apache.org/bugzilla/show_bug.cgi?id=60896)HTTP(S) Test Script Recorder : Improve UX by reducing number of properties on screen #### Other samplers - [Bug 60740](https://bz.apache.org/bugzilla/show_bug.cgi?id=60740)Support variable for all JMS messages (bytes, object, …) and sources (file, folder), based on [PR#241](https://github.com/apache/jmeter/pull/241). Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60585](https://bz.apache.org/bugzilla/show_bug.cgi?id=60585)JMS Publisher and JMS Subscriber : Allow reconnection on error and pause between errors. Based on [PR#240](https://github.com/apache/jmeter/pull/240) from by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [PR#259](https://github.com/apache/jmeter/pull/259) - Refactored and reformatted SmtpSampler. Contributed by Graham Russell (graham at ham1.co.uk) #### Controllers - [Bug 60672](https://bz.apache.org/bugzilla/show_bug.cgi?id=60672)JavaScript function / IfController : use Nashorn engine by default #### Listeners - [Bug 60144](https://bz.apache.org/bugzilla/show_bug.cgi?id=60144)View Results Tree : Add a more up to date Browser Renderer to replace old Render - [Bug 60542](https://bz.apache.org/bugzilla/show_bug.cgi?id=60542)View Results Tree : Allow Upper Panel to be collapsed. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 52962](https://bz.apache.org/bugzilla/show_bug.cgi?id=52962)Allow sorting by columns for View Results in Table, Summary Report, Aggregate Report and Aggregate Graph. Based on a [PR#245](https://github.com/apache/jmeter/pull/245) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60590](https://bz.apache.org/bugzilla/show_bug.cgi?id=60590)BackendListener : Add Influxdb BackendListenerClient implementation to JMeter. Partly based on [PR#246](https://github.com/apache/jmeter/pull/246) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60591](https://bz.apache.org/bugzilla/show_bug.cgi?id=60591)BackendListener : Add a time boxed sampling. Based on a [PR#237](https://github.com/apache/jmeter/pull/237) by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60678](https://bz.apache.org/bugzilla/show_bug.cgi?id=60678)View Results Tree : Text renderer, search should not popup "Text Not Found" - [Bug 60691](https://bz.apache.org/bugzilla/show_bug.cgi?id=60691)View Results Tree : In Renderers (XPath, JSON Path Tester, RegExp Tester and CSS/JQuery Tester) lower panel is sometimes not visible as upper panel is too big and cannot be resized - [Bug 60687](https://bz.apache.org/bugzilla/show_bug.cgi?id=60687)Make GUI more responsive when it gets a lot of events. - [Bug 60791](https://bz.apache.org/bugzilla/show_bug.cgi?id=60791)View Results Tree: Trigger search on Enter key in Search Feature and display red background if no match - [Bug 60822](https://bz.apache.org/bugzilla/show_bug.cgi?id=60822)ResultCollector does not ensure unique file name entries in files HashMap #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60154](https://bz.apache.org/bugzilla/show_bug.cgi?id=60154)User Parameters GUI: allow rows to be moved up & down in the list. Contributed by Murdecai777 (https://github.com/Murdecai777). - [Bug 60507](https://bz.apache.org/bugzilla/show_bug.cgi?id=60507)Added '`Or`' Function into ResponseAssertion. Based on a contribution from 忻隆 (298015902 at qq.com) - [Bug 58943](https://bz.apache.org/bugzilla/show_bug.cgi?id=58943)Create a Better Think Time experience. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60602](https://bz.apache.org/bugzilla/show_bug.cgi?id=60602)XPath Extractor : Add Match No. to allow extraction randomly, by index or all matches - [Bug 60710](https://bz.apache.org/bugzilla/show_bug.cgi?id=60710)XPath Extractor : When content on which assertion applies is not XML, in View Results Tree the extractor is marked in Red and named SAXParseException. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60712](https://bz.apache.org/bugzilla/show_bug.cgi?id=60712)Response Assertion : Improve Renderer of Patterns - [Bug 59174](https://bz.apache.org/bugzilla/show_bug.cgi?id=59174)Add a table with static hosts to the DNS Cache Manager. This enables better virtual hosts testing with HttpClient4. #### Functions - [Bug 60883](https://bz.apache.org/bugzilla/show_bug.cgi?id=60883)[PR#288](https://github.com/apache/jmeter/pull/288) - Add `\${__escapeXml()}` function. Contributed by Michael Osipov (michaelo at apache.org) #### I18N - Improve translation "`save_as`" in French. Based on a [PR#252](https://github.com/apache/jmeter/pull/252) by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60785](https://bz.apache.org/bugzilla/show_bug.cgi?id=60785)Improvement of Japanese translation. Patch by Kimono (kimono.outfit.am at gmail.com). #### Report / Dashboard - [Bug 60637](https://bz.apache.org/bugzilla/show_bug.cgi?id=60637)Improve Statistics table design ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - [Bug 60112](https://bz.apache.org/bugzilla/show_bug.cgi?id=60112)Report / Dashboard : Add ability to customize APDEX thresholds per Transaction name. Contributed by Stephane Leplus (s.leplus at ubik-ingenierie.com) #### General - [Bug 58164](https://bz.apache.org/bugzilla/show_bug.cgi?id=58164)Check if file already exists on ResultCollector listener before starting the loadtest - [Bug 54525](https://bz.apache.org/bugzilla/show_bug.cgi?id=54525)Search Feature : Enhance it with ability to replace - [Bug 60530](https://bz.apache.org/bugzilla/show_bug.cgi?id=60530)Add API to create JMeter threads while test is running. Based on a contribution by Logan Mauzaize (logan.mauzaize at gmail.com) and Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60514](https://bz.apache.org/bugzilla/show_bug.cgi?id=60514)Ability to apply a naming convention on Children of a Transaction Controller. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60711](https://bz.apache.org/bugzilla/show_bug.cgi?id=60711)Improve Delete button behaviour for Assertions / Header Manager / User Parameters GUIs / Exclude, Include in HTTP(S) Test Script Recorder - [Bug 60593](https://bz.apache.org/bugzilla/show_bug.cgi?id=60593)Switch to G1 GC algorithm - [Bug 60595](https://bz.apache.org/bugzilla/show_bug.cgi?id=60595)Add a SplashScreen at the start of JMeter GUI. Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 55258](https://bz.apache.org/bugzilla/show_bug.cgi?id=55258)Drop "Close" icon from toolbar and add "New" to menu. Partly based on contribution from Sanduni Kanishka (https://github.com/SanduniKanishka) - [Bug 59995](https://bz.apache.org/bugzilla/show_bug.cgi?id=59995)Allow user to change font size with two new menu items and use `jmeter.hidpi.scale.factor` for scaling fonts. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60654](https://bz.apache.org/bugzilla/show_bug.cgi?id=60654)Validation Feature : Be able to ignore BackendListener. Contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com). - [Bug 60646](https://bz.apache.org/bugzilla/show_bug.cgi?id=60646)Workbench : Save it by default - [Bug 60684](https://bz.apache.org/bugzilla/show_bug.cgi?id=60684)Thread Group: Validate ended prematurely by Scheduler with 0 or very short duration. Contributed by Andrew Burton (andrewburtonatwh at gmail.com). - [Bug 60589](https://bz.apache.org/bugzilla/show_bug.cgi?id=60589)Migrate LogKit to SLF4J - Drop Avalon, LogKit and Excalibur with backward compatibility for 3rd party modules. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60565](https://bz.apache.org/bugzilla/show_bug.cgi?id=60565)Migrate LogKit to SLF4J - Optimize logging statements. e.g, message format args, throwable args, unnecessary if-enabled-logging in simple ones, etc. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60564](https://bz.apache.org/bugzilla/show_bug.cgi?id=60564)Migrate LogKit to SLF4J - Replace LogKit loggers with SLF4J ones and keep the current LogKit binding solution for backward compatibility with plugins. Contributed by Woonsan Ko (woonsan at apache.org) - [Bug 60664](https://bz.apache.org/bugzilla/show_bug.cgi?id=60664)Add a UI menu to set log level. Contributed by Woonsan Ko (woonsan at apache.org) - [PR#276](https://github.com/apache/jmeter/pull/276) - Added some translations for polish locale. Contributed by Bartosz Siewniak (barteksiewniak at gmail.com) - [Bug 60792](https://bz.apache.org/bugzilla/show_bug.cgi?id=60792)Create a new Help menu item to create a thread dump - [Bug 60813](https://bz.apache.org/bugzilla/show_bug.cgi?id=60813)JSR223 Test element : Take into account JMeterStopTestNowException, JMeterStopTestException and JMeterStopThreadException - [Bug 60814](https://bz.apache.org/bugzilla/show_bug.cgi?id=60814)Menu : Add `Open Recent` menu item to make recent files loading more obvious - [Bug 60815](https://bz.apache.org/bugzilla/show_bug.cgi?id=60815)Drop "Reset GUI" from menu - [Bug 60886](https://bz.apache.org/bugzilla/show_bug.cgi?id=60886)Build improvements to better enable builds in environments that are behind a proxy. Partly contributed by Michael Osipov (michaelo at apache.org) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 60531](https://bz.apache.org/bugzilla/show_bug.cgi?id=60531)HTTP Cookie Manager : changing Implementation does not update Cookie Policy - [Bug 60575](https://bz.apache.org/bugzilla/show_bug.cgi?id=60575)HTTP GET Requests could have a content-type header without a body. - [Bug 60682](https://bz.apache.org/bugzilla/show_bug.cgi?id=60682)HTTP Request : Get method may fail on redirect due to Content-Length header being set - [Bug 60643](https://bz.apache.org/bugzilla/show_bug.cgi?id=60643)HTTP(S) Test Script Recorder doesn't correctly handle restart or start after stop. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60652](https://bz.apache.org/bugzilla/show_bug.cgi?id=60652)HTTP PUT Requests might leak file descriptors. - [Bug 60689](https://bz.apache.org/bugzilla/show_bug.cgi?id=60689)`httpclient4.validate_after_inactivity` has no impact leading to usage of potentially stale/closed connections - [Bug 60690](https://bz.apache.org/bugzilla/show_bug.cgi?id=60690)Default values for "httpclient4.validate_after_inactivity" and "httpclient4.time_to_live" which are equal to each other makes validation useless - [Bug 60758](https://bz.apache.org/bugzilla/show_bug.cgi?id=60758)HTTP(s) Test Script Recorder : Number request may generate duplicate numbers. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 56939](https://bz.apache.org/bugzilla/show_bug.cgi?id=56939)Parameters are not passed with OPTIONS HTTP Request - [Bug 60778](https://bz.apache.org/bugzilla/show_bug.cgi?id=60778)Http Java Impl does not show Authorization header in SampleResult even if it is sent - [Bug 60837](https://bz.apache.org/bugzilla/show_bug.cgi?id=60837)GET with body, PUT are not retried even if `httpclient4.retrycount` is higher than 0 - [Bug 60842](https://bz.apache.org/bugzilla/show_bug.cgi?id=60842)Trim extracted URLs when loading embedded resources using the Lagarto based HTML Parser. - [Bug 60928](https://bz.apache.org/bugzilla/show_bug.cgi?id=60928)Http Request : Connection Leak when keepalive is used with Embedded Resources #### Other Samplers - [Bug 603982](https://bz.apache.org/bugzilla/show_bug.cgi?id=603982)Guard Exception handler of the `JDBCSampler` against null messages - [Bug 55652](https://bz.apache.org/bugzilla/show_bug.cgi?id=55652)JavaSampler silently resets classname if class can not be found #### Controllers #### Listeners - [Bug 60648](https://bz.apache.org/bugzilla/show_bug.cgi?id=60648)GraphiteBackendListener can lose some metrics at end of test if test is very short - [Bug 60650](https://bz.apache.org/bugzilla/show_bug.cgi?id=60650)AbstractBackendListenerClient does not reset UserMetric between runs - [Bug 60759](https://bz.apache.org/bugzilla/show_bug.cgi?id=60759)View Results Tree : Search feature does not search in URL. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60859](https://bz.apache.org/bugzilla/show_bug.cgi?id=60859)Save Responses to a file : 2 elements with different configuration will overlap #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 60438](https://bz.apache.org/bugzilla/show_bug.cgi?id=60438)[PR#235](https://github.com/apache/jmeter/pull/235) - Clear old variables before extracting new ones in JSON Extractor. Based on a patch by Qi Chen (qi.chensh at ele.me) - [Bug 60607](https://bz.apache.org/bugzilla/show_bug.cgi?id=60607)DNS Cache Manager configuration is ignored - [Bug 60729](https://bz.apache.org/bugzilla/show_bug.cgi?id=60729)The Random Variable Config Element should allow minimum==maximum - [Bug 60730](https://bz.apache.org/bugzilla/show_bug.cgi?id=60730)The JSON PostProcessor should set the `_ALL` variable even if the JSON path matches only once. - [Bug 60747](https://bz.apache.org/bugzilla/show_bug.cgi?id=60747)Response Assertion : Add Request Headers to `Field to Test` - [Bug 60763](https://bz.apache.org/bugzilla/show_bug.cgi?id=60763)XMLAssertion should not leak errors to console - [Bug 60797](https://bz.apache.org/bugzilla/show_bug.cgi?id=60797)TestAction in pause mode can last beyond configured duration of test #### Functions - [Bug 60819](https://bz.apache.org/bugzilla/show_bug.cgi?id=60819)Function __fileToString does not honor the documentation contract when file is not found #### I18N #### Report / Dashboard - [Bug 60726](https://bz.apache.org/bugzilla/show_bug.cgi?id=60726)Report / Dashboard : Top 5 errors by samplers must not take into account the series filtering - [Bug 60919](https://bz.apache.org/bugzilla/show_bug.cgi?id=60919)Report / Dashboard : Latency Vs Request and Response Time Vs Request are wrong if granularity is different from 1000 (1 second) #### General - [Bug 60775](https://bz.apache.org/bugzilla/show_bug.cgi?id=60775)NamePanel ctor calls overrideable method - [Bug 60428](https://bz.apache.org/bugzilla/show_bug.cgi?id=60428)JMeter Graphite Backend Listener throws exception when test ends and `useRegexpForSamplersList` is set to `true`. Based on patch by Liu XP (liu_xp2003 at sina.com) - [Bug 60442](https://bz.apache.org/bugzilla/show_bug.cgi?id=60442)Fix a typo in `build.xml` (gavin at 16degrees.com.au) - [Bug 60449](https://bz.apache.org/bugzilla/show_bug.cgi?id=60449)JMeter Tree : Annoying behaviour when node name is empty - [Bug 60494](https://bz.apache.org/bugzilla/show_bug.cgi?id=60494)Add sonar analysis task to build - [Bug 60501](https://bz.apache.org/bugzilla/show_bug.cgi?id=60501)Search Feature : Performance issue when regexp is checked - [Bug 60444](https://bz.apache.org/bugzilla/show_bug.cgi?id=60444)Intermittent failure of `TestHTTPMirrorThread#testSleep()`. Contributed by Thomas Schapitz (ts-nospam12 at online.de) - [Bug 60621](https://bz.apache.org/bugzilla/show_bug.cgi?id=60621)The "`report-template`" folder is missing from `ApacheJMeter_config-3.1.jar` in maven central - [Bug 60744](https://bz.apache.org/bugzilla/show_bug.cgi?id=60744)GUI elements are not cleaned up when reused during load of Test Plan which can lead them to be partially initialized with a previous state for a new Test Element - [Bug 60812](https://bz.apache.org/bugzilla/show_bug.cgi?id=60812)JMeterThread does not honor contract of JMeterStopTestNowException - [Bug 60857](https://bz.apache.org/bugzilla/show_bug.cgi?id=60857)SaveService omits XML header if _file_encoding is not defined in saveservice.properties - [Bug 60830](https://bz.apache.org/bugzilla/show_bug.cgi?id=60830)Timestamps in CSV file could be corrupted due to sharing a SimpleDateFormatter across threads ## Non-functional changes - [Bug 60415](https://bz.apache.org/bugzilla/show_bug.cgi?id=60415)Drop support for Java 7. - Updated to dnsjava-2.1.8.jar (from 2.1.7) - Updated to groovy 2.4.10 (from 2.4.7) - Updated to httpcore 4.4.6 (from 4.4.5) - Updated to httpclient 4.5.3 (from 4.5.2) - Updated to jodd 3.8.1 (from 3.7.1.jar) - Updated to jsoup-1.10.2 (from 1.10.1) - Updated to ph-css 5.0.3 (from 4.1.6) - Updated to ph-commons 8.6.0 (from 6.2.4) - Updated to slf4j-api 1.7.25 (from 1.7.21) - Updated to asm 5.2 (from 5.1) - Updated to rsyntaxtextarea-2.6.1 (from 2.6.0) - Updated to commons-net-3.6 (from 3.5) - Updated to json-smart-2.3 (from 2.2.1) - Updated to accessors-smart-1.2 (from 1.1) - Converted the old pdf tutorials to xml. - [PR#255](https://github.com/apache/jmeter/pull/255) - Utilised Java 8 (and 7) features to tidy up code. Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 59435](https://bz.apache.org/bugzilla/show_bug.cgi?id=59435)JMeterTestCase no longer supports JUnit3 ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Jerome Loisel (loisel.jerome at gmail.com) - Liu XP (liu_xp2003 at sina.com) - Qi Chen (qi.chensh at ele.me) - (gavin at 16degrees.com.au) - Thomas Schapitz (ts-nospam12 at online.de) - Murdecai777 (https://github.com/Murdecai777) - Logan Mauzaize (logan.mauzaize at gmail.com) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - 忻隆 (298015902 at qq.com) - [Ubik Load Pack](http://ubikloadpack.com) - Graham Russell (graham at ham1.co.uk) - Sanduni Kanishka (https://github.com/SanduniKanishka) - Andrew Burton (andrewburtonatwh at gmail.com) - Woonsan Ko (woonsan at apache.org) - Bartosz Siewniak (barteksiewniak at gmail.com) - Kimono (kimono.outfit.am at gmail.com) - Michael Osipov (michaelo at apache.org) - Stephane Leplus (s.leplus at ubik-ingenierie.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Tuukka Mustonen (tuukka.mustonen at gmail.com) who gave us a lot of useful feedback which helped resolve [Bug 60689](https://bz.apache.org/bugzilla/show_bug.cgi?id=60689) and [Bug 60690](https://bz.apache.org/bugzilla/show_bug.cgi?id=60690) - Amar Darisa (amar.darisa at gmail.com) who helped us with his feedback on [Bug 60682](https://bz.apache.org/bugzilla/show_bug.cgi?id=60682) Apologies if we have omitted anyone else. ## IMPORTANT CHANGES JMeter now requires Java 8. Ensure you use the most up to date version. JMeter logging has been migrated to SLF4J and Log4j 2. This affects configuration and 3rd party plugins, see below **"Logging changes"**. Starting with JMeter version 3.2 the number of results in View Results Tree is limited by default to 500 entries. If you want more entries, you have to set the property `view.results.tree.max_results` to a higher value, or to `0`, if you don't want to impose any limit. You can set the property in bin/user.properties. More info might be found [here](/usermanual/component-reference/#View_Results_Tree). ### Core improvements - JMeter now provides a new BackendListener implementation that interfaces InfluxDB. ![changes/3.2/backend_influxdb.png](/images/screenshots/changes/3.2/backend_influxdb.png) This implementation sends data using Asynchronous HTTP calls to InfluxDB through its [HTTP API](https://docs.influxdata.com/influxdb/v1.2/guides/writing_data/) and give you the following graphs with annotations: ![backend_listener_influxdb_graph.png](/images/screenshots/backend_listener_influxdb_graph.png) - DNS Cache Manager now has a table to allow static host resolution. ![changes/3.2/dns_cache_manager_static_hosts.png](/images/screenshots/changes/3.2/dns_cache_manager_static_hosts.png) - JMS Publisher and Subscriber now allow reconnection on error with pause. ![changes/3.2/jms_publisher_reconnect.png](/images/screenshots/changes/3.2/jms_publisher_reconnect.png) ![changes/3.2/jms_subscriber_reconnect_pause.png](/images/screenshots/changes/3.2/jms_subscriber_reconnect_pause.png) - Variables in JMS Publisher are now supported for all types of messages. Add the encoding type of the file to parse its content - XPath Extractor now allows extraction randomly, by index or for all matches. ![changes/3.2/xpath_extractor_matchno.png](/images/screenshots/changes/3.2/xpath_extractor_matchno.png) - Response Assertion now allows to work on Request Header, provides a "OR" combination and has a better cell renderer ![changes/3.2/response_assertion.png](/images/screenshots/changes/3.2/response_assertion.png) - JMeter now uses Oracle Nashorn Javascript engine instead of Rhino. This provides a faster execution of Javascript. - HTTP HC4 Implementation now provides preemptive Basic Auth enabled by default - Embedded resources download in CSS has been improved to avoid useless repetitive parsing to find the resources - An important work on code quality and code coverage with tests has been done since Sonar has been setup on the project. You can see Sonar report [here](https://builds.apache.org/analysis/overview?id=12927). ### UX improvements - When running a Test, GUI is now more responsive and less impacting on memory usage thanks to a limitation on the number of Sample Results listeners hold and a rework of the way GUI is updated - HTTP Request GUI has been simplified and provides more place for parameters and body. ![changes/3.2/http_request.png](/images/screenshots/changes/3.2/http_request.png) - HTTP(S) Test Script Recorder has been simplified and clarified. ![changes/3.2/http_recorder_1.png](/images/screenshots/changes/3.2/http_recorder_1.png) ![changes/3.2/http_recorder_2.png](/images/screenshots/changes/3.2/http_recorder_2.png) - A `replace` feature has been added to Search feature to allow replacement in some elements. ![changes/3.2/search_replace.png](/images/screenshots/changes/3.2/search_replace.png) :::note ReplaceAll does not do replacement on all elements, it does it on: - HeaderManager: Replacement in values - Http Request: Replacement in Arguments, Path and Host ::: - View Results Tree now provides a more up to date Browser renderer which requires JavaFX. - You can now add through a contextual menu think times, this will add think times between samplers and Transaction Controllers of selected node. ![changes/3.2/menu_add_think_times.png](/images/screenshots/changes/3.2/menu_add_think_times.png) - You can now apply a naming policy to children of a Transaction Controller. A default policy exists but you can implement your own through `[org.apache.jmeter.gui.action.TreeNodeNamingPolicy](/./api/org/apache/jmeter/gui/action/TreeNodeNamingPolicy/)` and configuring property `naming_policy.impl` ![changes/3.2/menu_apply_naming_policy.png](/images/screenshots/changes/3.2/menu_apply_naming_policy.png) - Sorting per column has been added to View Results in Table, Summary Report, Aggregate Report and Aggregate Graph elements. ![changes/3.2/sorting.png](/images/screenshots/changes/3.2/sorting.png) ### Report/Dashboard improvements - Statistics have been reorganized to clarify report: ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - It is now possible to customize APDEX thresholds per transaction based on regular expression or sample name. The below example will apply different thresholds for samples sample(\\d+), sampleA and scenarioB than default ones (500 and 1500 for satisfied and tolerated thresholds) declared: ``` jmeter.reportgenerator.apdex_satisfied_threshold=500 jmeter.reportgenerator.apdex_tolerated_threshold=1500 jmeter.reportgenerator.apdex_per_transaction=sample(\\d+):1000|2000;\ sampleA:3000|4000;\ scenarioB:5000|6000 ``` ### Documentation improvements - PDF Documentations have been migrated and updated to HTML user manual ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 3.1 Release Notes URL: https://docs.jmeter.ai/releases/3-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 3.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 15 | | Improvements | 61 | | Bug fixes | 36 | | Non-functional changes | 17 | ## New and Noteworthy ## Incompatible changes - A cache for CSS Parsing of URLs has been introduced in this version, it is enabled by default. It is controlled by property `css.parser.cache.size`. It can be disabled by setting its value to `0`. See [Bug 59885](https://bz.apache.org/bugzilla/show_bug.cgi?id=59885) - ThroughputController defaults have changed. Now defaults are Percent Executions which is global and no more per user. See [Bug 60023](https://bz.apache.org/bugzilla/show_bug.cgi?id=60023) - Since version 3.1, HTML report ignores empty `Transaction Controller` (possibly generated by `If Controller` or `Throughput Controller`) when computing metrics. This provides more accurate metrics - Since version 3.1, Summariser ignores SampleResults generated by `Transaction Controller` when computing the live statistics, see [Bug 60109](https://bz.apache.org/bugzilla/show_bug.cgi?id=60109) - Since version 3.1, when using Stripped modes (by default `StrippedBatch` is used), response will be stripped also for failing SampleResults, you can revert this to previous behaviour by setting `sample_sender_strip_also_on_error=false` in `user.properties`, see [Bug 60137](https://bz.apache.org/bugzilla/show_bug.cgi?id=60137) - Since version 3.1, `jmeter.save.saveservice.connect_time` property value is `true`, meaning CSV file for results will contain an additional column containing connection time, see [Bug 60106](https://bz.apache.org/bugzilla/show_bug.cgi?id=60106) - Since version 3.1, Random Timer subclasses (Gaussian Random Timer, Uniform Random Timer and Poisson Random Timer) implement interface `[org.apache.jmeter.timers.ModifiableTimer](/./api/org/apache/jmeter/timers/ModifiableTimer/)` - Since version 3.1, if you don't select any language in JSR223 Test Elements, Apache Groovy language will be used. See [Bug 59945](https://bz.apache.org/bugzilla/show_bug.cgi?id=59945) - Since version 3.1, CSV DataSet now trims variable names to avoid issues due to spaces between variables names when configuring CSV DataSet. This should not have any impact for you unless you use space at the beginning or end of your variable names. See [Bug 60221](https://bz.apache.org/bugzilla/show_bug.cgi?id=60221) - Since version 3.1, HTTP Request is able when using HttpClient4 (default) implementation to handle responses bigger than `2147483647` Bytes, that is 2GB. To allow this two properties have been introduced: - `httpsampler.max_bytes_to_store_per_request` (defaults to 10MB) will control what is held in memory. By default JMeter will only keep in memory the first 10MB of a response. If you have responses larger than this value and use assertions that are after the first 10MB, then you must increase this value - `httpsampler.max_buffer_size` will control the buffer used to read the data. Previously JMeter used a buffer equal to Content-Length header which could lead to failures and make JMeter less resistant to faulty applications, but note this may impact response times and give slightly different results than previous versions if your application returned a Content-Length header higher than current default value (65KB) See [Bug 53039](https://bz.apache.org/bugzilla/show_bug.cgi?id=53039) #### Deprecated and removed elements or functions :::note These elements do not appear anymore in the menu, if you need them modify `not_in_menu` property. The JMeter team advises not to use them anymore and migrate to their replacement. ::: - [Bug 60222](https://bz.apache.org/bugzilla/show_bug.cgi?id=60222)Remove deprecated elements Distribution Graph, Spline Visualizer - [Bug 60224](https://bz.apache.org/bugzilla/show_bug.cgi?id=60224)Deprecate `[Monitor Results](/./usermanual/component-reference/#Monitor_Results_(DEPRECATED))` listener. It will be dropped in next version. - [Bug 60323](https://bz.apache.org/bugzilla/show_bug.cgi?id=60323)Deprecate BSF Elements (Use JSR223 Elements instead). They will probably be dropped in N+2 version. The following elements are deprecated: - `[BSF Sampler](/./usermanual/component-reference/#BSF_Sampler_(DEPRECATED))` - `[BSF Listener](/./usermanual/component-reference/#BSF_Listener_(DEPRECATED))` - `[BSF Assertion](/./usermanual/component-reference/#BSF_Assertion_(DEPRECATED))` - `[BSF Timer](/./usermanual/component-reference/#BSF_Timer_(DEPRECATED))` - `[BSF PreProcessor](/./usermanual/component-reference/#BSF_PreProcessor_(DEPRECATED))` - `[BSF PostProcessor](/./usermanual/component-reference/#BSF_PostProcessor_(DEPRECATED))` - [Bug 60225](https://bz.apache.org/bugzilla/show_bug.cgi?id=60225)Drop deprecated `__jexl` function, jexl support in BSF and dependency on `commons-jexl-1.1.jar`. This function can be easily replaced with `[__jexl3](/./usermanual/functions/#__jexl3)` function - [Bug 60268](https://bz.apache.org/bugzilla/show_bug.cgi?id=60268)Drop org.apache.jmeter.gui.action.Analyze and deprecate org.apache.jmeter.reporters.FileReporter (will be removed in next version) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 59882](https://bz.apache.org/bugzilla/show_bug.cgi?id=59882)Reduce memory allocations for better throughput. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) through [PR#217](https://github.com/apache/jmeter/pull/217) and [PR#228](https://github.com/apache/jmeter/pull/228) - [Bug 59885](https://bz.apache.org/bugzilla/show_bug.cgi?id=59885)Optimize css parsing for embedded resources download by introducing a cache. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) through [PR#219](https://github.com/apache/jmeter/pull/219) - [Bug 60092](https://bz.apache.org/bugzilla/show_bug.cgi?id=60092)View Result Tree: Add shortened version of the PUT body to sampler result. - [Bug 60229](https://bz.apache.org/bugzilla/show_bug.cgi?id=60229)Add a new metric : sent_bytes. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 53039](https://bz.apache.org/bugzilla/show_bug.cgi?id=53039)HTTP Request : Be able to handle responses which size exceeds `2147483647` bytes (that is 2GB) - [Bug 60265](https://bz.apache.org/bugzilla/show_bug.cgi?id=60265)HTTP Request : In Files Upload Tab you cannot resize columns - [Bug 60318](https://bz.apache.org/bugzilla/show_bug.cgi?id=60318)Ignore CSS warnings when parsing with ph-css library. - [Bug 60358](https://bz.apache.org/bugzilla/show_bug.cgi?id=60358)Http Request : Allow sending Body Data for HTTP GET request #### Other samplers - [PR#211](https://github.com/apache/jmeter/pull/211)Differentiate the timing for JDBC Sampler. Use latency and connect time. Contributed by Thomas Peyrard (thomas.peyrard at murex.com) - [Bug 59620](https://bz.apache.org/bugzilla/show_bug.cgi?id=59620)Fix button action in "JMS Publisher → Random File from folder specified below" to allow to select a directory - [Bug 60066](https://bz.apache.org/bugzilla/show_bug.cgi?id=60066)Handle CLOBs and BLOBs and limit them if necessary when storing them in result sampler. #### Controllers - [Bug 59351](https://bz.apache.org/bugzilla/show_bug.cgi?id=59351)Improve log/error/message for IncludeController. Partly contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 60023](https://bz.apache.org/bugzilla/show_bug.cgi?id=60023)ThroughputController : Make "Percent Executions" and global the default values. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60082](https://bz.apache.org/bugzilla/show_bug.cgi?id=60082)Validation mode : Be able to force Throughput Controller to run as if it was set to 100% - [Bug 59349](https://bz.apache.org/bugzilla/show_bug.cgi?id=59349)Trim spaces in input filename in IncludeController. - [Bug 60081](https://bz.apache.org/bugzilla/show_bug.cgi?id=60081)Interleave Controller : Add an option to alternate across threads #### Listeners - [Bug 59953](https://bz.apache.org/bugzilla/show_bug.cgi?id=59953)GraphiteBackendListener : Add Average metric. Partly contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 59975](https://bz.apache.org/bugzilla/show_bug.cgi?id=59975)View Results Tree : Text renderer annoyingly scrolls down when content is bulky. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60109](https://bz.apache.org/bugzilla/show_bug.cgi?id=60109)Summariser : Make it ignore TC generated SampleResult in its summary computations - [Bug 59948](https://bz.apache.org/bugzilla/show_bug.cgi?id=59948)Add a formatted and sane HTML source code render to View Results Tree - [Bug 60252](https://bz.apache.org/bugzilla/show_bug.cgi?id=60252)Add sent kbytes/s to Aggregate Report and Summary report - [Bug 60267](https://bz.apache.org/bugzilla/show_bug.cgi?id=60267)UX : In View Results Tree it should be possible to close the Configure popup by typing escape. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 59845](https://bz.apache.org/bugzilla/show_bug.cgi?id=59845)Log messages about JSON Path mismatches at `debug` level instead of `error`. - [PR#212](https://github.com/apache/jmeter/pull/212)Allow multiple selection and delete in HTTP Authorization Manager. Based on a patch by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59816](https://bz.apache.org/bugzilla/show_bug.cgi?id=59816)[PR#213](https://github.com/apache/jmeter/pull/213)Allow multiple selection and delete in HTTP Header Manager. Based on a patch by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59967](https://bz.apache.org/bugzilla/show_bug.cgi?id=59967)CSS/JQuery Extractor : Allow empty default value. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59974](https://bz.apache.org/bugzilla/show_bug.cgi?id=59974)Response Assertion : Add button "`Add from clipboard`". Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60050](https://bz.apache.org/bugzilla/show_bug.cgi?id=60050)CSV Data Set : Make it clear in the logs when a thread will exit due to this configuration - [Bug 59962](https://bz.apache.org/bugzilla/show_bug.cgi?id=59962)Cache Manager does not update expires date when response code is `304`. - [Bug 60018](https://bz.apache.org/bugzilla/show_bug.cgi?id=60018)Timer : Add a factor to apply on pauses. Partly based on a patch by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60203](https://bz.apache.org/bugzilla/show_bug.cgi?id=60203)Use more available space for textarea in XPath Assertion. - [Bug 60220](https://bz.apache.org/bugzilla/show_bug.cgi?id=60220)Rename JSON Path Post Processor to JSON Extractor - [Bug 60221](https://bz.apache.org/bugzilla/show_bug.cgi?id=60221)CSV DataSet : trim variable names - [Bug 59329](https://bz.apache.org/bugzilla/show_bug.cgi?id=59329)Trim spaces in input filename in CSVDataSet. #### Functions - [Bug 59963](https://bz.apache.org/bugzilla/show_bug.cgi?id=59963)New function `__RandomFromMultipleVars`: Ability to compute a random value from values of one or more variables. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59991](https://bz.apache.org/bugzilla/show_bug.cgi?id=59991)New function `__groovy` to evaluate Groovy Script. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### I18N - [PR#214](https://github.com/apache/jmeter/pull/214)Add spanish translation for delayed starting of threads. Contributed by Asier Lostalé (asier.lostale at openbravo.com). - [Bug 60348](https://bz.apache.org/bugzilla/show_bug.cgi?id=60348)Change chinese translation for `Save as`. Contributed by XMeter (support at xmeter.net). #### Report / Dashboard - [Bug 59954](https://bz.apache.org/bugzilla/show_bug.cgi?id=59954)Web Report/Dashboard : Add average metric - [Bug 59956](https://bz.apache.org/bugzilla/show_bug.cgi?id=59956)Web Report / Dashboard : Add ability to generate a graph for a range of data - [Bug 60065](https://bz.apache.org/bugzilla/show_bug.cgi?id=60065)Report / Dashboard : Improve Dashboard Error Summary by adding response message to "Type of error". Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60079](https://bz.apache.org/bugzilla/show_bug.cgi?id=60079)Report / Dashboard : Add a new "Response Time Overview" graph - [Bug 60080](https://bz.apache.org/bugzilla/show_bug.cgi?id=60080)Report / Dashboard : Add a new "Connect Time Over Time " graph. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60091](https://bz.apache.org/bugzilla/show_bug.cgi?id=60091)Report / Dashboard : Have a new report containing min/max and percentiles graphs. - [Bug 60108](https://bz.apache.org/bugzilla/show_bug.cgi?id=60108)Report / Dashboard : In Requests Summary rounding is too aggressive - [Bug 60098](https://bz.apache.org/bugzilla/show_bug.cgi?id=60098)Report / Dashboard : Reduce default value for "`jmeter.reportgenerator.statistic_window`" to reduce memory impact - [Bug 60115](https://bz.apache.org/bugzilla/show_bug.cgi?id=60115)Add date format property for start/end date filter into Report generator - [Bug 60171](https://bz.apache.org/bugzilla/show_bug.cgi?id=60171)Report / Dashboard : Active Threads Over Time should stack lines to give the total amount of threads running - [Bug 60250](https://bz.apache.org/bugzilla/show_bug.cgi?id=60250)Report / Dashboard : Need to Add Sent KB/s in Statistics Report of HTML Dashboard - [Bug 60287](https://bz.apache.org/bugzilla/show_bug.cgi?id=60287)Report / Dashboard : Have a new Top5 Errors by sampler table in Dashboard. Implemented by Philippe Mouawad (p.mouawad at ubik-ingenierie.com) and contributed by Ubik Load Pack (support at ubikloadpack.com) #### General - [Bug 59803](https://bz.apache.org/bugzilla/show_bug.cgi?id=59803)Use `isValid()` method from JDBC driver, if no `validationQuery` is given in JDBC Connection Configuration. - [Bug 57493](https://bz.apache.org/bugzilla/show_bug.cgi?id=57493)Create a documentation page for properties - [Bug 59924](https://bz.apache.org/bugzilla/show_bug.cgi?id=59924)The log level of _XXX_ package is set to `DEBUG` if `log_level._XXXX_` property value contains spaces, same for `__log` function - [Bug 59777](https://bz.apache.org/bugzilla/show_bug.cgi?id=59777)Extract SLF4J binding into its own jar and make it a JMeter lib. :::note If you get a warning about multiple SLF4J bindings on startup. Remove either the Apache JMeter provided binding `lib/ApacheJMeter_slf4j_logkit.jar`, or all of the other reported bindings. For more information you can have a look at [SLF4Js own info page.](http://www.slf4j.org/codes.html#multiple_bindings) ::: - [Bug 60085](https://bz.apache.org/bugzilla/show_bug.cgi?id=60085)Remove cache for prepared statements, as it didn't work with the current JDBC pool implementation and current JDBC drivers should support caching of prepared statements themselves. - [Bug 60137](https://bz.apache.org/bugzilla/show_bug.cgi?id=60137)In Distributed testing when using StrippedXXXX modes strip response also on error - [Bug 60106](https://bz.apache.org/bugzilla/show_bug.cgi?id=60106)Settings defaults : Switch "`jmeter.save.saveservice.connect_time`" to true (after 3.0) - [PR#229](https://github.com/apache/jmeter/pull/229) tiny memory allocation improvements. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 59945](https://bz.apache.org/bugzilla/show_bug.cgi?id=59945)For all JSR223 elements, if script language has not been chosen on the UI, the script will be interpreted as a groovy script. - [Bug 60266](https://bz.apache.org/bugzilla/show_bug.cgi?id=60266)Usability/ UX : It should not be possible to close/exit/Revert/Load/Load a recent project or create from template a JMeter plan or open a new one if a test is running - [Bug 57305](https://bz.apache.org/bugzilla/show_bug.cgi?id=57305)Remove dependency of `ProxyControl` on `GuiPackage`. Based on patches by jarek102 (jarek102 at gmail.com) and Wyatt Epp (wyatt.epp at gmail.com) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 58888](https://bz.apache.org/bugzilla/show_bug.cgi?id=58888)HTTP(S) Test Script Recorder (ProxyControl) does not add TestElement's returned by `SamplerCreator#createChildren()` - [Bug 59902](https://bz.apache.org/bugzilla/show_bug.cgi?id=59902)Https handshake failure when setting `httpclient.socket.https.cps` property - [Bug 60084](https://bz.apache.org/bugzilla/show_bug.cgi?id=60084)JMeter 3.0 embedded resource URL is silently encoded - [Bug 60376](https://bz.apache.org/bugzilla/show_bug.cgi?id=60376)Http Test Script Recorder : If deflate is used by server then recording may break application #### Other Samplers - [Bug 59113](https://bz.apache.org/bugzilla/show_bug.cgi?id=59113)JDBC Connection Configuration : Transaction Isolation level not correctly set if constant used instead of numerical #### Controllers - [Bug 60361](https://bz.apache.org/bugzilla/show_bug.cgi?id=60361)ModuleController : If a Test plan contains a Module Controller which references an unexistant Controller, JMeter in GUI mode will not stop #### Listeners - [Bug 59712](https://bz.apache.org/bugzilla/show_bug.cgi?id=59712)Display original query in RequestView when decoding fails. Based on a patch by Teemu Vesala (teemu.vesala at qentinel.com) - [Bug 60278](https://bz.apache.org/bugzilla/show_bug.cgi?id=60278)Since 2.13 (and [Bug 57514](https://bz.apache.org/bugzilla/show_bug.cgi?id=57514)), Aggregate Graph, Summary Report and Aggregate Report lost precision in the Error, Rate and Bandwidth values saved in the saved file csv - [Bug 60360](https://bz.apache.org/bugzilla/show_bug.cgi?id=60360)View Result Tree : Request Tab does not show body of a DELETE request #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 59964](https://bz.apache.org/bugzilla/show_bug.cgi?id=59964)JSR223 Test Element : Cache compiled script if available is not correctly reset. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 59609](https://bz.apache.org/bugzilla/show_bug.cgi?id=59609)Format extracted JSON Objects in JSON Post Processor correctly as JSON. - [Bug 60332](https://bz.apache.org/bugzilla/show_bug.cgi?id=60332)View Results Tree : With Windows LAF, JSON Extractor does not show JSON Path Expression and Result panel #### Functions #### I18N #### General - [Bug 59400](https://bz.apache.org/bugzilla/show_bug.cgi?id=59400)Get rid of UnmarshalException on stopping when `-X` option is used. - [Bug 59607](https://bz.apache.org/bugzilla/show_bug.cgi?id=59607)JMeter crashes when reading large test plan (greater than 2GB). Based on fix by Felix Draxler (felix.draxler at sap.com) - [Bug 59621](https://bz.apache.org/bugzilla/show_bug.cgi?id=59621)Error count in report dashboard is one off. - [Bug 59657](https://bz.apache.org/bugzilla/show_bug.cgi?id=59657)Only set font in JSyntaxTextArea, when property `jsyntaxtextarea.font.family` is set. - [Bug 59720](https://bz.apache.org/bugzilla/show_bug.cgi?id=59720)Batch test file comparisons fail on Windows as XML files are generated as EOL=LF - Code cleanups. Patches by Graham Russell (graham at ham1.co.uk) - [Bug 59722](https://bz.apache.org/bugzilla/show_bug.cgi?id=59722)Use StandardCharsets to reduce the possibility of misspelling Charset names. - [Bug 59723](https://bz.apache.org/bugzilla/show_bug.cgi?id=59723)Use `jmeter.properties` for testing whenever possible - [Bug 59726](https://bz.apache.org/bugzilla/show_bug.cgi?id=59726)Unit test to check that CSV header text and sample format don't change unexpectedly - [Bug 59889](https://bz.apache.org/bugzilla/show_bug.cgi?id=59889)Change encoding to UTF-8 in reports for dashboard. - [Bug 60053](https://bz.apache.org/bugzilla/show_bug.cgi?id=60053)In Non GUI mode, a Stacktrace is shown at end of test while report is being generated - [Bug 60049](https://bz.apache.org/bugzilla/show_bug.cgi?id=60049)When using Timers with high delays or Constant Throughput Timer with low throughput, Scheduler may take a lot of time to exit, same for Shutdown test - [Bug 60089](https://bz.apache.org/bugzilla/show_bug.cgi?id=60089)Report / Dashboard : Bytes throughput Over Time has reversed Sent and Received bytes. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 60090](https://bz.apache.org/bugzilla/show_bug.cgi?id=60090)Report / Dashboard : Empty Transaction Controller should not count in metrics - [Bug 60103](https://bz.apache.org/bugzilla/show_bug.cgi?id=60103)Report / Dashboard : Requests summary includes Transaction Controller leading to wrong percentage - [Bug 60105](https://bz.apache.org/bugzilla/show_bug.cgi?id=60105)Report / Dashboard : Report requires Transaction Controller "`generate parent sample`" option to be checked, fix related issues - [Bug 60107](https://bz.apache.org/bugzilla/show_bug.cgi?id=60107)Report / Dashboard : In StatisticSummary, TransactionController SampleResult makes Total line wrong - [Bug 60110](https://bz.apache.org/bugzilla/show_bug.cgi?id=60110)Report / Dashboard : In Response Time Percentiles, slider is useless - [Bug 60135](https://bz.apache.org/bugzilla/show_bug.cgi?id=60135)Report / Dashboard : Active Threads Over Time should be in OverTime section - [Bug 60125](https://bz.apache.org/bugzilla/show_bug.cgi?id=60125)Report / Dashboard : Dashboard cannot be generated if the default delimiter is `\t`. Based on a report from Tamas Szabadi (tamas.szabadi at rightside.co) - [Bug 59439](https://bz.apache.org/bugzilla/show_bug.cgi?id=59439)Report / Dashboard : AbstractOverTimeGraphConsumer.createGroupInfos() should be abstract - [Bug 59918](https://bz.apache.org/bugzilla/show_bug.cgi?id=59918)Ant generated HTML report is broken (extras folder) - [Bug 60295](https://bz.apache.org/bugzilla/show_bug.cgi?id=60295)JSON Extractor doesn't index array elements when only one element is found. Based on a patch by Roberto Braga (roberto.braga at sociale.it) - [Bug 60299](https://bz.apache.org/bugzilla/show_bug.cgi?id=60299)Thread Group with Scheduler : Weird behaviour when End-Time is in the past ## Non-functional changes - Updated to jsoup-1.10.1 (from 1.8.3) - Updated to ph-css 4.1.6 (from 4.1.4) - Updated to tika-core and tika-parsers 1.14 (from 1.12) - Updated to commons-io 2.5 (from 2.4) - Updated to commons-lang3 3.5 (from 3.4) - Updated to commons-net 3.5 (from 3.4) - Updated to groovy 2.4.7 (from 2.4.6) - Updated to httpcore 4.4.5 (from 4.4.4) - Updated to slf4j-api 1.7.21 (from 1.7.13) - Updated to rsyntaxtextarea-2.6.0 (from 2.5.8) - Updated to xstream 1.4.9 (from 1.4.8) - Updated to jodd 3.7.1 (from 3.6.7.jar) - Updated to xmlgraphics-commons 2.1 (from 2.0.1) - [PR#215](https://github.com/apache/jmeter/pull/215)Reduce duplicated code by using the newly added method `GuiUtils#cancelEditing`. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [PR#218](https://github.com/apache/jmeter/pull/218)Misc cleanup. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [PR#216](https://github.com/apache/jmeter/pull/216)Re-use pattern when possible. Contributed by Benoit Wiart (b.wiart at ubik-ingenierie.com) - [Bug 60364](https://bz.apache.org/bugzilla/show_bug.cgi?id=60364)Document Test Coverage. Contributed by Thomas Schapitz (ts-nospam12 at online.de) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Felix Draxler (felix.draxler at sap.com) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - Graham Russell (graham at ham1.co.uk) - Teemu Vesala (teemu.vesala at qentinel.com) - Asier Lostalé (asier.lostale at openbravo.com) - Thomas Peyrard (thomas.peyrard at murex.com) - Benoit Wiart (b.wiart at ubik-ingenierie.com) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Ubik Load Pack](http://ubikloadpack.com) - Tamas Szabadi (tamas.szabadi at rightside.co) - Roberto Braga (roberto.braga at soziale.it) - jarek102 at gmail.com - Wyatt Epp (wyatt.epp at gmail.com) - Thomas Schapitz (ts-nospam12 at online.de) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: Apologies if we have omitted anyone else. ## Improve Report/Dashboard The Dashboard has been improved with 3 new graphs and 1 summary table: - Connect Time over Time graph : ![dashboard/report_connect_time_over_time.png](/images/screenshots/dashboard/report_connect_time_over_time.png) - Response Time Percentiles Over Time (successful responses) graph : ![dashboard/response_time_percentiles_over_time.png](/images/screenshots/dashboard/response_time_percentiles_over_time.png) - Response Time Overview graph : ![dashboard/response_time_overview.png](/images/screenshots/dashboard/response_time_overview.png) - Top 5 errors by Sampler table : ![dashboard/top_5_errors_by_sampler.png](/images/screenshots/dashboard/top_5_errors_by_sampler.png) - More details on errors in Errors table - Average response time added to Statistics table : ![dashboard/report_statistics.png](/images/screenshots/dashboard/report_statistics.png) - Active Threads table now stacks threads : ![dashboard/report_active_threads_over_time.png](/images/screenshots/dashboard/report_active_threads_over_time.png) ## New Metrics A new `sent_bytes` metric has been introduced which reports the bytes sent to server. Another metric `connect_time` has been enabled by default in this version ## Handling Big responses JMeter is now able to handle in terms of metrics responses bigger than 2GB, limit has been increased to 9223372 TB. To handle such big responses, it can also now truncate part of the response to avoid overflooding memory. See `httpsampler.max_bytes_to_store_per_request` property. ## New `__groovy` function Introduce a new function `__groovy` that enables Groovy functions. This can be handy, as JavaScript can be quite slow (same for BeanShell), when used in highly concurrent test plans. ## Use Groovy as default for JSR-223 elements Groovy is now set as the default language for JSR-223 elements. If you want to use another of the supported language, you have to make an explicit choice. :::note By default `Cache compiled script if available` is not checked by default although we advise you to check it and ensure you don't use `\${varName}` syntax to access JMeter variables but `vars.get("varName")` instead. ::: ## Formatted HTML source view in Results Tree View The HTML source code in the Results Tree View can now be viewed formatted. This is extremely useful, if the code of the webpage has been stripped of all superfluous whitespace. ![New formatted HTML source view](/images/screenshots/html-formatted-tree-view.png) _New formatted HTML source view_ ## Ability to update all timers in Test plan with a new property A new property `timer.factor=1.0f` has been introduced which allows you to multiply pause times computed by Gaussian, Uniform and Poisson Timers by it. This allows you to update Think Times from one place and let you gain productivity. ### Core improvements - Various GUI and UX fixes - Memory usage improvements - JDBC Request is now able to return Blob/Clob and computes latency and connect time - CSS Parsing introduced in 3.0 has been optimized by introduction of a parsing cache - HTTP Request is now able to handle body in GET request, this is useful for Elastic Search requests for example. ### Documentation improvements - Documentation review and improvements for easier startup - New [properties reference](/usermanual/properties-reference/) documentation section ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 3.0 Release Notes URL: https://docs.jmeter.ai/releases/3-0/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 3.0, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 30 | | Improvements | 108 | | Bug fixes | 59 | | Non-functional changes | 39 | ## New and Noteworthy ## Incompatible changes - Since version 3.0, Groovy-2.4.6 is bundled with JMeter (`lib` folder), ensure you remove old version or referenced versions through properties `search_paths` or `user.classpath` - Since version 3.0, `jmeter.save.saveservice.assertion_results_failure_message` property value is true, meaning CSV file for results will contain an additional column containing assertion result response message, see [Bug 58978](https://bz.apache.org/bugzilla/show_bug.cgi?id=58978) - Since version 3.0, `jmeter.save.saveservice.print_field_names` property value is true, meaning CSV file for results will contain field names as first line in CSV, see [Bug 58991](https://bz.apache.org/bugzilla/show_bug.cgi?id=58991) - Since version 3.0, `jmeter.save.saveservice.idle_time` property value is true, meaning CSV/XML result files will contain an additional column containing idle time between samplers, see [Bug 57182](https://bz.apache.org/bugzilla/show_bug.cgi?id=57182) - In RandomTimer class, protected instance `timer` field has been replaced by `getTimer()` protected method, this is related to [Bug 58100](https://bz.apache.org/bugzilla/show_bug.cgi?id=58100). This may impact 3rd party plugins. - Since version 3.0, you can use Nashorn Engine (default javascript engine is Rhino) under Java8 for Elements that use Javascript Engine (`__javaScript`, `IfController`). If you want to use it, use property `javascript.use_rhino=false`, see [Bug 58406](https://bz.apache.org/bugzilla/show_bug.cgi?id=58406). :::note Note: in a future version, we will switch to Nashorn by default. Users are encouraged to report any issue related to using Nashorn instead of Rhino. ::: - Since version 3.0, JMS Publisher will reload contents of file if Message source is "`From File`" and the "`Filename`" field changes (e.g. if it uses a variable that has changed) - `org.apache.jmeter.gui.util.ButtonPanel` has been removed, if you use it in your 3rd party plugin or custom development ensure you update your code. See [Bug 58687](https://bz.apache.org/bugzilla/show_bug.cgi?id=58687) - Property `jmeterthread.startearlier` has been removed. See [Bug 58726](https://bz.apache.org/bugzilla/show_bug.cgi?id=58726) - Property `jmeterengine.startlistenerslater` has been removed. See [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728) - Property `jmeterthread.reversePostProcessors` has been removed. See [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728) - Property `jmeter.toolbar.display` has been removed, the toolbar is now always displayed. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Property `jmeter.errorscounter.display` has been removed, the errors/warnings counter is now always displayed. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Property `xml.parser` has been removed, it is not used anymore as `org.apache.jmeter.util.JMeterUtils#getXMLParser` has been deprecated and is not used either. See [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236) - Summariser listener now shows the duration in the format `HH:mm:ss` (Hour:Minute:Second), it previously showed the duration in seconds. See [Bug 58776](https://bz.apache.org/bugzilla/show_bug.cgi?id=58776) - `org.apache.jmeter.protocol.http.visualizers.RequestViewHTTP.getQueryMap` signature has changed, if you use it ensure you update your code. See [Bug 58845](https://bz.apache.org/bugzilla/show_bug.cgi?id=58845) - JMS Subscriber will consider a sample to be an error if the number of received messages is not equal to expected number of messages. It previously considered a sample OK if at least 1 message was received. See [Bug 58980](https://bz.apache.org/bugzilla/show_bug.cgi?id=58980) - Since version 3.0, HTTP(S) Test Script recorder defaults to using port `8888` (as configured when using Recording Template). See [Bug 59006](https://bz.apache.org/bugzilla/show_bug.cgi?id=59006) - Since version 3.0, the parser for embedded resources (replaced since 2.10 by Lagarto based implementation) which relied on the htmlparser library (HtmlParserHTMLParser) has been dropped along with its dependencies. - Since version 3.0, support for reading old Avalon format JTL (result) files has been removed, see [Bug 59064](https://bz.apache.org/bugzilla/show_bug.cgi?id=59064) - Since version 3.0, the default property value for `http.java.sampler.retries` has been changed to `0` (no retry by default) to align it with the behaviour of HttpClient4. :::note Note also that its meaning has changed: before 3.0, `http.java.sampler.retries=1` meant `No Retry` (i.e. total tries = 1), since 3.0 `http.java.sampler.retries=1` means `1` retry. (Note: this only applies to the Java HTTP Sampler) ::: See [Bug 59103](https://bz.apache.org/bugzilla/show_bug.cgi?id=59103) - Since 3.0, the following deprecated classes have been dropped - org.apache.jmeter.protocol.http.modifier.UserParameterXMLContentHandler - org.apache.jmeter.protocol.http.modifier.UserParameterXMLErrorHandler - org.apache.jmeter.protocol.http.modifier.UserParameterXMLParser - `httpsampler.await_termination_timeout` has been replaced by `httpsampler.parallel_download_thread_keepalive_inseconds` which is now the keep alive time for the parallel download threads (in seconds). - JDBC Request has been updated to use commons-dbcp2, since then the behaviour is slightly different, ensure you have a correct "Validation Query" for your database. See [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786) - The following jars have been removed: - excalibur-datasource-2.1.jar (see [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)) - excalibur-instrument-1.0.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-api-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-impl-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - excalibur-pool-instrumented-2.1.jar (see [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)) - htmllexer-2.1.jar (see [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)) - htmlparser-2.1.jar (see [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)) - soap-2.3.1.jar - jdom-1.1.3.jar (see [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)) - Maximum number of redirects allowed by JMeter is now 20, it was previously 5. This can be changed with the property `httpsampler.max_redirects`. See [Bug 59382](https://bz.apache.org/bugzilla/show_bug.cgi?id=59382) #### Deprecated and removed elements - MongoDB elements (MongoDB Source Config, MongoDB Script) have been deprecated and will be removed in the next version of JMeter. They do not appear anymore in the menu, if you need them modify `not_in_menu` property. The JMeter team advises not to use them anymore. See [Bug 58772](https://bz.apache.org/bugzilla/show_bug.cgi?id=58772) - WebService(SOAP) Request and HTML Parameter Mask which were deprecated in 2.13 version, have now been removed following our [deprecation strategy](/./usermanual/best-practices/#deprecation). Classes and properties which were only used by those elements have been dropped: - `org.apache.jmeter.protocol.http.util.DOMPool` - `org.apache.jmeter.protocol.http.util.WSDLException` - `org.apache.jmeter.protocol.http.util.WSDLHelper` - Property `soap.document_cache` - JAR soap-2.3.1 has been also removed - `__jexl` function (i.e. JEXL 1) has been deprecated and will be removed in next version. See [Bug 58903](https://bz.apache.org/bugzilla/show_bug.cgi?id=58903) - Spline Visualizer listener and Distribution Graph listener have been deprecated and will be removed in the next version of JMeter. They do not appear anymore in the menu, if you need them modify `not_in_menu` property. JMeter team advises not to use them anymore. See [Bug 58791](https://bz.apache.org/bugzilla/show_bug.cgi?id=58791) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 57696](https://bz.apache.org/bugzilla/show_bug.cgi?id=57696)HTTP Request : Improve responseMessage when resource download fails. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57995](https://bz.apache.org/bugzilla/show_bug.cgi?id=57995)Use FileServer for HTTP Request files. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 58843](https://bz.apache.org/bugzilla/show_bug.cgi?id=58843)Improve the usable space in the HTTP sampler GUI. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58852](https://bz.apache.org/bugzilla/show_bug.cgi?id=58852)Use less memory for `PUT` requests. The uploaded data will no longer be stored in the Sampler. This is the same behaviour as with `POST` requests. - [Bug 58860](https://bz.apache.org/bugzilla/show_bug.cgi?id=58860)HTTP Request : Add automatic variable generation in HTTP parameters table by right click. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58923](https://bz.apache.org/bugzilla/show_bug.cgi?id=58923)normalize URIs when downloading embedded resources. - [Bug 59005](https://bz.apache.org/bugzilla/show_bug.cgi?id=59005)HTTP Sampler : Added WebDAV verb (`SEARCH`). - [Bug 59006](https://bz.apache.org/bugzilla/show_bug.cgi?id=59006)Change Default proxy recording port to `8888` to align it with Recording Template. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58099](https://bz.apache.org/bugzilla/show_bug.cgi?id=58099)Performance : Lazily initialize HttpClient SSL Context to avoid its initialization even for HTTP only scenarios - [Bug 57577](https://bz.apache.org/bugzilla/show_bug.cgi?id=57577)HttpSampler : Retrieve All Embedded Resources, add property "`httpsampler.embedded_resources_use_md5`" to only compute md5 and not keep response data. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59023](https://bz.apache.org/bugzilla/show_bug.cgi?id=59023)HttpSampler UI : rework the embedded resources labels and change default number of parallel downloads to `6`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59028](https://bz.apache.org/bugzilla/show_bug.cgi?id=59028)Use `SystemDefaultDnsResolver` singleton. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59036](https://bz.apache.org/bugzilla/show_bug.cgi?id=59036)FormCharSetFinder : Use JSoup instead of deprecated HTMLParser - [Bug 59034](https://bz.apache.org/bugzilla/show_bug.cgi?id=59034)Parallel downloads connection management is not realistic. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) and Philippe Mouawad - [Bug 59060](https://bz.apache.org/bugzilla/show_bug.cgi?id=59060)HTTP Request GUI : Move File Upload to a new Tab to have more space for parameters and prevent incompatible configuration. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59103](https://bz.apache.org/bugzilla/show_bug.cgi?id=59103)HTTP Request Java Implementation: Change default "`http.java.sampler.retries`" to align it on HttpClient behaviour and make the name meaningful - [Bug 59083](https://bz.apache.org/bugzilla/show_bug.cgi?id=59083)HTTP Request : Make Method field editable so that additional methods (WebDAV) can be added easily - [Bug 59118](https://bz.apache.org/bugzilla/show_bug.cgi?id=59118)Add comment in recorded think time by proxy recorder. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59116](https://bz.apache.org/bugzilla/show_bug.cgi?id=59116)Add the possibility to setup a prefix to sampler name recorded by proxy. Partly based on a patch by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59129](https://bz.apache.org/bugzilla/show_bug.cgi?id=59129)HTTP Request : Simplify GUI with simple/advanced Tabs - [Bug 59033](https://bz.apache.org/bugzilla/show_bug.cgi?id=59033)Parallel Download : Rework Parser classes hierarchy to allow plug-in parsers for different mime types - [Bug 52073](https://bz.apache.org/bugzilla/show_bug.cgi?id=52073)Embedded Resources Parallel download : Improve performances by avoiding shutdown of ThreadPoolExecutor at each sample. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59190](https://bz.apache.org/bugzilla/show_bug.cgi?id=59190)HTTP(S) Test Script Recorder : Suggested excludes should ignore case. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59140](https://bz.apache.org/bugzilla/show_bug.cgi?id=59140)Parallel Download : Add CSS Parsing to extract links from CSS files - [Bug 59249](https://bz.apache.org/bugzilla/show_bug.cgi?id=59249)Http Request Defaults : Add "`Source address`" and "`Save responses as MD5`" - [Bug 59382](https://bz.apache.org/bugzilla/show_bug.cgi?id=59382)More realistic default value for `httpsampler.max_redirects` #### Other samplers - [Bug 57928](https://bz.apache.org/bugzilla/show_bug.cgi?id=57928)Add ability to define protocol (http/https) to AccessLogSampler GUI. Contributed by Jérémie Lesage (jeremie.lesage at jeci.fr) - [Bug 58300](https://bz.apache.org/bugzilla/show_bug.cgi?id=58300)Make existing Java Samplers implement Interruptible - [Bug 58160](https://bz.apache.org/bugzilla/show_bug.cgi?id=58160)JMS Publisher : reload file content if file name changes. Based partly on a patch contributed by Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 58786](https://bz.apache.org/bugzilla/show_bug.cgi?id=58786)JDBC Sampler : Replace Excalibur DataSource by more up to date library commons-dbcp2 - [Bug 59205](https://bz.apache.org/bugzilla/show_bug.cgi?id=59205)TCP Sampler: Set connect time in sampler when connection is established. - [Bug 59381](https://bz.apache.org/bugzilla/show_bug.cgi?id=59381)JMSPublisher : FileChooserDialog filter does not work for browser buttons. Based partly on a patch contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### Controllers - [Bug 58406](https://bz.apache.org/bugzilla/show_bug.cgi?id=58406)IfController : Allow use of Nashorn Engine if available for JavaScript evaluation - [Bug 58281](https://bz.apache.org/bugzilla/show_bug.cgi?id=58281)RandomOrderController : Improve randomization algorithm performance. Contributed by Graham Russell (jmeter at ham1.co.uk) - [Bug 58675](https://bz.apache.org/bugzilla/show_bug.cgi?id=58675)Module controller : error message can easily be missed. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58673](https://bz.apache.org/bugzilla/show_bug.cgi?id=58673)Module controller : when the target element is disabled the default jtree icons are displayed. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58674](https://bz.apache.org/bugzilla/show_bug.cgi?id=58674)Module controller : it should not be possible to select more than one node in the tree. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58680](https://bz.apache.org/bugzilla/show_bug.cgi?id=58680)Module Controller : ui enhancement. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58989](https://bz.apache.org/bugzilla/show_bug.cgi?id=58989)Record controller gui : add a button to clear all the recorded samples. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Listeners - [Bug 58041](https://bz.apache.org/bugzilla/show_bug.cgi?id=58041)Tree View Listener should show sample data type - [Bug 58122](https://bz.apache.org/bugzilla/show_bug.cgi?id=58122)GraphiteBackendListener : Add Server Hits metric. Partly based on a patch from Amol Moye (amol.moye at thomsonreuters.com) - [Bug 58681](https://bz.apache.org/bugzilla/show_bug.cgi?id=58681)GraphiteBackendListener : Don't send data if no sampling occurred - [Bug 58776](https://bz.apache.org/bugzilla/show_bug.cgi?id=58776)Summariser should display a more readable duration - [Bug 58791](https://bz.apache.org/bugzilla/show_bug.cgi?id=58791)Deprecate listeners: Distribution Graph (alpha) and Spline Visualizer - [Bug 58849](https://bz.apache.org/bugzilla/show_bug.cgi?id=58849)View Results Tree : Add a search panel to the request http view to be able to search in the parameters table. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58857](https://bz.apache.org/bugzilla/show_bug.cgi?id=58857)View Results Tree : the request view http does not allow to resize the parameters table first column. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58955](https://bz.apache.org/bugzilla/show_bug.cgi?id=58955)Request view http does not correctly display http parameters in multipart/form-data. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 55597](https://bz.apache.org/bugzilla/show_bug.cgi?id=55597)View Results Tree: Add a search feature to search in recorded samplers - [Bug 59102](https://bz.apache.org/bugzilla/show_bug.cgi?id=59102)View Results Tree: Better default value for "`view.results.tree.max_size`" - [Bug 59099](https://bz.apache.org/bugzilla/show_bug.cgi?id=59099)Backend listener : Add the possibility to consider samplersList as a Regular Expression. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59424](https://bz.apache.org/bugzilla/show_bug.cgi?id=59424)Visualizer : Add "Clear" in popup menu #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58303](https://bz.apache.org/bugzilla/show_bug.cgi?id=58303)Change usage of bouncycastle api in SMIMEAssertion to get rid of deprecation warnings. - [Bug 58515](https://bz.apache.org/bugzilla/show_bug.cgi?id=58515)New JSON related components : JSON-PATH Extractor and JSON-PATH Renderer in View Results Tree. Donated by Ubik Load Pack (support at ubikloadpack.com). - [Bug 58698](https://bz.apache.org/bugzilla/show_bug.cgi?id=58698)Correct parsing of auth-files in HTTP Authorization Manager. - [Bug 58756](https://bz.apache.org/bugzilla/show_bug.cgi?id=58756)CookieManager : Cookie Policy select box content must depend on Cookie implementation. - [Bug 56358](https://bz.apache.org/bugzilla/show_bug.cgi?id=56358)Cookie manager supports cross port cookies and RFC6265. Thanks to Oleg Kalnichevski (olegk at apache.org) - [Bug 58773](https://bz.apache.org/bugzilla/show_bug.cgi?id=58773)TestCacheManager : Add tests for CacheManager that use HttpClient 4 - [Bug 58742](https://bz.apache.org/bugzilla/show_bug.cgi?id=58742)CompareAssertion : Reset data in TableEditor when switching between different CompareAssertions in gui. Based on a patch by Vincent Herilier (vherilier at gmail.com) - [Bug 59108](https://bz.apache.org/bugzilla/show_bug.cgi?id=59108)TableEditor: Allow rows to be moved up and down. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 58848](https://bz.apache.org/bugzilla/show_bug.cgi?id=58848)Argument Panel : when adding an argument (add button or from clipboard) scroll the table to the new line. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58865](https://bz.apache.org/bugzilla/show_bug.cgi?id=58865)Allow empty default value in the Regular Expression Extractor. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59156](https://bz.apache.org/bugzilla/show_bug.cgi?id=59156)XMLAssertion : drop jdom dependency by using XMLReader - [Bug 59328](https://bz.apache.org/bugzilla/show_bug.cgi?id=59328)Better tooltip for Variable Names in CSVDataSet. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### Functions - [Bug 58477](https://bz.apache.org/bugzilla/show_bug.cgi?id=58477) __javaScript function : Allow use of Nashorn engine for Java8 and later versions - [Bug 58903](https://bz.apache.org/bugzilla/show_bug.cgi?id=58903)Provide __jexl3 function that uses commons-jexl3 and deprecated __jexl (1.1) function #### I18N #### General - [Bug 58736](https://bz.apache.org/bugzilla/show_bug.cgi?id=58736)Add Sample Timeout support - [Bug 57913](https://bz.apache.org/bugzilla/show_bug.cgi?id=57913)Automated backups of last saved JMX files. Contributed by Benoit Vatan (benoit.vatan at gmail.com) - [Bug 57988](https://bz.apache.org/bugzilla/show_bug.cgi?id=57988)Shortcuts (`Ctrl + 1` … `Ctrl + 9`) to quickly add elements into test plan. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. - [Bug 58100](https://bz.apache.org/bugzilla/show_bug.cgi?id=58100)Performance enhancements : Replace Random by ThreadLocalRandom. - [Bug 58677](https://bz.apache.org/bugzilla/show_bug.cgi?id=58677)`TestSaveService#testLoadAndSave` use the wrong set of files. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58689](https://bz.apache.org/bugzilla/show_bug.cgi?id=58689)Add shortcuts to expand / collapse a part of the tree. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58696](https://bz.apache.org/bugzilla/show_bug.cgi?id=58696)Create Ant task to setup Eclipse project - [Bug 58653](https://bz.apache.org/bugzilla/show_bug.cgi?id=58653)New JMeter Dashboard/Report with Dynamic Graphs, Tables to help analyzing load test results. Developed by Ubik-Ingenierie and contributed by Decathlon S.A. and Ubik-Ingenierie / UbikLoadPack - [Bug 58699](https://bz.apache.org/bugzilla/show_bug.cgi?id=58699)Workbench changes neither saved nor prompted for saving upon close. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58728](https://bz.apache.org/bugzilla/show_bug.cgi?id=58728)Drop old behavioural properties - [Bug 57319](https://bz.apache.org/bugzilla/show_bug.cgi?id=57319)Upgrade to HttpClient 4.5.2. With the big help from Oleg Kalnichevski (olegk at apache.org) and Gary Gregory (ggregory at apache.org). - [Bug 58772](https://bz.apache.org/bugzilla/show_bug.cgi?id=58772)Deprecate MongoDB related elements - [Bug 58782](https://bz.apache.org/bugzilla/show_bug.cgi?id=58782)ThreadGroup : Improve ergonomy - [Bug 58165](https://bz.apache.org/bugzilla/show_bug.cgi?id=58165)Show the time elapsed since the start of the load test in GUI mode. Partly based on a contribution from Maxime Chassagneux (maxime.chassagneux at gmail.com) - [Bug 58814](https://bz.apache.org/bugzilla/show_bug.cgi?id=58814)JVM no longer recognizes option `MaxLiveObjectEvacuationRatio`; remove from comments - [Bug 58810](https://bz.apache.org/bugzilla/show_bug.cgi?id=58810)Config Element Counter (and others): Check Boxes Toggle Area Too Big - [Bug 56554](https://bz.apache.org/bugzilla/show_bug.cgi?id=56554)JSR223 Test Element : Generate compilation cache key automatically. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58911](https://bz.apache.org/bugzilla/show_bug.cgi?id=58911)Header Manager : it should be possible to copy/paste between Header Managers. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58864](https://bz.apache.org/bugzilla/show_bug.cgi?id=58864)Arguments Panel : when moving parameter with up / down, ensure that the selection remains visible. Based on a contribution by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58968](https://bz.apache.org/bugzilla/show_bug.cgi?id=58968)Add a new template to allow to record script with think time included. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58978](https://bz.apache.org/bugzilla/show_bug.cgi?id=58978)Settings defaults : Switch "`jmeter.save.saveservice.assertion_results_failure_message`" to true (after 2.13) - [Bug 58991](https://bz.apache.org/bugzilla/show_bug.cgi?id=58991)Settings defaults : Switch "`jmeter.save.saveservice.print_field_names`" to true (after 2.13) - [Bug 57182](https://bz.apache.org/bugzilla/show_bug.cgi?id=57182)Settings defaults : Switch "`jmeter.save.saveservice.idle_time`" to true (after 2.13) - [Bug 58870](https://bz.apache.org/bugzilla/show_bug.cgi?id=58870)TableEditor: minimum size is too small. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 58933](https://bz.apache.org/bugzilla/show_bug.cgi?id=58933)JSyntaxTextArea : Ability to set font. Contributed by Denis Kirpichenkov (denis.kirpichenkov at gmail.com) - [Bug 58793](https://bz.apache.org/bugzilla/show_bug.cgi?id=58793)Create developers page explaining how to build and contribute - [Bug 59046](https://bz.apache.org/bugzilla/show_bug.cgi?id=59046)JMeter Gui Replace controller should keep the name and the selection. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59038](https://bz.apache.org/bugzilla/show_bug.cgi?id=59038)Deprecate HTTPClient 3.1 related elements - [Bug 59094](https://bz.apache.org/bugzilla/show_bug.cgi?id=59094)Drop support of old JMX file format - [Bug 59082](https://bz.apache.org/bugzilla/show_bug.cgi?id=59082)Remove the "`TestCompiler.useStaticSet`" parameter. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59093](https://bz.apache.org/bugzilla/show_bug.cgi?id=59093)Option parsing error message can be '_lost_' - [Bug 58715](https://bz.apache.org/bugzilla/show_bug.cgi?id=58715)Feature request: Bundle `groovy-all` with JMeter - [Bug 58426](https://bz.apache.org/bugzilla/show_bug.cgi?id=58426)Improve display of JMeter on high resolution devices (HiDPI) (part 1 of enhancement) - [Bug 59105](https://bz.apache.org/bugzilla/show_bug.cgi?id=59105)TableEditor : Add ability to paste rows from clipboard and delete multiple selection. Contributed by Vincent Herilier (vherilier at gmail.com) - [Bug 59197](https://bz.apache.org/bugzilla/show_bug.cgi?id=59197)Thread Group : it should be possible to only run a single threadgroup or a selection of threadgroups with a popup menu. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59207](https://bz.apache.org/bugzilla/show_bug.cgi?id=59207)Change the font color of `errorsOrFatalsLabel` to red when an error occurs. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 58941](https://bz.apache.org/bugzilla/show_bug.cgi?id=58941)Create a new Starter that runs thread groups in validation mode (`1` thread only, `1` iteration, no pause all customizable) - [Bug 59236](https://bz.apache.org/bugzilla/show_bug.cgi?id=59236)JMeter Properties : Make some cleanup - [Bug 59240](https://bz.apache.org/bugzilla/show_bug.cgi?id=59240)Introduce a slf4j adapter for Logkit (this allows using slf4j within plugins and core code) - [Bug 59153](https://bz.apache.org/bugzilla/show_bug.cgi?id=59153)Stop test if CSVDataSet is accessing non-existing file. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59320](https://bz.apache.org/bugzilla/show_bug.cgi?id=59320)Better tooltip in GUI with GenericTestBeanCustomizer (CSV Data Set Config, JDBC Connection Configuration, Keystore Configuration, …) . Based on a patch by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 59171](https://bz.apache.org/bugzilla/show_bug.cgi?id=59171)Sample Result SaveConfig Dialog is generated in random order - [Bug 59425](https://bz.apache.org/bugzilla/show_bug.cgi?id=59425)Display error about missing help page inside the help pane ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 57806](https://bz.apache.org/bugzilla/show_bug.cgi?id=57806)"`audio/x-mpegurl`" mime type is erroneously considered as binary by ViewResultsTree. Contributed by Ubik Load Pack (support at ubikloadpack.com). - [Bug 57858](https://bz.apache.org/bugzilla/show_bug.cgi?id=57858)Don't call `sampleEnd` twice in HTTPHC4Impl when a `RuntimeException` or an `IOException` occurs in the sample method. - [Bug 57921](https://bz.apache.org/bugzilla/show_bug.cgi?id=57921)HTTP/1.1 without keep-alive "`Connection`" response header no longer uses infinite keep-alive. - [Bug 57956](https://bz.apache.org/bugzilla/show_bug.cgi?id=57956)The `hc.parameters` reference in `jmeter.properties` doesn't work when JMeter is not started in `bin`. - [Bug 58137](https://bz.apache.org/bugzilla/show_bug.cgi?id=58137)JMeter fails to download embedded URLs that contain illegal characters in URL (it does not escape them). - [Bug 58201](https://bz.apache.org/bugzilla/show_bug.cgi?id=58201)Make usage of port in the host header more consistent across the different http samplers. - [Bug 58453](https://bz.apache.org/bugzilla/show_bug.cgi?id=58453)HTTP Test Script Recorder : `NullPointerException` when disabling Capture HTTP Headers - [Bug 57804](https://bz.apache.org/bugzilla/show_bug.cgi?id=57804)HTTP Request doesn't reuse cached SSL context when using Client Certificates in HTTPS (only fixed for HttpClient4 implementation) - [Bug 58800](https://bz.apache.org/bugzilla/show_bug.cgi?id=58800)`proxy.pause` default value: fix documentation - [Bug 58844](https://bz.apache.org/bugzilla/show_bug.cgi?id=58844)Buttons enable / disable is broken in the arguments panel. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58861](https://bz.apache.org/bugzilla/show_bug.cgi?id=58861)When clicking on up, down or detail while in a cell of the argument panel, newly added content is lost. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 57935](https://bz.apache.org/bugzilla/show_bug.cgi?id=57935)SSL SNI extension not supported by HttpClient 4.2.6 - [Bug 59044](https://bz.apache.org/bugzilla/show_bug.cgi?id=59044)Http Sampler : It should not be possible to select the multipart encoding if the method is not `POST`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59008](https://bz.apache.org/bugzilla/show_bug.cgi?id=59008)Http Sampler: Infinite recursion SampleResult on frame depth limit reached - [Bug 58881](https://bz.apache.org/bugzilla/show_bug.cgi?id=58881)HTTP Request : HTTPHC4Impl shows exception when server uses "`deflate`" compression - [Bug 58583](https://bz.apache.org/bugzilla/show_bug.cgi?id=58583)HTTP client fails to close connection if server misbehaves by not sending "`connection: close`", violating HTTP RFC 2616 / RFC 7230 - [Bug 58950](https://bz.apache.org/bugzilla/show_bug.cgi?id=58950)`NoHttpResponseException` when Pause between samplers exceeds keepalive sent by server - [Bug 59085](https://bz.apache.org/bugzilla/show_bug.cgi?id=59085)Http file panel : data lost on browse cancellation. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 56141](https://bz.apache.org/bugzilla/show_bug.cgi?id=56141)Application does not behave correctly when using HTTP Recorder. With the help of Dan (java.junkee at yahoo.com) - [Bug 59079](https://bz.apache.org/bugzilla/show_bug.cgi?id=59079)"`httpsampler.max_redirects`" property is not enforced when "`Redirect Automatically`" is used - [Bug 58811](https://bz.apache.org/bugzilla/show_bug.cgi?id=58811)When pasting arguments between http samplers the column "Encode" and "Include Equals" are lost. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Other Samplers - [Bug 58013](https://bz.apache.org/bugzilla/show_bug.cgi?id=58013)Enable all protocols that are enabled on the default SSLContext for usage with the SMTP Sampler. - [Bug 58209](https://bz.apache.org/bugzilla/show_bug.cgi?id=58209)JMeter hang when testing javasampler because `HashMap.put()` is called from multiple threads without sync. - [Bug 58301](https://bz.apache.org/bugzilla/show_bug.cgi?id=58301)Use typed methods such as `setInt`, `setDouble`, `setDate`, … for prepared statement #27 - [Bug 58851](https://bz.apache.org/bugzilla/show_bug.cgi?id=58851)Add a dependency on hamcrest-core to allow JUnit tests with annotations to work - [Bug 58947](https://bz.apache.org/bugzilla/show_bug.cgi?id=58947)Connect metric is wrong when `ConnectException` occurs - [Bug 58980](https://bz.apache.org/bugzilla/show_bug.cgi?id=58980)JMS Subscriber will return successful as long as 1 message is received. Contributed by Harrison Termotto (harrison dot termotto at stonybrook.edu) - [Bug 59075](https://bz.apache.org/bugzilla/show_bug.cgi?id=59075)JMS Publisher: `NumberFormatException` is thrown if priority or expiration field is empty - [Bug 59345](https://bz.apache.org/bugzilla/show_bug.cgi?id=59345)SMTPSampler connection leak. Based on a patch by Luca Maragnani (luca dot maragnani at gmail dot com) #### Controllers - [Bug 58600](https://bz.apache.org/bugzilla/show_bug.cgi?id=58600)Display correct filenames, when they are searched by IncludeController - [Bug 58678](https://bz.apache.org/bugzilla/show_bug.cgi?id=58678)Module Controller : limit target element selection. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58714](https://bz.apache.org/bugzilla/show_bug.cgi?id=58714)Module controller : it should not be possible to add a timer as child. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59067](https://bz.apache.org/bugzilla/show_bug.cgi?id=59067)JMeter fails to iterate over Controllers that are children of a TransactionController having "`Generate parent sample`" checked after an assertion error occurs on a Thread Group with "`Start Next Thread Loop`". Contributed by Benoit Wiart(benoit dot wiart at gmail.com) - [Bug 59076](https://bz.apache.org/bugzilla/show_bug.cgi?id=59076)Test should fail if a module controller cannot find its replacement subtree #### Listeners - [Bug 58033](https://bz.apache.org/bugzilla/show_bug.cgi?id=58033)SampleResultConverter should note that it cannot record non-TEXT data - [Bug 58845](https://bz.apache.org/bugzilla/show_bug.cgi?id=58845)Request http view doesn't display all the parameters. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58413](https://bz.apache.org/bugzilla/show_bug.cgi?id=58413)ViewResultsTree : Request HTTP Renderer does not show correctly parameters that contain ampersand (&). Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59172](https://bz.apache.org/bugzilla/show_bug.cgi?id=59172)SampleResult SaveConfig does not allow some fields to be disabled - [Bug 58329](https://bz.apache.org/bugzilla/show_bug.cgi?id=58329)Response Time Graph and Aggregate Graph : Save graph to file does not take into account the settings changed since last click on Graph. Contributed by David Coppens (d.l.coppens at gmail.com) #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 58079](https://bz.apache.org/bugzilla/show_bug.cgi?id=58079)Do not cache HTTP samples that have a `Vary` header when using a HTTP CacheManager. - [Bug 58912](https://bz.apache.org/bugzilla/show_bug.cgi?id=58912)Response assertion gui : Deleting more than 1 selected row deletes only one row. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) #### Functions - [Bug 57825](https://bz.apache.org/bugzilla/show_bug.cgi?id=57825)__Random function fails if `min` value is equal to `max` value (regression related to [Bug 54453](https://bz.apache.org/bugzilla/show_bug.cgi?id=54453)) #### I18N #### General - [Bug 54826](https://bz.apache.org/bugzilla/show_bug.cgi?id=54826)Don't fail on long strings in JSON responses when displaying them as JSON in View Results Tree. - [Bug 57734](https://bz.apache.org/bugzilla/show_bug.cgi?id=57734)Maven transient dependencies are incorrect for 2.13 (Fixed group ids for Commons Pool and Math) - [Bug 57731](https://bz.apache.org/bugzilla/show_bug.cgi?id=57731)`TESTSTART.MS` has always the value of the first Test started in Server mode in NON GUI Distributed testing - [Bug 58016](https://bz.apache.org/bugzilla/show_bug.cgi?id=58016) Error type casting using external SSL Provider. Contributed by Kirill Yankov (myworkpostbox at gmail.com) - [Bug 58293](https://bz.apache.org/bugzilla/show_bug.cgi?id=58293)SOAP/XML-RPC Sampler file browser generates NullPointerException - [Bug 58685](https://bz.apache.org/bugzilla/show_bug.cgi?id=58685)JDatefield : Make the modification of the date with up/down arrow work. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58693](https://bz.apache.org/bugzilla/show_bug.cgi?id=58693)Fix "Cannot nest output folder 'jmeter/build/components' inside output folder 'jmeter/build'" when setting up eclipse - [Bug 58781](https://bz.apache.org/bugzilla/show_bug.cgi?id=58781)Command line option "`-?`" shows Unknown option - [Bug 57821](https://bz.apache.org/bugzilla/show_bug.cgi?id=57821)Command-line option "`-X --remoteexit`" doesn't work since 2.13 (regression related to [Bug 57500](https://bz.apache.org/bugzilla/show_bug.cgi?id=57500)) - [Bug 58795](https://bz.apache.org/bugzilla/show_bug.cgi?id=58795)NPE may occur in `GuiPackage#getTestElementCheckSum` with some 3rd party plugins - [Bug 58913](https://bz.apache.org/bugzilla/show_bug.cgi?id=58913)When closing JMeter should not interpret cancel as "_destroy my test plan_". Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59096](https://bz.apache.org/bugzilla/show_bug.cgi?id=59096)Search Feature : Case insensitive search is not really case insensitive - [Bug 59193](https://bz.apache.org/bugzilla/show_bug.cgi?id=59193)`ant run_gui` fails with `ClassNotFoundException` or `IllegalAccessError` when accessing classes from dependencies not loaded through `Thread.currentThread().getContextClassLoader()` - [Bug 59225](https://bz.apache.org/bugzilla/show_bug.cgi?id=59225)Bad display of running indicator icon. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) - [Bug 56927](https://bz.apache.org/bugzilla/show_bug.cgi?id=56927)Disable language change during a test - [Bug 59391](https://bz.apache.org/bugzilla/show_bug.cgi?id=59391)In Distributed mode, the client exits abnormally at the end of test - [Bug 59397](https://bz.apache.org/bugzilla/show_bug.cgi?id=59397)`build.xml` does not make dist.executables executable on Unix systems ## Non-functional changes - Updated to httpclient, httpmime 4.5.2 (from 4.2.6) - Updated to tika-core and tika-parsers 1.12 (from 1.7) - Updated to commons-math3 3.6.1 (from 3.4.1) - Updated to commons-pool2 2.4.2 (from 2.3) - Updated to commons-lang 3.4 (from 3.3.2) - Updated to rhino-1.7.7.1 (from 1.7R5) - Updated to jodd-3.6.7.jar (from 3.6.4) - Updated to jsoup-1.8.3 (from 1.8.1) - Updated to rsyntaxtextarea-2.5.8 (from 2.5.6) - Updated to slf4j-1.7.12 (from 1.7.10) - Updated to xmlgraphics-commons-2.0.1 (from 1.5) - Updated to commons-collections-3.2.2 (from 3.2.1) - Updated to commons-net 3.4 (from 3.3) - Updated to slf4j 1.7.13 (from 1.7.12) - [Bug 57981](https://bz.apache.org/bugzilla/show_bug.cgi?id=57981)Require a minimum of Java 7. Partly contributed by Graham Russell (jmeter at ham1.co.uk) - [Bug 58684](https://bz.apache.org/bugzilla/show_bug.cgi?id=58684)JMeterColor does not need to extend `java.awt.Color`. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58687](https://bz.apache.org/bugzilla/show_bug.cgi?id=58687)ButtonPanel should die. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58705](https://bz.apache.org/bugzilla/show_bug.cgi?id=58705)Make `org.apache.jmeter.testelement.property.MultiProperty` iterable. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58729](https://bz.apache.org/bugzilla/show_bug.cgi?id=58729)Cleanup extras folder for maintainability - [Bug 57110](https://bz.apache.org/bugzilla/show_bug.cgi?id=57110)Fixed spelling+grammar, formatting, removed commented out code etc. Contributed by Graham Russell (jmeter at ham1.co.uk) - Correct instructions on running JMeter in `help.txt`. Contributed by Pascal Schumacher (pascalschumacher at gmx.net) - [Bug 58704](https://bz.apache.org/bugzilla/show_bug.cgi?id=58704)Non regression testing : Ant task batchtest fails if tests and run in a non `en_EN` locale and use a JMX file that uses a CSV DataSet - [Bug 58897](https://bz.apache.org/bugzilla/show_bug.cgi?id=58897)Improve JUnit Test code. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58949](https://bz.apache.org/bugzilla/show_bug.cgi?id=58949)Cleanup of LDAP code. Based on a patch by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58897](https://bz.apache.org/bugzilla/show_bug.cgi?id=58897)Improve JUnit Test code. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58967](https://bz.apache.org/bugzilla/show_bug.cgi?id=58967)Use JUnit categories to exclude tests that need a gui. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59003](https://bz.apache.org/bugzilla/show_bug.cgi?id=59003)`ClutilTestCase` `testSingleArg8` and `testSingleArg9` are identical - [Bug 59064](https://bz.apache.org/bugzilla/show_bug.cgi?id=59064)Remove OldSaveService which supported very old Avalon format JTL (result) files - [Bug 59165](https://bz.apache.org/bugzilla/show_bug.cgi?id=59165)RSyntaxTextArea not compatible with headless testing - [Bug 59021](https://bz.apache.org/bugzilla/show_bug.cgi?id=59021)Use `Double#compare` instead of reimplementing it in `NumberProperty#compareTo` - [Bug 59037](https://bz.apache.org/bugzilla/show_bug.cgi?id=59037)Drop HtmlParserHTMLParser and dependencies on htmlparser and htmllexer - [Bug 58465](https://bz.apache.org/bugzilla/show_bug.cgi?id=58465)JMS Read response field is badly named and documented - [Bug 58601](https://bz.apache.org/bugzilla/show_bug.cgi?id=58601)Change check for modification of `saveservice.properties` from `SVN Revision ID` to sha1 sum of the file itself. - [Bug 58726](https://bz.apache.org/bugzilla/show_bug.cgi?id=58726)Remove the `jmeterthread.startearlier` parameter. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 58784](https://bz.apache.org/bugzilla/show_bug.cgi?id=58784)Make `JMeterUtils#runSafe` sync/async awt invocation configurable and change the visualizers to use the async version. - [Bug 58790](https://bz.apache.org/bugzilla/show_bug.cgi?id=58790)Issue in CheckDirty and its relation to ActionRouter - [Bug 59095](https://bz.apache.org/bugzilla/show_bug.cgi?id=59095)Remove UserParameterXMLParser that was deprecated eight years ago. Contributed by Benoit Wiart (benoit dot wiart at gmail.com) - [Bug 59262](https://bz.apache.org/bugzilla/show_bug.cgi?id=59262)Add list of binary jars to LICENSE; use that for unit tests - [Bug 59353](https://bz.apache.org/bugzilla/show_bug.cgi?id=59353)Add "Deprecated and removed elements" in "Incompatible changes" part in changes.xml. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](http://ubikloadpack.com) - Benoit Vatan (benoit.vatan at gmail.com) - Jérémie Lesage (jeremie.lesage at jeci.fr) - Kirill Yankov (myworkpostbox at gmail.com) - Amol Moye (amol.moye at thomsonreuters.com) - Samoht-fr (https://github.com/Samoht-fr) - Graham Russell (jmeter at ham1.co.uk) - Maxime Chassagneux (maxime.chassagneux at gmail.com) - Benoit Wiart (benoit.wiart at gmail.com) - [Decathlon S.A.](http://www.decathlon.com) - [Ubik-Ingenierie S.A.S.](http://www.ubik-ingenierie.com) - Oleg Kalnichevski (olegk at apache.org) - Pascal Schumacher (pascalschumacher at gmx.net) - Vincent Herilier (vherilier at gmail.com) - Florent Sabbe (f dot sabbe at ubik-ingenierie.com) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - Harrison Termotto (harrison dot termotto at stonybrook.edu - Denis Kirpichenkov (denis.kirpichenkov at gmail.com) - Gary Gregory (ggregory at apache.org) - David Coppens (d.l.coppens at gmail.com) - Luca Maragnani (luca dot maragnani at gmail dot com) - Philip Helger (http://www.helger.com) for his [CSS Parser](https://github.com/phax) and for taking into account our bug reports very rapidly - Irek Pastusiak (the.automatic.tester at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - purnasatyap at gmail dot com for the tests and reports on nightly build - Sergey Batalin (sergey_batalin at mail dot ru) for the tests and reports on nightly build - Vincent Daburon (vdaburon at gmail dot com) for the tests and reports on nightly build Apologies if we have omitted anyone else. ## Test plan creation and debugging improvements ### New Search Feature in View Results Tree to allow searching for text / regexp in Request/Responses/Headers/Cookies/… This will ease correlation and Test plans creation ![changes/3.0/view_results_tree_search_feature.png](/images/screenshots/changes/3.0/view_results_tree_search_feature.png) ### New JSON Post Processor to better extract data from JSON content using user friendly JSON-PATH syntax JSON is now a first class citizen in JMeter with the introduction of a new [JSONPath](http://goessner.net/articles/JsonPath/) post processor. This post processor is very similar to Regular Expression Post Processor but is well suited for JSON code. It is based on [Jayway JSON Path library](https://github.com/jayway/JsonPath) ![changes/3.0/json_path_extractor.png](/images/screenshots/changes/3.0/json_path_extractor.png) ### New validation feature, in one click run a selection of Thread Groups with `1` user, no pause and `1` iteration ![changes/3.0/thread_group_validate.png](/images/screenshots/changes/3.0/thread_group_validate.png) ### JSR223 Test Elements do not require a Cache Compilation Key anymore Just check `Cache compiled script if available` checkbox and the elements (Pre-Processor, Post-Processor, Assertions, Listeners, …) will pre-compile the script and cache the compiled code if the underlying language supports it ![changes/3.0/jsr223_cache_compiled.png](/images/screenshots/changes/3.0/jsr223_cache_compiled.png) ### Nashorn can now be used as Javascript engine providing better performance and easier usage To enable [Nashorn](http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html), you need to set in `user.properties`: ``` javascript.use_rhino=false ``` Nashorn can be used with Java 8 in the following elements: - IfController - JSR223 Test elements with `javascript` language selected - `__javaScript` function ### Jexl3 has been integrated. It provides new scripting features and much better documentation [JEXL3](http://commons.apache.org/proper/commons-jexl/) can now be used thanks to a new function `__jexl3`. JEXL is a language very similar to JSTL. ### Simplified HTTP Request UI A new "`Advanced`" tab has been added to HTTP Request to simplify configuration. The file upload feature has been moved into a dedicated tab. This increases the space available for parameters in UI and simplifies the UX. ![changes/3.0/http_request_basic.png](/images/screenshots/changes/3.0/http_request_basic.png) ![changes/3.0/http_request_advanced.png](/images/screenshots/changes/3.0/http_request_advanced.png) ### HTTP Request Defaults improvements You can now configure Source Address (IP Spoofing like feature) and "`Save response as MD5 hash`" in Advanced Tab ![changes/3.0/http_request_defaults_advanced.png](/images/screenshots/changes/3.0/http_request_defaults_advanced.png) ## Reporting improvements ### New Reporting Feature generating dynamic Graphs in HTML pages (APDEX, Summary report and Graphs) A dynamic HTML report can now be generated either at the end of a load test or from a result file whenever you want. See [Generating dashboard](/./usermanual/generating-dashboard/) for more details. This report provides the following metrics: - [APDEX](https://en.wikipedia.org/wiki/Apdex) (Application Performance Index) table that computes the APDEX based on configurable values for tolerated and satisfied thresholds - A request summary graph showing the Success and failed transaction percentage: ![changes/3.0/report_apdex_and_summary.png](/images/screenshots/changes/3.0/report_apdex_and_summary.png) - A Statistics table providing in one table a summary of all metrics per transaction including 3 configurable percentiles : ![changes/3.0/report_statistics.png](/images/screenshots/changes/3.0/report_statistics.png) - An error table providing a summary of all errors and their proportion in the total requests : ![changes/3.0/report_errors.png](/images/screenshots/changes/3.0/report_errors.png) - Zoomable chart where you can check/uncheck every transaction to show/hide it for: - Response times Over Time : ![changes/3.0/report_response_times_over_time.png](/images/screenshots/changes/3.0/report_response_times_over_time.png) - Bytes throughput Over Time : ![changes/3.0/report_bytes_throughput_over_time.png](/images/screenshots/changes/3.0/report_bytes_throughput_over_time.png) - Latencies Over Time : ![changes/3.0/report_latencies_over_time.png](/images/screenshots/changes/3.0/report_latencies_over_time.png) - Hits per second : ![changes/3.0/report_hits_per_second.png](/images/screenshots/changes/3.0/report_hits_per_second.png) - Response codes per second : ![changes/3.0/report_codes_per_second.png](/images/screenshots/changes/3.0/report_codes_per_second.png) - Transactions per second : ![changes/3.0/report_transactions_per_second.png](/images/screenshots/changes/3.0/report_transactions_per_second.png) - Response Time vs Request per second : ![changes/3.0/report_response_time_vs_request.png](/images/screenshots/changes/3.0/report_response_time_vs_request.png) - Latency vs Request per second : ![changes/3.0/report_latencies_vs_request.png](/images/screenshots/changes/3.0/report_latencies_vs_request.png) - Response times percentiles : ![changes/3.0/report_response_time_percentiles.png](/images/screenshots/changes/3.0/report_response_time_percentiles.png) - Active Threads Over Time : ![changes/3.0/report_active_threads_over_time.png](/images/screenshots/changes/3.0/report_active_threads_over_time.png) - Times vs Threads : ![changes/3.0/report_time_vs_threads.png](/images/screenshots/changes/3.0/report_time_vs_threads.png) - Response Time Distribution : ![changes/3.0/report_response_time_distribution.png](/images/screenshots/changes/3.0/report_response_time_distribution.png) ### GraphiteBackendListener has a new Server Hits metric ### Summariser displays a more readable duration Now duration are display in the format `hours:minutes:seconds` ``` Generate Summary Results + 1 in 00:00:01 = 1.7/s Avg: 1 Min: 1 Max: 1 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0 Generate Summary Results + 138 in 00:00:09 = 16.2/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 9 Started: 9 Finished: 0 Generate Summary Results = 139 in 00:00:09 = 15.3/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 467 in 00:00:10 = 47.0/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 19 Started: 19 Finished: 0 Generate Summary Results = 606 in 00:00:19 = 31.9/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) ⋮ Generate Summary Results + 1662 in 00:00:10 = 166.1/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 28932 in 00:03:19 = 145.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 1664 in 00:00:10 = 166.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 30596 in 00:03:29 = 146.4/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Generate Summary Results + 1661 in 00:00:10 = 166.1/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0 Generate Summary Results = 32257 in 00:03:39 = 147.3/s Avg: 0 Min: 0 Max: 1 Err: 0 (0.00%) ``` ### BackendListener now allows you to define sampler list as a regular expression You can now use a regular expression to select the samplers you want to filter. Use parameter: `useRegexpForSamplersList=true` and put a regex in parameter `samplersList` ![changes/3.0/graphite_backend_listener_regex.png](/images/screenshots/changes/3.0/graphite_backend_listener_regex.png) ## Protocols and Load Testing improvements ### Migration to HttpClient 4.5.2 has been started. Although not completely finished, it improves many areas in JMeter Migration to HttpClient 4.5.2 improves the following fields of JMeter: - Support of recent RFC like [HTTP State Management Mechanism RFC-6265 for Cookies](https://tools.ietf.org/html/rfc6265), you should use now `HC4CookieHandler` in HTTP Cookie Manager component and select `standard` Cookie policy - [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) support for HttpClient4 implementation - Improved and better performing validation mechanism for Stale connections and Keep-Alive management, see properties `httpclient4.validate_after_inactivity` and `httpclient4.time_to_live` - Many bug fixes since previous version 4.2.6 used in JMeter 2.13, see [HttpClient 4.5.X release notes](http://www.apache.org/dist/httpcomponents/httpclient/RELEASE_NOTES-4.5.x.txt) - Better support of HTTP RFC 2616 / RFC 7230 and fixes to issues with `deflate` compression management ### Parallel Downloads is now realistic and scales much better: - Parsing of CSS imported files (through `@import`) or embedded resources (background, images, …) - Lazy initialization of SSL context: For 15 Threads 138% more sampling in 5 minutes for HTTP only tests. Gain increases as number of threads increases - Rework of Connection management for Parallel Download: This better simulates current browser behaviour and improves throughput. For 15 Threads 135% extra samples in 5 minutes. - Reuse of Threads used for Parallel downloads through a ThreadPool: This improves throughput and increases JMeter scalability for such tests - Total of 750% more throughput found on test with 15 threads, the more threads you have the more the gain - You can now compute and store just the MD5 of embedded resources instead of storing the entire response, this can be done by setting the property `httpsampler.embedded_resources_use_md5=true` ### Introduction of Sample Timeout feature This new [Sample Timeout](/user-manual/component-reference/#Sample_Timeout) Pre-Processor allows you to apply a Timeout on the elements that are in its scope. In the screenshot below the 10 second timeout applies to the `Debug Sampler` and `HTTP Request` elements. ![changes/3.0/sample_timeout.png](/images/screenshots/changes/3.0/sample_timeout.png) ### JDBC request now uses DBCP2 pool JDBC Request and JDBC Connection Configuration have been updated to replace old Excalibur Pool by Apache Commons DBCP2 pool. As a consequence properties have been migrated to equivalent when available and UI has been updated. Note that unlike Excalibur, Commons DBCP uses the validation query when creating the pool. So make sure the query is valid. The default query suits many databases, but not all - for example Oracle requires '`SELECT 1 FROM DUAL`' or similar. ![changes/3.0/jdbc_connection_configuration.png](/images/screenshots/changes/3.0/jdbc_connection_configuration.png) ## UX Improvements: ### Better display in HiDPI screens See [JMeter with a HiDPI screen on Linux or Windows](/usermanual/hints-and-tips/#hidpi) in Hints and Tips section in user manual ### New Icon look and Logo JMeter has a new Logo created by Felix Schumacher. Icons have also been refreshed to give a more modern style and make them more meaningful ### Lots of fixes of annoying little bugs Around 40 UI fixes have been made to either fix buggy, confusing behaviour or simplify usage by not allowing incompatible options to be selected ### Improved Thread Group UI and related actions (`Start`, `Start No Timers`, `Validate`) Creating and testing a Test Plan before Load Test has been much simplified by allowing you to only start a selection of Thread Group, start them without applying Timers (thus gaining time) or start them using a new Validation mode. This validation mode allows you to start a Thread Group (without modifying it) with 1 thread, 1 iteration and without applying timers. This validation mode can be customized. ![changes/3.0/thread_group_starters.png](/images/screenshots/changes/3.0/thread_group_starters.png) ### New shortcuts - Add most used elements (`Ctrl + 0` … `Ctrl + 9`), configurable through `gui.quick__XXX_` properties - Shortcuts to expand nodes ## Core improvements ### Configuration simplification with better defaults Default values for many properties have been modified to make JMeter configuration optimal Out of the box. Read "Incompatible changes" section for more details. ### Apache Groovy bundled with JMeter [Apache Groovy](http://www.groovy-lang.org/), the well-known JVM scripting language, is now bundled with Apache JMeter in lib folder. This allows you to use it immediately through JSR223 Elements by selecting the Groovy language. ### Superfluous and old properties removed Old properties that existed to maintain backward compatibility or to offer some superfluous customization have been removed. Read "Incompatible changes" section to see which properties have been removed. ### Code and documentation improvements - Migration to Java7 source code and use of its syntactic sugar - Major code cleanups - Full review of documentation and improvement both in content and presentation ### Improvements to unit tests - Migration of many tests to JUnit 4 - Better management of Headless tests - More Unit Tests ### Dependencies refresh Deprecated Libraries dropped or replaced by up to date ones: - Excalibur replaced by commons-dbcp - htmllexer, htmlparser removed - soap removed - jdom removed ### Slf4j can now be used within Plugins and core code You can now use [SLF4J](http://www.slf4j.org/) logging wrapper in your custom plugins or `org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient` subclasses. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.13 Release Notes URL: https://docs.jmeter.ai/releases/2-13/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.13, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 3 | | Improvements | 20 | | Bug fixes | 16 | | Non-functional changes | 18 | ## New and Noteworthy ## Incompatible changes - Since 2.13, Aggregate Graph, Summary Report and Aggregate Report now export percentages to %, before they exported the decimal value which differed from what was shown in GUI - Third party plugins may be impacted by fix of [Bug 57586](https://bz.apache.org/bugzilla/show_bug.cgi?id=57586), ensure that your subclass of HttpTestSampleGui implements ItemListener if you relied on parent class doing so. - Report package has been removed, `ApacheJMeter_report.jar` is not generated anymore as a consequence, see [Bug 57269](https://bz.apache.org/bugzilla/show_bug.cgi?id=57269) ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 25430](https://bz.apache.org/bugzilla/show_bug.cgi?id=25430)HTTP(S) Test Script Recorder : Make it populate HTTP Authorization Manager. Partly based on a patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [Bug 57381](https://bz.apache.org/bugzilla/show_bug.cgi?id=57381)HTTP(S) Test Script Recorder should display an error if Target Controller references a Recording Controller and no Recording Controller exists. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57488](https://bz.apache.org/bugzilla/show_bug.cgi?id=57488)Performance : Improve SSLContext reset for Two-way SSL Authentication - [Bug 57565](https://bz.apache.org/bugzilla/show_bug.cgi?id=57565)SamplerCreator : Add method to allow implementations to add children to created sampler - [Bug 57606](https://bz.apache.org/bugzilla/show_bug.cgi?id=57606)HTTPSamplerBase#errorResult changes the sample label on exception - [Bug 57613](https://bz.apache.org/bugzilla/show_bug.cgi?id=57613)HTTP Sampler : Added CalDAV verbs (REPORT, MKCALENDAR). Contributed by Richard Brigham (richard.brigham at teamaol.com) - [Bug 48799](https://bz.apache.org/bugzilla/show_bug.cgi?id=48799)Add time to establish connection to available sample metrics. Implemented by Andrey Pokhilko (andrey at blazemeter.com) and contributed by BlazeMeter Ltd. and Pieter Ennes (apache.org at spam.ennes.nl) - [Bug 57500](https://bz.apache.org/bugzilla/show_bug.cgi?id=57500)Introduce retry behavior for distributed testing. Implemented by Andrey Pokhilko and Dzimitry Kashlach and contributed by BlazeMeter Ltd. #### Other samplers - [Bug 57322](https://bz.apache.org/bugzilla/show_bug.cgi?id=57322)JDBC Test elements: add ResultHandler to deal with ResultSets(cursors) returned by callable statements. Contributed by Yngvi Þór Sigurjónsson (blitzkopf at gmail.com) #### Controllers - [Bug 57561](https://bz.apache.org/bugzilla/show_bug.cgi?id=57561)Module controller UI : Replace combobox by tree. Contributed by Maciej Franek (maciej.franek at gmail.com) - [Bug 57648](https://bz.apache.org/bugzilla/show_bug.cgi?id=57648)TestFragment should be disabled when created. Contributed by Ubik Load Pack (support at ubikloadpack.com) #### Listeners - [Bug 55932](https://bz.apache.org/bugzilla/show_bug.cgi?id=55932)Create a Async BackendListener to allow easy plug of new listener (Graphite, JDBC, Console, …) - [Bug 57246](https://bz.apache.org/bugzilla/show_bug.cgi?id=57246)BackendListener : Create a Graphite implementation - [Bug 57217](https://bz.apache.org/bugzilla/show_bug.cgi?id=57217)Aggregate graph and Aggregate report improvements (3 configurable percentiles, same data in both, factor out code). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57537](https://bz.apache.org/bugzilla/show_bug.cgi?id=57537)BackendListener : Allow implementations to drop samples #### Timers, Assertions, Config, Pre- & Post-Processors #### Functions - [Bug 54453](https://bz.apache.org/bugzilla/show_bug.cgi?id=54453)Performance enhancements : Replace Random by ThreadLocalRandom in __Random function #### I18N #### General - [Bug 57518](https://bz.apache.org/bugzilla/show_bug.cgi?id=57518)Icons for toolbar with several sizes - [Bug 57605](https://bz.apache.org/bugzilla/show_bug.cgi?id=57605)When there is an error loading Test Plan, `SaveService.loadTree` returns `null` leading to NPE in callers - [Bug 57269](https://bz.apache.org/bugzilla/show_bug.cgi?id=57269)Drop `org.apache.jmeter.reports` package - [Bug 53764](https://bz.apache.org/bugzilla/show_bug.cgi?id=53764)Website : Create a new style for website ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 57385](https://bz.apache.org/bugzilla/show_bug.cgi?id=57385)Getting empty thread name in xml result for HTTP requests with "Follow Redirects" set. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57579](https://bz.apache.org/bugzilla/show_bug.cgi?id=57579)NullPointerException error is raised on main sample if "RETURN_NO_SAMPLE" is used (default) and "Use Cache-Control / Expires header…" is checked in HTTP Cache Manager #### Other Samplers #### Controllers - [Bug 57447](https://bz.apache.org/bugzilla/show_bug.cgi?id=57447)Use only the user listed DNS Servers, when "use custom DNS resolver" option is enabled. #### Listeners - [Bug 57262](https://bz.apache.org/bugzilla/show_bug.cgi?id=57262)Aggregate Report, Aggregate Graph and Summary Report export : headers use keys instead of labels - [Bug 57346](https://bz.apache.org/bugzilla/show_bug.cgi?id=57346)Summariser : The + (difference) reports show wrong elapsed time and throughput - [Bug 57449](https://bz.apache.org/bugzilla/show_bug.cgi?id=57449)Distributed Testing: Stripped modes do not strip responses from SubResults (affects load tests that use Download of embedded resources). Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57562](https://bz.apache.org/bugzilla/show_bug.cgi?id=57562)View Results Tree CSS/JQuery Tester : Nothing happens when there is an error in syntax and an exception occurs in jmeter.log - [Bug 57514](https://bz.apache.org/bugzilla/show_bug.cgi?id=57514)Aggregate Graph, Summary Report and Aggregate Report show wrong percentage reporting in saved file #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 57607](https://bz.apache.org/bugzilla/show_bug.cgi?id=57607)Constant Throughput Timer : Wrong throughput computed in shared modes due to rounding error #### General - [Bug 57365](https://bz.apache.org/bugzilla/show_bug.cgi?id=57365)Selected LAF is not correctly setup due to call of `UIManager.setLookAndFeel` too late. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57364](https://bz.apache.org/bugzilla/show_bug.cgi?id=57364)Options < Look And Feel does not update all windows LAF. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57394](https://bz.apache.org/bugzilla/show_bug.cgi?id=57394)When constructing an instance with ClassTools#construct(String, int) the integer was ignored and the default constructor was used instead. - [Bug 57440](https://bz.apache.org/bugzilla/show_bug.cgi?id=57440)OutOfMemoryError after introduction of JSyntaxTextArea in LoggerPanel due to disableUndo not being taken into account. - [Bug 57569](https://bz.apache.org/bugzilla/show_bug.cgi?id=57569)FileServer.reserveFile - inconsistent behaviour when hasHeader is true - [Bug 57555](https://bz.apache.org/bugzilla/show_bug.cgi?id=57555)Cannot use JMeter 2.12 as a maven dependency. Contributed by Pascal Schumacher (pascal.schumacher at t-systems.com) - [Bug 57608](https://bz.apache.org/bugzilla/show_bug.cgi?id=57608)Fix start script compatibility with old Unix shells, e.g. on Solaris ## Non-functional changes - Updated to jsoup-1.8.1.jar (from 1.7.3) - Updated to tika-core and tika-parsers 1.7 (from 1.6) - Updated to commons-codec-1.10.jar (from 1.9) - Updated to dnsjava-2.1.7.jar (from 2.1.6) - Updated to jodd-3.6.4.jar (from 3.6.1) - Updated to junit-4.12.jar (from 4.11) - Updated to rhino-1.7R5 (from 1.7R4) - Updated to rsyntaxtextarea-2.5.6 (from 2.5.3) - Updated to slf4j-1.7.10 (from 1.7.5) - [Bug 57276](https://bz.apache.org/bugzilla/show_bug.cgi?id=57276)RMIC no longer needed since Java 5 - [Bug 57310](https://bz.apache.org/bugzilla/show_bug.cgi?id=57310)Replace `System.getProperty("file.separator")` with `File.separator` throughout (Also "`path.separator"` with `File.pathSeparator`) - [Bug 57389](https://bz.apache.org/bugzilla/show_bug.cgi?id=57389)Fix potential NPE in converters - [Bug 57417](https://bz.apache.org/bugzilla/show_bug.cgi?id=57417)Remove unused method `isTemporary` from `NullProperty`. This was a leftover from a refactoring done in 2003. - [Bug 57418](https://bz.apache.org/bugzilla/show_bug.cgi?id=57418)Remove unused constructor from Workbench - [Bug 57419](https://bz.apache.org/bugzilla/show_bug.cgi?id=57419)Remove unused interface ModelListener. - [Bug 57466](https://bz.apache.org/bugzilla/show_bug.cgi?id=57466)IncludeController : Remove an unneeded set creation. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - Added property `loggerpanel.usejsyntaxtext` to disable the use of JSyntaxTextArea for the Console Logger (in case of memory or other issues) - [Bug 57586](https://bz.apache.org/bugzilla/show_bug.cgi?id=57586)HttpTestSampleGui: Remove interface ItemListener implementation ## Thanks We thank all contributors mentioned in bug and improvement sections above: - [Ubik Load Pack](http://ubikloadpack.com) - Yngvi Þór Sigurjónsson (blitzkopf at gmail.com) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [BlazeMeter Ltd.](http://blazemeter.com) - Benoit Wiart (benoit.wiart at gmail.com) - Pascal Schumacher (pascal.schumacher at t-systems.com) - Maciej Franek (maciej.franek at gmail.com) - Richard Brigham (richard.brigham at teamaol.com) - Pieter Ennes (apache.org at spam.ennes.nl) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Chaitanya Bhatt (bhatt.chaitanya at gmail.com) for his thorough testing of new BackendListener and Graphite Client implementation. - Marcelo Jara (marcelojara at hotmail.com) for his clear report on [Bug 57607](https://bz.apache.org/bugzilla/show_bug.cgi?id=57607). Apologies if we have omitted anyone else. ## New Elements ### New Async BackendListener with Graphite implementation A new Async BackendListener has been added to allow sending result data to a backend listener. JMeter ships with a GraphiteBackendListenerClient that allows sending results to a [Graphite](http://graphite.wikidot.com/) server using Pickle or Plaintext protocols. You can implement your own backend by extending [AbstractBackendListenerClient](/./api/org/apache/jmeter/visualizers/backend/AbstractBackendListenerClient/). This backend could be a database (JDBC), a Message Oriented Middleware (JMS), a Webservice or anything you want. ![changes/2.13/backend_listener_graphite.png](/images/screenshots/changes/2.13/backend_listener_graphite.png) This is the kind of Live Dashboard you can obtain using [Grafana](http://grafana.org/) and [InfluxDB](http://influxdb.com/) Read [this](/./usermanual/realtime-results/) for more details. ![Grafana dashboard](/images/screenshots/grafana_dashboard.png) _Grafana dashboard_ ## Core Improvements ### New connect time metric Starting with this version a new metric called connectTime has been added. It represents the time to establish connection. By default it is not saved to CSV or XML, to have it saved add to user.properties: ` jmeter.save.saveservice.connect_time=true ` ![changes/2.13/connect_time_table.png](/images/screenshots/changes/2.13/connect_time_table.png) ![changes/2.13/connect_time_tree.png](/images/screenshots/changes/2.13/connect_time_tree.png) ### Aggregate Graph and Report The listeners Aggregate Graph and Aggregate Report previously showed only the 90 percentile (historical behavior), the 95 percentile and the 99 percentile have been added and are customizable. To setup the percentiles value you want, add to user.properties: ` aggregate_rpt_pct1=90 aggregate_rpt_pct2=95 aggregate_rpt_pct3=99 ` ![changes/2.13/aggregate_graph_new_percentile.png](/images/screenshots/changes/2.13/aggregate_graph_new_percentile.png) ### HTTP(S) Test Script Recorder Now component is able to detect authentication schemes and automatically adds a pre-configured HTTP Authorization Manager with the correct Mechanism. ### HTTP Request The CalDAV verbs (Calendar extensions to WebDAV) REPORT and MKCALENDAR have been added in the HTTP Request sampler. ![changes/2.13/new_methods_caldav.png](/images/screenshots/changes/2.13/new_methods_caldav.png) ### JDBC Request The ResultSet can be get as a object, this allows to handle more easily the results after in BeanShell, JSR223 scripts, … ![changes/2.13/jdbc_resultset_handler.png](/images/screenshots/changes/2.13/jdbc_resultset_handler.png) ### Distributed Testing To allow better usage of Distributed Testing in the cloud, retry behaviour has been added when starting test on servers. Read [this](/./usermanual/remote-test/#retries) for more details. ![changes/2.13/distributed_retry.png](/images/screenshots/changes/2.13/distributed_retry.png) ### Distributed Testing performance Since JMeter 2.13, Stripping modes (StrippingBatch being the default mode) now also strip responses from SubResults improving consumed network bandwidth. ### Documentation refresh A new style for website (responsive and more up to date) has been created by Felix Schumacher. Documentations have been refreshed particularly: - [Building a Webservice Test Plan](/./usermanual/build-ws-test-plan/) - [Best Practices](/./usermanual/best-practices/) - [Help! My boss wants me to load test our application!](/./usermanual/boss/) ## GUI Improvements ### Module Controller The Module Controller now shows the target controller in a tree view (instead of combo list). ![changes/2.13/module_controller_tree_view.png](/images/screenshots/changes/2.13/module_controller_tree_view.png) ### Toolbar JMeter's toolbar has been refreshed for some icons (start, toggle, etc.). Three sizes are now available for the icons: 22x22, 32x32 and 48x48. The toolbar with 22x22 pixels icons ![changes/2.13/toolbar_22x22.png](/images/screenshots/changes/2.13/toolbar_22x22.png) The toolbar with 32x32 pixels icons ![changes/2.13/toolbar_32x32.png](/images/screenshots/changes/2.13/toolbar_32x32.png) The toolbar with 48x48 pixels icons ![changes/2.13/toolbar_48x48.png](/images/screenshots/changes/2.13/toolbar_48x48.png) ### HTTP(S) Test Script Recorder If your Test Plan does not contains a Recording Controller, a new warning message will appear if the HTTP(S) Test Script Recorder is configured to send the samples into a Recording Controller. ![changes/2.13/warning_message_proxy.png](/images/screenshots/changes/2.13/warning_message_proxy.png) ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: _java.security.cert.CertificateException: Certificates does not conform to algorithm constraints_ if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java **jdk.certpath.disabledAlgorithms** property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.12 Release Notes URL: https://docs.jmeter.ai/releases/2-12/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.12, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 4 | | Improvements | 38 | | Bug fixes | 45 | | Non-functional changes | 12 | ## New and Noteworthy ### Java 8 support Now, JMeter 2.12 is compliant with Java 8. ## Incompatible changes - Since JMeter 2.12, active threads in all thread groups and active threads in current thread group are saved by default to CSV or XML results, see [Bug 57025](https://bz.apache.org/bugzilla/show_bug.cgi?id=57025). This is usually the expected behaviour as you want to have the number of running threads during the test. But if you want to revert to previous behaviour, set property **jmeter.save.saveservice.thread_counts=false** - Since JMeter 2.12, Mail Reader Sampler will show 1 for number of samples instead of number of messages retrieved, see [Bug 56539](https://bz.apache.org/bugzilla/show_bug.cgi?id=56539) - Since JMeter 2.12, when using Cache Manager, if resource is found in cache no SampleResult will be created, in previous version a SampleResult with empty content and 204 return code was returned, see [Bug 54778](https://bz.apache.org/bugzilla/show_bug.cgi?id=54778). You can choose between different ways to handle this case, see `cache_manager.cached_resource_mode` in `jmeter.properties`. - Since JMeter 2.12, Log Viewer will no more clear logs when closed and will have logs available even if closed. See [Bug 56920](https://bz.apache.org/bugzilla/show_bug.cgi?id=56920). Read [Hints and Tips > Enabling Debug logging](/./usermanual/hints-and-tips/#debug_logging) for details on configuring this component. ## Improvements #### HTTP Samplers and Test Script Recorder - [Bug 55959](https://bz.apache.org/bugzilla/show_bug.cgi?id=55959) - Improve error message when Test Script Recorder fails due to I/O problem - [Bug 52013](https://bz.apache.org/bugzilla/show_bug.cgi?id=52013) - Test Script Recorder's Child View Results Tree does not take into account Test Script Recorder excluded/included URLs. Based on report and analysis of James Liang - [Bug 56119](https://bz.apache.org/bugzilla/show_bug.cgi?id=56119) - File uploads fail every other attempt using timers. Enable idle timeouts for servers that don't send Keep-Alive headers. - [Bug 56272](https://bz.apache.org/bugzilla/show_bug.cgi?id=56272) - MirrorServer should support query parameters for status and redirects - [Bug 56772](https://bz.apache.org/bugzilla/show_bug.cgi?id=56772) - Handle IE Conditional comments when parsing embedded resources - [Bug 57026](https://bz.apache.org/bugzilla/show_bug.cgi?id=57026) - HTTP(S) Test Script Recorder : Better default settings. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57107](https://bz.apache.org/bugzilla/show_bug.cgi?id=57107) - Patch proposal: Add DAV verbs to HTTP Sampler. Contributed by Philippe Jung (apache at famille-jung.fr) - [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) - Certificates does not conform to algorithm constraints: Adding a note to indicate how to remove of the Java installation these new security constraints #### Other samplers - [Bug 56033](https://bz.apache.org/bugzilla/show_bug.cgi?id=56033) - Add Connection timeout and Read timeout to SMTP Sampler - [Bug 56429](https://bz.apache.org/bugzilla/show_bug.cgi?id=56429) - MailReaderSampler - no need to fetch all Messages if not all wanted - [Bug 56427](https://bz.apache.org/bugzilla/show_bug.cgi?id=56427) - MailReaderSampler enhancement: read message header only - [Bug 56510](https://bz.apache.org/bugzilla/show_bug.cgi?id=56510) - JMS Publisher/Point to Point: Add JMSPriority and JMSExpiration #### Controllers - [Bug 56728](https://bz.apache.org/bugzilla/show_bug.cgi?id=56728) - New Critical Section Controller to serialize blocks of a Test. Based partly on a patch contributed by Mikhail Epikhin(epihin-m at yandex.ru) - [Bug 57145](https://bz.apache.org/bugzilla/show_bug.cgi?id=57145) - RandomController : Use ThreadLocalRandom instead of Random for better performances #### Listeners - [Bug 56228](https://bz.apache.org/bugzilla/show_bug.cgi?id=56228) - View Results Tree : Improve ergonomy by changing placement of Renderers and allowing custom ordering - [Bug 56349](https://bz.apache.org/bugzilla/show_bug.cgi?id=56349) - "summary" is a bad name for a Generate Summary Results component, documentation clarified - [Bug 56769](https://bz.apache.org/bugzilla/show_bug.cgi?id=56769) - Adds the ability for the Response Time Graph listener to save/restore format settings in/from the jmx file - [Bug 57025](https://bz.apache.org/bugzilla/show_bug.cgi?id=57025) - SaveService : Better defaults, save thread counts by default #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 56691](https://bz.apache.org/bugzilla/show_bug.cgi?id=56691) - Synchronizing Timer : Add timeout on waiting - [Bug 56701](https://bz.apache.org/bugzilla/show_bug.cgi?id=56701) - HTTP Authorization Manager/ Kerberos Authentication: add port to SPN when server port is neither 80 nor 443. Based on patches from Dan Haughey (dan.haughey at swinton.co.uk) and Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 56841](https://bz.apache.org/bugzilla/show_bug.cgi?id=56841) - New configuration element: DNS Cache Manager to improve the testing of CDN. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. - [Bug 52061](https://bz.apache.org/bugzilla/show_bug.cgi?id=52061) - Allow access to Request Headers in Regex Extractor. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. #### Functions - [Bug 56708](https://bz.apache.org/bugzilla/show_bug.cgi?id=56708) - __jexl2 doesn't scale with multiple CPU cores. Based on analysis and patch contributed by Mikhail Epikhin(epihin-m at yandex.ru) - [Bug 57114](https://bz.apache.org/bugzilla/show_bug.cgi?id=57114) - Performance : Functions that only have values as instance variable should not synchronize execute. Based on analysis by Ubik Load Pack support and Vladimir Sitnikov, patch contributed by Vladimir Sitnikov (sitnikov.vladimir at gmail.com) #### I18N #### General - [Bug 21695](https://bz.apache.org/bugzilla/show_bug.cgi?id=21695) - Unix jmeter start script assumes it is on PATH, not a link - [Bug 56292](https://bz.apache.org/bugzilla/show_bug.cgi?id=56292) - Add the check of the Java's version in startup files and disable some options when is Java v8 engine - [Bug 56298](https://bz.apache.org/bugzilla/show_bug.cgi?id=56298) - JSR223 language display does not show which engine will be used - [Bug 56455](https://bz.apache.org/bugzilla/show_bug.cgi?id=56455) - Batch files: drop support for non-NT Windows shell scripts - [Bug 52707](https://bz.apache.org/bugzilla/show_bug.cgi?id=52707) - Make Open File dialog use last opened file folder as start folder. Based on patch from Dzmitry Kashlach (dzmitrykashlach at gmail.com), and contributed by BlazeMeter Ltd. - [Bug 56807](https://bz.apache.org/bugzilla/show_bug.cgi?id=56807) - Ability to force flush of ResultCollector file. Contributed by Andrey Pohilko (apc4 at ya.ru) - [Bug 56921](https://bz.apache.org/bugzilla/show_bug.cgi?id=56921) - Templates : Improve Recording template to ignore embedded resources case and URL parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 42248](https://bz.apache.org/bugzilla/show_bug.cgi?id=42248) - Undo-redo support on Test Plan tree modification. Developed by Andrey Pohilko (apc4 at ya.ru) and contributed by BlazeMeter Ltd. Additional contribution by Ubik Load Pack (support at ubikloadpack.com) - [Bug 56920](https://bz.apache.org/bugzilla/show_bug.cgi?id=56920) - LogViewer : Make it receive all log events even when it is closed. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57083](https://bz.apache.org/bugzilla/show_bug.cgi?id=57083) - simplified the CachedResourceMode enum. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57082](https://bz.apache.org/bugzilla/show_bug.cgi?id=57082) - ComboStringEditor : Added hashCode to an inner class which overwrote equals. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57081](https://bz.apache.org/bugzilla/show_bug.cgi?id=57081) - Updating checkstyle to only check for tabs in java, xml, xsd, dtd, htm, html and txt files (not images!). Contributed by Graham Russell (graham at ham1.co.uk) - [Bug 56178](https://bz.apache.org/bugzilla/show_bug.cgi?id=56178) - Really replace backslashes in user name before generating proxy certificate. Contributed by Graham Russel (graham at ham1.co.uk) - [Bug 57084](https://bz.apache.org/bugzilla/show_bug.cgi?id=57084) - Close socket after usage in BeanShellClient. Contributed by Graham Russel (graham at ham1.co.uk) ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 55998](https://bz.apache.org/bugzilla/show_bug.cgi?id=55998) - HTTP recording – Replacing port value by user defined variable does not work - [Bug 56178](https://bz.apache.org/bugzilla/show_bug.cgi?id=56178) - keytool error: Invalid escaped character in AVA: - some characters must be escaped - [Bug 56222](https://bz.apache.org/bugzilla/show_bug.cgi?id=56222) - NPE if jmeter.httpclient.strict_rfc2616=true and location is not absolute - [Bug 56263](https://bz.apache.org/bugzilla/show_bug.cgi?id=56263) - DefaultSamplerCreator should set BrowserCompatible Multipart true - [Bug 56231](https://bz.apache.org/bugzilla/show_bug.cgi?id=56231) - Move redirect location processing from HC3/HC4 samplers to HTTPSamplerBase#followRedirects() - [Bug 56207](https://bz.apache.org/bugzilla/show_bug.cgi?id=56207) - URLs get encoded on redirects in HC3.1 & HC4 samplers - [Bug 56303](https://bz.apache.org/bugzilla/show_bug.cgi?id=56303) - The width of target controller's combo list should be set to the current panel size, not on label size of the controllers - [Bug 54778](https://bz.apache.org/bugzilla/show_bug.cgi?id=54778) - HTTP Sampler should not return 204 when resource is found in Cache, make it configurable with new property cache_manager.cached_resource_mode #### Other Samplers - [Bug 55977](https://bz.apache.org/bugzilla/show_bug.cgi?id=55977) - JDBC pool keepalive flooding - [Bug 55999](https://bz.apache.org/bugzilla/show_bug.cgi?id=55999) - Scroll bar on jms point-to-point sampler does not work when content exceeds display - [Bug 56198](https://bz.apache.org/bugzilla/show_bug.cgi?id=56198) - JMSSampler : NullPointerException is thrown when JNDI underlying implementation of JMS provider does not comply with `Context.getEnvironment` contract - [Bug 56428](https://bz.apache.org/bugzilla/show_bug.cgi?id=56428) - MailReaderSampler - should it use mail.pop3s.* properties? - [Bug 46932](https://bz.apache.org/bugzilla/show_bug.cgi?id=46932) - Alias given in select statement is not used as column header in response data for a JDBC request. Based on report and analysis of Nicola Ambrosetti - [Bug 56539](https://bz.apache.org/bugzilla/show_bug.cgi?id=56539) - Mail reader sampler: When Number of messages to retrieve is superior to 1, Number of samples should only show 1 not the number of messages retrieved - [Bug 56809](https://bz.apache.org/bugzilla/show_bug.cgi?id=56809) - JMSSampler closes InitialContext too early. Contributed by Bradford Hovinen (hovinen at gmail.com) - [Bug 56761](https://bz.apache.org/bugzilla/show_bug.cgi?id=56761) - JMeter tries to stop already stopped JMS connection and displays "The connection is closed" - [Bug 57068](https://bz.apache.org/bugzilla/show_bug.cgi?id=57068) - No error thrown when negative duration is entered in Test Action - [Bug 57078](https://bz.apache.org/bugzilla/show_bug.cgi?id=57078) - LagartoBasedHTMLParser fails to parse page that contains input with no type - [Bug 57183](https://bz.apache.org/bugzilla/show_bug.cgi?id=57183) - JMSSampler: For input string: "" java.lang.NumberFormatException (for Expiration or Priority fields) #### Controllers - [Bug 56243](https://bz.apache.org/bugzilla/show_bug.cgi?id=56243) - Foreach works incorrectly with indexes on subsequent iterations - [Bug 56276](https://bz.apache.org/bugzilla/show_bug.cgi?id=56276) - Loop controller becomes broken once loop count evaluates to zero - [Bug 56160](https://bz.apache.org/bugzilla/show_bug.cgi?id=56160) - StackOverflowError when using WhileController within IfController - [Bug 56811](https://bz.apache.org/bugzilla/show_bug.cgi?id=56811) - "Start Next Thread Loop" in Result Status Action Handler or on Thread Group and "Go to next Loop iteration" in Test Action behave incorrectly with TransactionController that has "Generate Parent Sampler" checked #### Listeners - [Bug 56706](https://bz.apache.org/bugzilla/show_bug.cgi?id=56706) - SampleResult#getResponseDataAsString() does not use encoding in response body impacting PostProcessors and ViewResultsTree. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57052](https://bz.apache.org/bugzilla/show_bug.cgi?id=57052) - ArithmeticException: / by zero when sampleCount is equal to 0 #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 56162](https://bz.apache.org/bugzilla/show_bug.cgi?id=56162) - HTTP Cache Manager should not cache PUT/POST etc. - [Bug 56227](https://bz.apache.org/bugzilla/show_bug.cgi?id=56227) - AssertionGUI : NPE in assertion on mouse selection - [Bug 41319](https://bz.apache.org/bugzilla/show_bug.cgi?id=41319) - URLRewritingModifier : Allow Parameter value to be url encoded #### Functions #### I18N - [Bug 56111](https://bz.apache.org/bugzilla/show_bug.cgi?id=56111) - "comments" in german translation is not correct #### General - [Bug 56059](https://bz.apache.org/bugzilla/show_bug.cgi?id=56059) - Older TestBeans incompatible with 2.11 when using TextAreaEditor - [Bug 56080](https://bz.apache.org/bugzilla/show_bug.cgi?id=56080) - Conversion error com.thoughtworks.xstream.converters.ConversionException with Java 8 Early Access Build - [Bug 56182](https://bz.apache.org/bugzilla/show_bug.cgi?id=56182) - Can't trigger bsh script using bshclient.jar; socket is closed unexpectedly - [Bug 56360](https://bz.apache.org/bugzilla/show_bug.cgi?id=56360) - HashTree and ListedHashTree fail to compile with Java 8 - [Bug 56419](https://bz.apache.org/bugzilla/show_bug.cgi?id=56419) - JMeter silently fails to save results - [Bug 56662](https://bz.apache.org/bugzilla/show_bug.cgi?id=56662) - Save as xml in a listener is not remembered - [Bug 56367](https://bz.apache.org/bugzilla/show_bug.cgi?id=56367) - JMeter 2.11 on maven central triggers a not existing dependency rsyntaxtextarea 2.5.1, upgrade to 2.5.3 - [Bug 56743](https://bz.apache.org/bugzilla/show_bug.cgi?id=56743) - Wrong mailing list archives on mail2.xml. Contributed by Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 56763](https://bz.apache.org/bugzilla/show_bug.cgi?id=56763) - Removing the Oracle icons, not used by JMeter (and missing license) - [Bug 54100](https://bz.apache.org/bugzilla/show_bug.cgi?id=54100) - Switching languages fails to preserve toolbar button states (enabled/disabled) - [Bug 54648](https://bz.apache.org/bugzilla/show_bug.cgi?id=54648) - JMeter GUI on OS X crashes when using CMD+C (keyboard shortcut or UI menu entry) on an element from the tree - [Bug 56962](https://bz.apache.org/bugzilla/show_bug.cgi?id=56962) - JMS GUIs should disable all fields affected by jndi.properties checkbox - [Bug 57061](https://bz.apache.org/bugzilla/show_bug.cgi?id=57061) - Save as Test Fragment fails to clone deeply selected node. Contributed by Ubik Load Pack (support at ubikloadpack.com) - [Bug 57075](https://bz.apache.org/bugzilla/show_bug.cgi?id=57075) - BeanInfoSupport.MULTILINE attribute is not processed - [Bug 57076](https://bz.apache.org/bugzilla/show_bug.cgi?id=57076) - BooleanPropertyEditor#getAsText() must return a value that is in getTags() - [Bug 57088](https://bz.apache.org/bugzilla/show_bug.cgi?id=57088) - NPE in ResultCollector.testEnded ## Non-functional changes - [Bug 57117](https://bz.apache.org/bugzilla/show_bug.cgi?id=57117) - Increase the default cipher for HTTPS Test Script Recorder from SSLv3 to TLS - Updated to commons-lang3 3.3.2 (from 3.1) - Updated to commons-codec 1.9 (from 1.8) - Updated to commons-logging 1.2 (from 1.1.3) - Updated to tika 1.6 (from 1.4) - Updated to xercesImpl 2.11.0 (from 2.9.1) - Updated to xml-apis 1.4.01 (from 1.3.04) - Updated to xstream 1.4.8 (from 1.4.4) - Updated to jodd 3.6.1 (from 3.4.10) - Updated to rsyntaxtextarea 2.5.3 (from 2.5.1) - Updated xalan and serializer to 2.7.2 (from 2.7.1) - Updated to jsoup-1.8.1.jar (from 1.7.3) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - James Liang (jliang at andera.com) - Emmanuel Bourg (ebourg at apache.org) - Nicola Ambrosetti (ambrosetti.nicola at gmail.com) - [Ubik Load Pack](http://ubikloadpack.com) - Mikhail Epikhin (epihin-m at yandex.ru) - Dan Haughey (dan.haughey at swinton.co.uk) - Felix Schumacher (felix.schumacher at internetallee.de) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - Andrey Pohilko (apc4 at ya.ru) - Bradford Hovinen (hovinen at gmail.com) - [BlazeMeter Ltd.](http://blazemeter.com) - Graham Russell (graham at ham1.co.uk) - Philippe Jung (apache at famille-jung.fr) - Vladimir Sitnikov (sitnikov.vladimir at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Oliver LLoyd (email at oliverlloyd.com) for his help on [Bug 56119](https://bz.apache.org/bugzilla/show_bug.cgi?id=56119) - Vladimir Ryabtsev (greatvovan at gmail.com) for his help on [Bug 56243](https://bz.apache.org/bugzilla/show_bug.cgi?id=56243) and [Bug 56276](https://bz.apache.org/bugzilla/show_bug.cgi?id=56276) - Adrian Speteanu (asp.adieu at gmail.com) and Matt Kilbride (matt.kilbride at gmail.com) for their feedback and tests on [Bug 54648](https://bz.apache.org/bugzilla/show_bug.cgi?id=54648) - Shmuel Krakower (shmulikk at gmail.com) for his tests and reports on Undo/Redo feature Apologies if we have omitted anyone else. ## New Elements ### Critical Section Controller The Critical Section Controller allow to serialize the execution of a section in your tree. Only one instance of the section will be executed at the same time during the test. ![changes/2.12/01_critical_section_controller.png](/images/screenshots/changes/2.12/01_critical_section_controller.png) ### DNS Cache Manager The new configuration element **DNS Cache Manager**(see [Bug 56841](https://bz.apache.org/bugzilla/show_bug.cgi?id=56841)) improves the testing of: - CDN (Content Delivery Network) - DNS load balancing. - Load Balancers like Amazon Elastic Load Balancer ![changes/2.12/02_dns_cache_manager.png](/images/screenshots/changes/2.12/02_dns_cache_manager.png) ## Core Improvements ### Smarter Recording of Http Test Plans Test Script Recorder has been improved in many ways - Better matching of Variables in Requests, making Test Script Recorder variabilize your sampler during recording more versatile - Ability to filter from View Results Tree the Samples that are excluded from recording, this lets you concentrate on recorded Samplers analysis and not bother with useless Sample Results ![changes/2.12/14_recorder_filter.png](/images/screenshots/changes/2.12/14_recorder_filter.png) - Better defaults for recording, since this version Recorder will number created Samplers letting you find them much easily in View Results Tree. Grouping of Samplers under Transaction Controller will be smarter making all requests emitted by a web page be children as new Transaction Controller ### Support of Webdav requests You can now test against WebDav server using HttpClient4 Implementation of Http Request ![changes/2.12/13_webdav.png](/images/screenshots/changes/2.12/13_webdav.png) ### Better handling of embedded resources When download embedded resources is checked, JMeter now uses User Agent header to download or not resources embedded within conditional comments as per [About conditional comments](http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx). ### Ability to customize Cache Manager (Browser cache simulation) handling of cached resources You can now configure the behaviour of JMeter when a resource is found in Cache, this can be controlled with _cache_manager.cached_resource_mode_ property ![changes/2.12/12_cache_resource_mode.png](/images/screenshots/changes/2.12/12_cache_resource_mode.png) ### JMS Publisher / JMS Point-to-Point Add JMSPriority and JMSExpiration fields for these samplers. ![changes/2.12/04_jms_publisher.png](/images/screenshots/changes/2.12/04_jms_publisher.png) ![changes/2.12/05_jms_point_to_point.png](/images/screenshots/changes/2.12/05_jms_point_to_point.png) ### Mail Reader Sampler You can now specify the number of messages that want you retrieve (before all messages were retrieved). In addition, you can fetch only the message header now. ![changes/2.12/03_mail_reader_sampler.png](/images/screenshots/changes/2.12/03_mail_reader_sampler.png) ### SMTP Sampler Adding the Connection timeout and the Read timeout to the **SMTP Sampler.** ![changes/2.12/06_smtp_sampler.png](/images/screenshots/changes/2.12/06_smtp_sampler.png) ### Synchronizing Timer Adding a timeout to define the maximum time to waiting of the group of virtual users. ![changes/2.12/09_synchronizing_timer.png](/images/screenshots/changes/2.12/09_synchronizing_timer.png) ### Performance improvements A big improvement in performances of Functions has been made by lifting useless synchronization. It concerns all functions except __StringFromFile, __XPath and __BeanShell, see [Bug 57114](https://bz.apache.org/bugzilla/show_bug.cgi?id=57114) __jexl2 performances have been improved to avoid contention point, see [Bug 56708](https://bz.apache.org/bugzilla/show_bug.cgi?id=56708) ## GUI Improvements ### Undo/Redo support Undo / Redo has been introduced and allows user to undo/redo changes made on Test Plan Tree. This feature (ALPHA MODE) is disabled by default, to enable it set property **undo.history.size=25** ![changes/2.12/10_undo_redo.png](/images/screenshots/changes/2.12/10_undo_redo.png) ### View Results Tree Improve the ergonomics of View Results Tree by changing placement of Renderers and allowing custom ordering (with the property _view.results.tree.renderers_order_). ![changes/2.12/07_view_results_tree.png](/images/screenshots/changes/2.12/07_view_results_tree.png) ### Response Time Graph Adding the ability for the **Response Time Graph** listener to save/restore format its settings in/from the jmx file. ![changes/2.12/08_response_time_graph.png](/images/screenshots/changes/2.12/08_response_time_graph.png) ### Log Viewer Starting with this version, the last lines of JMeter's log file (jmeter.log) can be viewed directly in GUI by clicking on Warning icon in the upper right corner. This will unfold the Log Viewer panel and show logs. ![changes/2.12/11_log_viewer.png](/images/screenshots/changes/2.12/11_log_viewer.png) ### File Opening Now, "Open File dialog" uses last opened file folder as start folder, see [Bug 52707](https://bz.apache.org/bugzilla/show_bug.cgi?id=52707) ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - Note that under some windows systems you may have this WARNING: ``` java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0 x80000002. Windows RegCreateKeyEx(…) returned error code 5. ``` The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. - You may encounter the following error: _java.security.cert.CertificateException: Certificates does not conform to algorithm constraints_ if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature algorithm using MD2 (like md2WithRSAEncryption) or with a SSL certificate with a size lower than 1024 bits. This error is related to increased security in Java 7 version u16 (MD2) and version u40 (Certificate size lower than 1024 bits), and Java 8 too. To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing the Java **jdk.certpath.disabledAlgorithms** property. Remove the MD2 value or the constraint on size, depending on your case. This property is in this file: ``` JAVA_HOME/jre/lib/security/java.security ``` See [Bug 56357](https://bz.apache.org/bugzilla/show_bug.cgi?id=56357) for details. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.11 Release Notes URL: https://docs.jmeter.ai/releases/2-11/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.11, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | New and Noteworthy | 2 | | Incompatible changes | 4 | | Improvements | 13 | | Bug fixes | 9 | | Non-functional changes | 5 | ## New and Noteworthy ### HTTP(S) Test Script Recorder improvements Following improvements have been made since major changes introduced in JMeter 2.10 on HTTP(S) Test Script Recorder: - Better detection of missing or invalid configuration of keytool utility - New system property `keytool.directory` (see `system.properties`) lets you configure directory containing keytool in case on non-standard installation ### JMS Publisher/Point to Point : Add ability to set typed values in JMS header properties In the samplers JMS Publisher and JMS Point-to-Point, you can now set up the class of values for the JMS header properties. Previously only String was possible. ![changes/2.11/01_jms_properties_typed_values.png](/images/screenshots/changes/2.11/01_jms_properties_typed_values.png) ### View Results Tree : Add an XPath Tester In View Results Tree listener, a new XPath tester can be used to test XPATH expressions. ![changes/2.11/03_xpath_tester.png](/images/screenshots/changes/2.11/03_xpath_tester.png) ### Ability to choose the client alias for the cert key in JsseSslManager such that Mutual SSL auth testing can be made more flexible When testing client based certificate authentications you have now better control on certificate you use through a new field "Variable name holding certificate alias", this field lets you select the certificate you want to send to server to authenticate. You can use a CSV Data Set as a holder for the variable value. ![changes/2.11/07_keystore_config.png](/images/screenshots/changes/2.11/07_keystore_config.png) ### Add a "Save as Test Fragment" option In the file menu, a new option allow to save a group of elements as a Test fragment. ![changes/2.11/05_save_as_fragement.png](/images/screenshots/changes/2.11/05_save_as_fragement.png) ### Summariser is be enabled by default in Non GUI mode When you run JMeter from command line, now JMeter displays some statistics from the Summariser mode. ![changes/2.11/06_summariser.png](/images/screenshots/changes/2.11/06_summariser.png) ### Transaction Controller:Change default property "Include duration of timer…" for newly created element Starting from 2.11, Transaction Controller is configured by default to exclude processing time of pre/post processors as long as timers pause. ![changes/2.11/02_transaction_controller.png](/images/screenshots/changes/2.11/02_transaction_controller.png) ## Incompatible changes - When creating a new Transaction Controller, property "Include duration of timer and pre-post processors in generated sample" will be unchecked starting from version 2.11 - In Non GUI mode, since 2.11 summariser is enabled with a 30 seconds frequency - JMeter is more lenient with redirect handling and relaxes on RFC2616 by allowing relative locations. See property "`jmeter.httpclient.strict_rfc2616`" in `jmeter.properties` to change this behaviour, see [Bug 55717](https://bz.apache.org/bugzilla/show_bug.cgi?id=55717) - When creating a new Response Assertion, property "Pattern Matching Rules" now defaults to Substring starting from version 2.11 ## Improvements #### HTTP Samplers and Proxy #### Other samplers - [Bug 55589](https://bz.apache.org/bugzilla/show_bug.cgi?id=55589) - JMS Publisher/Point to Point : Add ability to set typed values in JMS header properties. #### Controllers - [Bug 55854](https://bz.apache.org/bugzilla/show_bug.cgi?id=55854) - Transaction Controller:Change default property "Include duration of timer…" for newly created element #### Listeners - [Bug 55610](https://bz.apache.org/bugzilla/show_bug.cgi?id=55610) - View Results Tree : Add an XPath Tester #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 55908](https://bz.apache.org/bugzilla/show_bug.cgi?id=55908) - Response assertion : Change Pattern Matching Rules default to Substring on creation for better performances - [Bug 54977](https://bz.apache.org/bugzilla/show_bug.cgi?id=54977) - Ability to choose the client alias for the cert key in JsseSslManager such that Mutual SSL auth testing can be made more flexible. Contributed by UBIK Load Pack (support at ubikloadpack.com) #### Functions #### I18N #### General - [Bug 55693](https://bz.apache.org/bugzilla/show_bug.cgi?id=55693) - Add a "Save as Test Fragment" option - [Bug 55753](https://bz.apache.org/bugzilla/show_bug.cgi?id=55753) - Improve FilePanel behaviour to start from the value set in Filename field if any. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55756](https://bz.apache.org/bugzilla/show_bug.cgi?id=55756) - HTTP Mirror Server : Add ability to set Headers - [Bug 55852](https://bz.apache.org/bugzilla/show_bug.cgi?id=55852) - Be more lenient in parsing when charset value is surrounded with single quotes - [Bug 55857](https://bz.apache.org/bugzilla/show_bug.cgi?id=55857) - Performance : AbstractProperty should test for emptiness to avoid Exception throwing - [Bug 55858](https://bz.apache.org/bugzilla/show_bug.cgi?id=55858) - Startup Performance : On Startup, BeanInfoSupport should test for key availability instead of throwing - [Bug 55865](https://bz.apache.org/bugzilla/show_bug.cgi?id=55865) - Performance :Disable stale check by default in HttpClient 4 and 3.1 - [Bug 55512](https://bz.apache.org/bugzilla/show_bug.cgi?id=55512) - Summariser should be enabled by default in Non GUI mode ## Bug fixes #### HTTP Samplers and Test Script Recorder - [Bug 55815](https://bz.apache.org/bugzilla/show_bug.cgi?id=55815) - Proxy#getDomainMatch does not handle wildcards correctly - [Bug 55717](https://bz.apache.org/bugzilla/show_bug.cgi?id=55717) - Bad handling of Redirect when URLs are in relative format by HttpClient4 and HttpClient3.1 #### Other Samplers - [Bug 55685](https://bz.apache.org/bugzilla/show_bug.cgi?id=55685) - OS Sampler: timeout option don't save and restore correctly value and don't init correctly timeout #### Controllers - [Bug 55816](https://bz.apache.org/bugzilla/show_bug.cgi?id=55816) - Transaction Controller with "Include duration of timer…" unchecked does not ignore processing time of last child sampler #### Listeners - [Bug 55826](https://bz.apache.org/bugzilla/show_bug.cgi?id=55826) - Unsynchronised concurrent accesses to list in field RespTimeGraphVisualizer.internalList #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 55694](https://bz.apache.org/bugzilla/show_bug.cgi?id=55694) - Assertions and Extractors : Avoid NullPointerException when scope is variable and variable is missing - [Bug 55721](https://bz.apache.org/bugzilla/show_bug.cgi?id=55721) - HTTP Cache Manager - no-store directive is wrongly interpreted #### Functions - [Bug 55871](https://bz.apache.org/bugzilla/show_bug.cgi?id=55871) - Wrong result with intSum() function when a space character is present before/after the number. Contributed by Milamber based on a proposal by James Liang. #### I18N #### General - [Bug 55739](https://bz.apache.org/bugzilla/show_bug.cgi?id=55739) - Remote Test : Total threads in GUI mode shows invalid total number of threads ## Non-functional changes - Updated to rsyntaxtextarea-2.5.1.jar (from 2.5.0) - Updated to jodd-core-3.4.9.jar from (3.4.8) and jodd-lagarto-3.4.9.jar (from 3.4.9) - Updated to jsoup-1.7.3.jar (from 1.7.2) - Updated to mail-1.5.0-b01 (from 1.4.4) - Updated to mongo-java-driver-2.11.3 (from 2.11.2) ## Thanks We thank all contributors mentioned in bug and improvement sections above: - James Liang (jliang at andera.com) - UBIK Load Pack (support at ubikloadpack.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - John Natsioulas (john_natsioulas at yahoo.com.au) - Antonio Gomes Rodrigues (ra0077 at gmail.com) Apologies if we have omitted anyone else. ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). - The numbers that appear to the left of the green box are the number of active threads / total number of threads, the total number of threads only applies to a locally run test, otherwise it will show 0 (see [Bug 55510](https://bz.apache.org/bugzilla/show_bug.cgi?id=55510)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.10 Release Notes URL: https://docs.jmeter.ai/releases/2-10/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.10, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Change summary | Section | Changes | | --- | --- | | Incompatible changes | 11 | | Improvements | 52 | | Bug fixes | 61 | | Non-functional changes | 29 | ## New and Noteworthy ## Incompatible changes - **SMTP Sampler** now uses eml file subject if subject field is empty - With this version autoFlush has been turned off on PrintWriter in charge of writing test results. This results in improved throughput for intensive tests but can result in more test data loss in case of JMeter crash (extremely rare). To revert to previous behaviour set `jmeter.save.saveservice.autoflush` property to `true`. - Shortcut for **Function Helper Dialog** is now _CTRL+SHIFT+F1 (CMD + SHIFT + F1 for Mac OS)_. The original key sequence _(Ctrl+F1)_ did not work in some locations (it is consumed by the Java Swing ToolTipManager). It was therefore necessary to change the shortcut. - **Webservice (SOAP) Request** has been removed by default from GUI as Element is deprecated. (Use **HTTP Request** with _Body Data_, see also the Template _Building a SOAP Webservice Test Plan_), if you need to show it, see property `not_in_menu` in _jmeter.properties_ - **Transaction Controller** now sets _Response Code_ of _Generated Parent Sampler_ (if _Generated Parent Sampler_ is checked) to response code of first failing child in case of failure of one of the children, in previous versions _Response Code_ was empty. - In previous versions, **IncludeController** could run Test Elements located inside a **Thread Group**, this behaviour (_which was not documented_) could result in weird behaviour, it has been removed in this version (see [Bug 55464](https://bz.apache.org/bugzilla/show_bug.cgi?id=55464)). The correct way to include Test Elements is to use **Test Fragment** as stated in documentation of **Include Controller**. - The retry count for the HttpClient 3.1 and HttpClient 4.x samplers has been changed to **0**. Previously the default was 1, which could cause unexpected additional traffic. - Starting with this version, the **HTTP(S) Test Script Recorder** tries to detect when a sample is the result of a previous redirect. If the current response is a redirect, JMeter will save the redirect URL. When the next request is received, it is compared with the saved redirect URL and if there is a match, JMeter will disable the generated sample. To revert to previous behaviour, set the property `proxy.redirect.disabling=false` - Starting with this version, in **HTTP(S) Test Script Recorder** if Grouping is set to _Put each group in a new Transaction Controller_, the Recorder will create **Transaction Controller** instances with _Include duration of timer and pre-post processors in generated sample_ set to false. This default value reflect more accurately response time. - `__escapeOroRegexpChars` function (which escapes ORO reserved characters) no longer trims the value (see [Bug 55328](https://bz.apache.org/bugzilla/show_bug.cgi?id=55328)) - The _commons-lang-2.6.jar_ has been removed from embedded libraries in `jmeter/lib` folder as it is not needed by JMeter at run-time (it is only used by Apache Velocity for generating documentation). If you use any plugin or third-party code that depends on it, you need to add it in `jmeter/lib` folder ## Improvements #### HTTP Samplers and Proxy - HTTP Request: Small user interaction improvements in Row parameter Detail Box. Contributed by Milamber - [Bug 55255](https://bz.apache.org/bugzilla/show_bug.cgi?id=55255) - Allow Body in HTTP DELETE method to support API that use it (like ElasticSearch). - [Bug 53480](https://bz.apache.org/bugzilla/show_bug.cgi?id=53480) - Add Kerberos support to Http Sampler (HttpClient4). Based on patch by Felix Schumacher (felix.schumacher at internetallee.de) - [Bug 54874](https://bz.apache.org/bugzilla/show_bug.cgi?id=54874) - Support device in addition to source IP address. Based on patch by Dan Fruehauf (malkodan at gmail.com) - [Bug 55488](https://bz.apache.org/bugzilla/show_bug.cgi?id=55488) - Add .ico and .woff file extension to default suggested exclusions in proxy recorder. Contributed by Antonio Gomes Rodrigues - [Bug 55525](https://bz.apache.org/bugzilla/show_bug.cgi?id=55525) - Proxy should support alias for keyserver entry - [Bug 55531](https://bz.apache.org/bugzilla/show_bug.cgi?id=55531) - Proxy recording and redirects. Added code to disable redirected samples. - [Bug 55507](https://bz.apache.org/bugzilla/show_bug.cgi?id=55507) - Proxy SSL recording does not handle external embedded resources well - [Bug 55632](https://bz.apache.org/bugzilla/show_bug.cgi?id=55632) - Have a new implementation of htmlParser for embedded resources parsing with better performances - [Bug 55653](https://bz.apache.org/bugzilla/show_bug.cgi?id=55653) - HTTP(S) Test Script Recorder should set TransactionController property "Include duration of timer and pre-post processors in generated sample" to false #### Other samplers - [Bug 54788](https://bz.apache.org/bugzilla/show_bug.cgi?id=54788) - JMS Point-to-Point Sampler - GUI enhancements to increase readability and ease of use. Contributed by Bruno Antunes (b.m.antunes at gmail.com) - [Bug 54798](https://bz.apache.org/bugzilla/show_bug.cgi?id=54798) - Using subject from EML-file for SMTP Sampler. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 54759](https://bz.apache.org/bugzilla/show_bug.cgi?id=54759) - SSLPeerUnverifiedException using HTTPS , property documented. - [Bug 54896](https://bz.apache.org/bugzilla/show_bug.cgi?id=54896) - JUnit sampler gives only "failed to create an instance of the class" message with constructor problems. - [Bug 55084](https://bz.apache.org/bugzilla/show_bug.cgi?id=55084) - Add timeout support for JDBC Request. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 55403](https://bz.apache.org/bugzilla/show_bug.cgi?id=55403) - Enhancement to OS sampler: Support for timeout - [Bug 55518](https://bz.apache.org/bugzilla/show_bug.cgi?id=55518) - Add ability to limit number of cached PreparedStatements per connection when "Prepared Select Statement", "Prepared Update Statement" or "Callable Statement" query type is selected #### Controllers - [Bug 54271](https://bz.apache.org/bugzilla/show_bug.cgi?id=54271) - Module Controller breaks if test plan is renamed. #### Listeners - [Bug 54532](https://bz.apache.org/bugzilla/show_bug.cgi?id=54532) - Improve Response Time Graph Y axis scale with huge values or small values (< 1000ms). Add a new field to define increment scale. Contributed by Milamber based on patch by Luca Maragnani (luca.maragnani at gmail.com) - [Bug 54576](https://bz.apache.org/bugzilla/show_bug.cgi?id=54576) - View Results Tree : Add a CSS/JQuery Tester. - [Bug 54777](https://bz.apache.org/bugzilla/show_bug.cgi?id=54777) - Improve Performance of default ResultCollector. Based on patch by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 55389](https://bz.apache.org/bugzilla/show_bug.cgi?id=55389) - Show IP source address in request data #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54789](https://bz.apache.org/bugzilla/show_bug.cgi?id=54789) - XPath Assertion - GUI enhancements to increase readability and ease of use. #### Functions - [Bug 54991](https://bz.apache.org/bugzilla/show_bug.cgi?id=54991) - Add functions to encode/decode URL encoded chars (__urlencode and __urldecode). Contributed by Milamber. #### I18N - [Bug 55241](https://bz.apache.org/bugzilla/show_bug.cgi?id=55241) - Need GUI Editor to process fields which are based on Enums with localised display strings - [Bug 55440](https://bz.apache.org/bugzilla/show_bug.cgi?id=55440) - ComboStringEditor should allow tags to be language dependent - [Bug 55432](https://bz.apache.org/bugzilla/show_bug.cgi?id=55432) - CSV Dataset Config loses sharing mode when switching languages #### General - [Bug 54584](https://bz.apache.org/bugzilla/show_bug.cgi?id=54584) - MongoDB plugin. Based on patch by Jan Paul Ettles (janpaulettles at gmail.com) - [Bug 54669](https://bz.apache.org/bugzilla/show_bug.cgi?id=54669) - Add flag forcing non-GUI JVM to exit after test. Contributed by Scott Emmons - [Bug 42428](https://bz.apache.org/bugzilla/show_bug.cgi?id=42428) - Workbench not saved with Test Plan. Contributed by Dzmitry Kashlach (dzmitrykashlach at gmail.com) - [Bug 54825](https://bz.apache.org/bugzilla/show_bug.cgi?id=54825) - Add shortcuts to move elements in the tree. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54834](https://bz.apache.org/bugzilla/show_bug.cgi?id=54834) - Improve Drag & Drop in the jmeter tree. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54839](https://bz.apache.org/bugzilla/show_bug.cgi?id=54839) - Set the application name on Mac. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54841](https://bz.apache.org/bugzilla/show_bug.cgi?id=54841) - Correctly handle the quit shortcut on Mac Os (CMD-Q). Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54844](https://bz.apache.org/bugzilla/show_bug.cgi?id=54844) - Set the application icon on Mac Os. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54864](https://bz.apache.org/bugzilla/show_bug.cgi?id=54864) - Enable multi selection drag & drop in the tree without having to start dragging before releasing Shift or Control. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54945](https://bz.apache.org/bugzilla/show_bug.cgi?id=54945) - Add Shutdown Hook to enable trapping kill or CTRL+C signals. - [Bug 54990](https://bz.apache.org/bugzilla/show_bug.cgi?id=54990) - Download large files avoiding outOfMemory. - [Bug 55085](https://bz.apache.org/bugzilla/show_bug.cgi?id=55085) - UX Improvement : Ability to create New Test Plan from Templates. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55172](https://bz.apache.org/bugzilla/show_bug.cgi?id=55172) - Provide plugins a way to add Top Menu and menu items. - [Bug 55202](https://bz.apache.org/bugzilla/show_bug.cgi?id=55202) - Add syntax color for scripts elements (BeanShell, BSF, and JSR223) and JDBC elements with RSyntaxTextArea. Contributed by Milamber based on patch by Marko Vlahovic (vlahovic74 at gmail.com) - [Bug 55175](https://bz.apache.org/bugzilla/show_bug.cgi?id=55175) - HTTPHC4Impl refactoring to allow better inheritance. - [Bug 55236](https://bz.apache.org/bugzilla/show_bug.cgi?id=55236) - Templates - provide button to reload template details. - [Bug 55237](https://bz.apache.org/bugzilla/show_bug.cgi?id=55237) - Template system should support relative fileName entries. - [Bug 55423](https://bz.apache.org/bugzilla/show_bug.cgi?id=55423) - BatchSampleSender: Reduce locking granularity by moving listener.processBatch outside of synchronized block - [Bug 55424](https://bz.apache.org/bugzilla/show_bug.cgi?id=55424) - Add Stripping to existing SampleSenders - [Bug 55451](https://bz.apache.org/bugzilla/show_bug.cgi?id=55451) - Test Element GUI with JSyntaxTextArea scroll down when text content is long enough to add a Scrollbar - [Bug 55513](https://bz.apache.org/bugzilla/show_bug.cgi?id=55513) - StreamCopier cannot be used with System.err or System.out as it closes the output stream - [Bug 55514](https://bz.apache.org/bugzilla/show_bug.cgi?id=55514) - SystemCommand should support arbitrary input and output streams - [Bug 55515](https://bz.apache.org/bugzilla/show_bug.cgi?id=55515) - SystemCommand should support chaining of commands - [Bug 55606](https://bz.apache.org/bugzilla/show_bug.cgi?id=55606) - Use JSyntaxtTextArea for Http Request, JMS Test Elements - [Bug 55651](https://bz.apache.org/bugzilla/show_bug.cgi?id=55651) - Change JMeter application icon to Apache plume icon ## Bug fixes #### HTTP Samplers and Proxy - [Bug 54627](https://bz.apache.org/bugzilla/show_bug.cgi?id=54627) - JMeter Proxy GUI: Type of sampler setting takes the whole screen when there are samplers with long names. - [Bug 54629](https://bz.apache.org/bugzilla/show_bug.cgi?id=54629) - HTMLParser does not extract <object> tag urls. - [Bug 55023](https://bz.apache.org/bugzilla/show_bug.cgi?id=55023) - SSL Context reuse feature (51380) adversely affects non-ssl request performance/throughput. based on analysis by Brent Cromarty (brent.cromarty at yahoo.ca) - [Bug 55092](https://bz.apache.org/bugzilla/show_bug.cgi?id=55092) - Log message "WARN - jmeter.protocol.http.sampler.HTTPSamplerBase: Null URL detected (should not happen)" displayed when embedded resource URL is malformed. - [Bug 55161](https://bz.apache.org/bugzilla/show_bug.cgi?id=55161) - Useless processing in SoapSampler.setPostHeaders. Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 54482](https://bz.apache.org/bugzilla/show_bug.cgi?id=54482) - HC fails to follow redirects with non-encoded chars. - [Bug 54142](https://bz.apache.org/bugzilla/show_bug.cgi?id=54142) - HTTP Proxy Server throws an exception when path contains "|" character. - [Bug 55388](https://bz.apache.org/bugzilla/show_bug.cgi?id=55388) - HC3 does not allow IP Source field to override httpclient.localaddress. - [Bug 55450](https://bz.apache.org/bugzilla/show_bug.cgi?id=55450) - HEAD redirects should remain as HEAD - [Bug 55455](https://bz.apache.org/bugzilla/show_bug.cgi?id=55455) - HTTPS with HTTPClient4 ignores cps setting - [Bug 55502](https://bz.apache.org/bugzilla/show_bug.cgi?id=55502) - Proxy generates empty http:/ entries when recording - [Bug 55504](https://bz.apache.org/bugzilla/show_bug.cgi?id=55504) - Proxy incorrectly issues CONNECT requests when browser prompts for certificate override - [Bug 55506](https://bz.apache.org/bugzilla/show_bug.cgi?id=55506) - Proxy should deliver failed requests to any configured Listeners - [Bug 55545](https://bz.apache.org/bugzilla/show_bug.cgi?id=55545) - HTTP Proxy Server GUI should not allow both Follow and Auto redirect to be selected #### Other Samplers - [Bug 54913](https://bz.apache.org/bugzilla/show_bug.cgi?id=54913) - JMSPublisherGui incorrectly restores its state. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55027](https://bz.apache.org/bugzilla/show_bug.cgi?id=55027) - Test Action regression, duration value is not recorded (nightly build). - [Bug 55163](https://bz.apache.org/bugzilla/show_bug.cgi?id=55163) - BeanShellTestElement fails to quote string when calling testStarted(String)/testEnded(String). - [Bug 55349](https://bz.apache.org/bugzilla/show_bug.cgi?id=55349) - NativeCommand hangs if no input file is specified and the application requests input. - [Bug 55462](https://bz.apache.org/bugzilla/show_bug.cgi?id=55462) - System Sampler should not change the sampler label if a sample fails #### Controllers - [Bug 54467](https://bz.apache.org/bugzilla/show_bug.cgi?id=54467) - Loop Controller: compute loop value only once per parent iteration. - [Bug 54985](https://bz.apache.org/bugzilla/show_bug.cgi?id=54985) - Make Transaction Controller set Response Code of Generated Parent Sampler to response code of first failing child in case of failure of one of its children. Contributed by Mikhail Epikhin (epihin-m at yandex.ru) - [Bug 54950](https://bz.apache.org/bugzilla/show_bug.cgi?id=54950) - ModuleController : Changes to referenced Module are not taken into account if changes occur after first run and referenced node is disabled. - [Bug 55201](https://bz.apache.org/bugzilla/show_bug.cgi?id=55201) - ForEach controller excludes start index and includes end index (clarified documentation). - [Bug 55334](https://bz.apache.org/bugzilla/show_bug.cgi?id=55334) - Adding Include Controller to test plan (made of Include Controllers) without saving TestPlan leads to included code not being taken into account until save. - [Bug 55375](https://bz.apache.org/bugzilla/show_bug.cgi?id=55375) - StackOverflowError with ModuleController in Non-GUI mode if its name is the same as the target node. - [Bug 55464](https://bz.apache.org/bugzilla/show_bug.cgi?id=55464) - Include Controller running included thread group #### Listeners - [Bug 54589](https://bz.apache.org/bugzilla/show_bug.cgi?id=54589) - View Results Tree have a lot of Garbage characters if html page uses double-byte charset. - [Bug 54753](https://bz.apache.org/bugzilla/show_bug.cgi?id=54753) - StringIndexOutOfBoundsException at SampleResult.getSampleLabel() if key_on_threadname=false when using Statistical mode. - [Bug 54685](https://bz.apache.org/bugzilla/show_bug.cgi?id=54685) - ArrayIndexOutOfBoundsException if "sample_variable" is set in client but not server. - [Bug 55111](https://bz.apache.org/bugzilla/show_bug.cgi?id=55111) - ViewResultsTree: text not refitted if vertical scrollbar is required. Contributed by Milamber #### Timers, Assertions, Config, Pre- & Post-Processors - [Bug 54540](https://bz.apache.org/bugzilla/show_bug.cgi?id=54540) - "HTML Parameter Mask" are not marked deprecated in the IHM. - [Bug 54575](https://bz.apache.org/bugzilla/show_bug.cgi?id=54575) - CSS/JQuery Extractor : Choosing JODD Implementation always uses JSOUP. - [Bug 54901](https://bz.apache.org/bugzilla/show_bug.cgi?id=54901) - Response Assertion GUI behaves weirdly. - [Bug 54924](https://bz.apache.org/bugzilla/show_bug.cgi?id=54924) - XMLAssertion uses JMeter JVM file.encoding instead of response encoding and does not clean threadlocal variable. - [Bug 53679](https://bz.apache.org/bugzilla/show_bug.cgi?id=53679) - Constant Throughput Timer bug with localization. Reported by Ludovic Garcia #### Functions - [Bug 55328](https://bz.apache.org/bugzilla/show_bug.cgi?id=55328) - __escapeOroRegexpChars trims spaces. #### I18N - [Bug 55437](https://bz.apache.org/bugzilla/show_bug.cgi?id=55437) - ComboStringEditor does not translate EDIT and UNDEFINED strings on language change - [Bug 55501](https://bz.apache.org/bugzilla/show_bug.cgi?id=55501) - Incorrect encoding for French description of __char function. Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com) #### General - [Bug 54504](https://bz.apache.org/bugzilla/show_bug.cgi?id=54504) - Resource string not found: [clipboard_node_read_error]. - [Bug 54538](https://bz.apache.org/bugzilla/show_bug.cgi?id=54538) - GUI: context menu is too big. - [Bug 54847](https://bz.apache.org/bugzilla/show_bug.cgi?id=54847) - Cut & Paste is broken with tree multi-selection. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54870](https://bz.apache.org/bugzilla/show_bug.cgi?id=54870) - Tree drag and drop may lose leaf nodes (affected nightly build). Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55056](https://bz.apache.org/bugzilla/show_bug.cgi?id=55056) - wasted work in Data.append(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55129](https://bz.apache.org/bugzilla/show_bug.cgi?id=55129) - Change Javadoc generation per CVE-2013-1571, VU#225657. - [Bug 55187](https://bz.apache.org/bugzilla/show_bug.cgi?id=55187) - Integer overflow when computing ONE_YEAR_MS in HTTP CacheManager. - [Bug 55208](https://bz.apache.org/bugzilla/show_bug.cgi?id=55208) - JSR223 language entries are duplicated; fold to lower case. - [Bug 55203](https://bz.apache.org/bugzilla/show_bug.cgi?id=55203) - TestBeanGUI - wrong language settings found. - [Bug 55065](https://bz.apache.org/bugzilla/show_bug.cgi?id=55065) - Useless processing in Spline3.converge(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55064](https://bz.apache.org/bugzilla/show_bug.cgi?id=55064) - Useless processing in ReportTreeListener.isValidDragAction(). Contributed by Adrian Nistor (nistor1 at illinois.edu) - [Bug 55242](https://bz.apache.org/bugzilla/show_bug.cgi?id=55242) - BeanShell Client jar throws exceptions after upgrading to 2.8. - [Bug 55288](https://bz.apache.org/bugzilla/show_bug.cgi?id=55288) - JMeter should default to 0 retries for HTTP requests. - [Bug 55405](https://bz.apache.org/bugzilla/show_bug.cgi?id=55405) - ant download_jars task fails if lib/api or lib/doc are missing. Contributed by Antonio Gomes Rodrigues. - [Bug 55427](https://bz.apache.org/bugzilla/show_bug.cgi?id=55427) - TestBeanHelper should ignore properties not supported by GenericTestBeanCustomizer - [Bug 55459](https://bz.apache.org/bugzilla/show_bug.cgi?id=55459) - Elements using ComboStringEditor lose the input value if user selects another Test Element - [Bug 54152](https://bz.apache.org/bugzilla/show_bug.cgi?id=54152) - In distributed testing : activeThreads always show 0 in GUI and Summariser - [Bug 55509](https://bz.apache.org/bugzilla/show_bug.cgi?id=55509) - Allow Plugins to be notified of remote thread number progression - [Bug 55572](https://bz.apache.org/bugzilla/show_bug.cgi?id=55572) - Detail popup of parameter does not show a Scrollbar when content exceeds display - [Bug 55580](https://bz.apache.org/bugzilla/show_bug.cgi?id=55580) - Help pane does not scroll to start for <a href="#"> links - [Bug 55600](https://bz.apache.org/bugzilla/show_bug.cgi?id=55600) - JSyntaxTextArea : Strange behaviour on first undo - [Bug 55655](https://bz.apache.org/bugzilla/show_bug.cgi?id=55655) - NullPointerException when Remote stopping /shutdown all if one engine did not start correctly. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55657](https://bz.apache.org/bugzilla/show_bug.cgi?id=55657) - Remote and Local Stop/Shutdown buttons state does not take into account local / remote status ## Non-functional changes - Updated to jsoup-1.7.2 - [Bug 54776](https://bz.apache.org/bugzilla/show_bug.cgi?id=54776) - Update the dependency on Bouncy Castle to 1.48. Contributed by Emmanuel Bourg (ebourg at apache.org) - Updated to HttpComponents Client 4.2.6 (from 4.2.3) - Updated to HttpComponents Core 4.2.5 (from 4.2.3) - Updated to commons-codec 1.8 (from 1.6) - Updated to commons-io 2.4 (from 2.2) - Updated to commons-logging 1.1.3 (from 1.1.1) - Updated to commons-net 3.3 (from 3.1) - Updated to jdom-1.1.3 (from 1.1.2) - Updated to jodd-lagarto and jodd-core 3.4.8 (from 3.4.1) - Updated to junit 4.11 (from 4.10) - Updated to slf4j-api 1.7.5 (from 1.7.2) - Updated to tika 1.4 (from 1.3) - Updated to xmlgraphics-commons 1.5 (from 1.3.1) - Updated to xstream 1.4.4 (from 1.4.2) - Updated to BouncyCastle 1.49 (from 1.48) - [Bug 54912](https://bz.apache.org/bugzilla/show_bug.cgi?id=54912) - JMeterTreeListener should use constants. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 54903](https://bz.apache.org/bugzilla/show_bug.cgi?id=54903) - Remove the dependency on the Activation Framework. Contributed by Emmanuel Bourg (ebourg at apache.org) - Moved commons-lang (2.6) to lib/doc as it's only needed by Velocity. - Re-organised and simplified NOTICE and LICENSE files. - [Bug 55411](https://bz.apache.org/bugzilla/show_bug.cgi?id=55411) - NativeCommand could be useful elsewhere. Copied code to o.a.jorphan.exec. - [Bug 55435](https://bz.apache.org/bugzilla/show_bug.cgi?id=55435) - ComboStringEditor could be simplified to make most settings final - [Bug 55436](https://bz.apache.org/bugzilla/show_bug.cgi?id=55436) - ComboStringEditor should implement ClearGui - [Bug 55463](https://bz.apache.org/bugzilla/show_bug.cgi?id=55463) - Component.requestFocus() is discouraged; use requestFocusInWindow() instead - [Bug 55486](https://bz.apache.org/bugzilla/show_bug.cgi?id=55486) - New JMeter Logo. Contributed by UBIK Load Pack (support at ubikloadpack.com) - [Bug 55548](https://bz.apache.org/bugzilla/show_bug.cgi?id=55548) - Tidy up use of TestElement.ENABLED; use TestElement.isEnabled()/setEnabled() throughout - [Bug 55617](https://bz.apache.org/bugzilla/show_bug.cgi?id=55617) - Improvements to jorphan collection. Contributed by Benoit Wiart (benoit.wiart at gmail.com) - [Bug 55623](https://bz.apache.org/bugzilla/show_bug.cgi?id=55623) - Invalid/unexpected configuration values should not be silently ignored - [Bug 55626](https://bz.apache.org/bugzilla/show_bug.cgi?id=55626) - Rename HTTP Proxy Server as HTTP(S) Test Script Recorder ## Thanks We thank all contributors mentioned in bug and improvement sections above: - Bruno Antunes (b.m.antunes at gmail.com) - Emmanuel Bourg (ebourg at apache.org) - Scott Emmons - Mikhail Epikhin (epihin-m at yandex.ru) - Dzmitry Kashlach (dzmitrykashlach at gmail.com) - Luca Maragnani (luca.maragnani at gmail.com) - Milamber - Adrian Nistor (nistor1 at illinois.edu) - Antonio Gomes Rodrigues (ra0077 at gmail.com) - UBIK Load Pack (support at ubikloadpack.com) - Benoit Wiart (benoit.wiart at gmail.com) We also thank bug reporters who helped us improve JMeter. For this release we want to give special thanks to the following reporters for the clear reports and tests made after our fixes: - Immanuel Hayden (immanuel.hayden at gmail.com) - Danny Lade (dlade at web.de) - Brent Cromarty (brent.cromarty at yahoo.ca) - Wolfgang Heider (wolfgang.heider at racon.at) - Shmuel Krakower (shmulikk at gmail.com) Apologies if we have omitted anyone else. ## Core Improvements ### New Performance improvements - A Huge performance improvement has been made on High Throughput Tests (no pause), see [Bug 54777](https://bz.apache.org/bugzilla/show_bug.cgi?id=54777) - An issue with unnecessary SSL Context reset has been fixed which improves performances of pure HTTP tests, see [Bug 55023](https://bz.apache.org/bugzilla/show_bug.cgi?id=55023) - Important performance improvement in parsing of Embedded resource in HTML pages thanks to a switch to JODD/Lagarto HTML Parser, see [Bug 55632](https://bz.apache.org/bugzilla/show_bug.cgi?id=55632) ### New CSS/JQuery Tester in View Tree Results A new CSS/JQuery Tester in View Tree Results that makes CSS/JQuery Extractor a first class citizen in JMeter, you can now test your expressions very easily ![changes/2.10/01_css_jquery_tester.png](/images/screenshots/changes/2.10/01_css_jquery_tester.png) ### Many improvements in HTTP(S) Recording have been made ![changes/2.10/18_https_test_script_recorder.png](/images/screenshots/changes/2.10/18_https_test_script_recorder.png) :::note The "HTTP Proxy Server" test element has been renamed as "HTTP(S) Test Script Recorder". ::: - Better recording of HTTPS sites, embedded resources using subdomains will more easily be recorded when using JDK 7. See [Bug 55507](https://bz.apache.org/bugzilla/show_bug.cgi?id=55507). See updated documentation: [HTTP(S) Test Script Recorder](/user-manual/component-reference/#HTTP_S__Test_Script_Recorder) - Redirection are now more smartly detected by HTTP Proxy Server, see [Bug 55531](https://bz.apache.org/bugzilla/show_bug.cgi?id=55531) - Many fixes on edge cases with HTTPS have been made, see [Bug 55502](https://bz.apache.org/bugzilla/show_bug.cgi?id=55502), [Bug 55504](https://bz.apache.org/bugzilla/show_bug.cgi?id=55504), [Bug 55506](https://bz.apache.org/bugzilla/show_bug.cgi?id=55506) - Many encoding fixes have been made, see [Bug 54482](https://bz.apache.org/bugzilla/show_bug.cgi?id=54482), [Bug 54142](https://bz.apache.org/bugzilla/show_bug.cgi?id=54142), [Bug 54293](https://bz.apache.org/bugzilla/show_bug.cgi?id=54293) ### You can now load test MongoDB through new MongoDB Source Config ![changes/2.10/02_mongodb_source_config.png](/images/screenshots/changes/2.10/02_mongodb_source_config.png) ![changes/2.10/14_mongodb_jsr223.png](/images/screenshots/changes/2.10/14_mongodb_jsr223.png) ### Kerberos authentication has been added to Auth Manager ![changes/2.10/15_kerberos.png](/images/screenshots/changes/2.10/15_kerberos.png) ### Device can now be used in addition to source IP address ![changes/2.10/16_device.png](/images/screenshots/changes/2.10/16_device.png) ### You can now do functional testing of MongoDB scripts through new MongoDB Script ![changes/2.10/03_mongodb_script_alpha.png](/images/screenshots/changes/2.10/03_mongodb_script_alpha.png) ### Timeout has been added to OS Process Sampler ![changes/2.10/17_os_process_timeout.png](/images/screenshots/changes/2.10/17_os_process_timeout.png) ### Query timeout has been added to JDBC Request ![changes/2.10/04_jdbc_request_timeout.png](/images/screenshots/changes/2.10/04_jdbc_request_timeout.png) ### New functions (__urlencode and __urldecode) are now available to encode/decode URL encoded chars ![changes/2.10/05_urlencode_function.png](/images/screenshots/changes/2.10/05_urlencode_function.png) ### Continuous Integration is now eased by addition of a new flag that forces NON-GUI JVM to exit after test end See jmeter property: `jmeterengine.force.system.exit` ### HttpSampler now allows DELETE Http Method to have a body (works for HC4 and HC31 implementations). This allows for example to test Elastic Search APIs ![changes/2.10/06_http_request_delete_method.png](/images/screenshots/changes/2.10/06_http_request_delete_method.png) ### 2 implementations of HtmlParser have been added to improve Embedded resources parsing You can choose the implementation to use for parsing Embedded resources in HTML pages: See jmeter.properties and look at property "htmlParser.className". - org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser for optimal performances - org.apache.jmeter.protocol.http.parser.JSoupBasedHtmlParser for most accurate parsing and functional testing ### Distributed testing has been improved - Number of threads on each node are now reported to controller. ![changes/2.10/17_threads_summariser.png](/images/screenshots/changes/2.10/17_threads_summariser.png) ![changes/2.10/17_threads_gui.png](/images/screenshots/changes/2.10/17_threads_gui.png) - Performance improvement on BatchSampleSender([Bug 55423](https://bz.apache.org/bugzilla/show_bug.cgi?id=55423)) - Addition of 2 SampleSender modes (StrippedAsynch and StrippedDiskStore), see jmeter.properties ### ModuleController has been improved to better handle changes to referenced controllers ### Improved class loader configuration, see [Bug 55503](https://bz.apache.org/bugzilla/show_bug.cgi?id=55503) - New property "plugin_dependency_paths" for plugin dependencies - Properties "search_paths", "user.classpath" and "plugin_dependency_paths" now automatically add all jars from configured directories ### Best-practices section has been improved, ensure you read it to get the most out of JMeter See [Best Practices](/usermanual/best-practices/) ## GUI and ergonomy Improvements ### New Templates feature that allows you to create test plan from existing template or merge template into your Test Plan ![changes/2.10/07_jmeter_templates_icon.png](/images/screenshots/changes/2.10/07_jmeter_templates_icon.png) ![changes/2.10/08_jmeter_templates_box.png](/images/screenshots/changes/2.10/08_jmeter_templates_box.png) ### Workbench can now be saved ![changes/2.10/09_save_workbench.png](/images/screenshots/changes/2.10/09_save_workbench.png) ### Syntax color has been added to scripts elements (BeanShell, BSF, and JSR223), MongoDB and JDBC elements making code much more readable and allowing UNDO/REDO through CTRL+Z/CTRL+Y BSF Sampler with syntax color ![changes/2.10/10_color_syntax_bsf_sampler.png](/images/screenshots/changes/2.10/10_color_syntax_bsf_sampler.png) JSR223 Pre Processor with syntax color ![changes/2.10/11_color_syntax_jsr223_preprocessor.png](/images/screenshots/changes/2.10/11_color_syntax_jsr223_preprocessor.png) ### Better editors are now available for Test Elements with large text content, like HTTP Sampler, and JMS related Test Element providing line numbering and allowing UNDO/REDO through CTRL+Z/CTRL+Y ### JMeter GUI can now be fully Internationalized, all remaining issues have been fixed ###### Currently French has all its labels translated. Other languages are partly translated, feel free to contribute translations by reading [Localisation (Translator's Guide)](/localising/index/) ### Moving elements in Test plan has been improved in many ways ###### Drag and drop of elements in Test Plan tree is now much easier and possible on multiple nodes ![changes/2.10/12_drap_n-drop_multiple.png](/images/screenshots/changes/2.10/12_drap_n-drop_multiple.png) Note that due to this [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6560955), you cannot drop a node after last node. The workaround is to drop it before this last node and then Drag and Drop the last node before the one you just dropped. ###### New shortcuts have been added to move elements in the tree. (alt + Arrow Up) and (alt + Arrow Down) move the element within the parent node (alt + Arrow Left) and (alt + Arrow Right) move the element up and down in the tree depth ### Response Time Graph Y axis can now be scaled ![changes/2.10/13_response_time_graph_y_scale.png](/images/screenshots/changes/2.10/13_response_time_graph_y_scale.png) ### JUnit Sampler gives now more details on configuration errors ## Known bugs - The Once Only controller behaves correctly under a Thread Group or Loop Controller, but otherwise its behaviour is not consistent (or clearly specified). - Listeners don't show iteration counts when a If Controller has a condition which is always false from the first iteration (see [Bug 52496](https://bz.apache.org/bugzilla/show_bug.cgi?id=52496)). A workaround is to add a sampler at the same level as (or superior to) the If Controller. For example a Test Action sampler with 0 wait time (which doesn't generate a sample), or a Debug Sampler with all fields set to False (to reduce the sample size). - Webservice sampler does not consider the HTTP response status to compute the status of a response, thus a response 500 containing a non empty body will be considered as successful, see [Bug 54006](https://bz.apache.org/bugzilla/show_bug.cgi?id=54006). To workaround this issue, ensure you always read the response and add a Response Assertion checking text inside the response. - The numbers that appear to the left of the green box are the number of active threads / total number of threads, these only apply to a locally run test; they do not include any threads started on remote systems when using client-server mode, (see [Bug 54152](https://bz.apache.org/bugzilla/show_bug.cgi?id=54152)). - Note that there is a [bug in Java](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6396599 ) on some Linux systems that manifests itself as the following error when running the test cases or JMeter itself: ``` [java] WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: java.lang.IllegalArgumentException: Not supported: indent-number ``` This does not affect JMeter operation. This issue is fixed since Java 7b05. - With Java 1.6 and Gnome 3 on Linux systems, the JMeter menu may not work correctly (shift between mouse's click and the menu). This is a known Java bug (see [Bug 54477](https://bz.apache.org/bugzilla/show_bug.cgi?id=54477)). A workaround is to use a Java 7 runtime (OpenJDK or Oracle JDK). - With Oracle Java 7 and Mac Book Pro Retina Display, the JMeter GUI may look blurry. This is a known Java bug, see Bug [JDK-8000629](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000629). A workaround is to use a Java 7 update 40 runtime which fixes this issue. ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.9 Release Notes URL: https://docs.jmeter.ai/releases/2-9/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.9, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.8 Release Notes URL: https://docs.jmeter.ai/releases/2-8/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.8, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.7 Release Notes URL: https://docs.jmeter.ai/releases/2-7/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.7, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.6 Release Notes URL: https://docs.jmeter.ai/releases/2-6/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.6, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.5.1 Release Notes URL: https://docs.jmeter.ai/releases/2-5-1/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.5.1, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.5 Release Notes URL: https://docs.jmeter.ai/releases/2-5/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.5, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.4 Release Notes URL: https://docs.jmeter.ai/releases/2-4/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.4, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.3.4 Release Notes URL: https://docs.jmeter.ai/releases/2-3-4/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.3.4, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/) --- Title: JMeter 2.3.3 Release Notes URL: https://docs.jmeter.ai/releases/2-3-3/ --- {/* GENERATED by scripts/generate-release-pages.mjs from user-manual/changes.mdx and changes-history.mjs - do not edit by hand */} :::note[About these release notes] This page lists every documented change shipped in Apache JMeter 2.3.3, generated from the official changelog. For download and upgrade guidance, see [Download JMeter](/reference/download-jmeter/). ::: ## Useful links - [Download JMeter](/reference/download-jmeter/) - [Getting started guide](/getting-started/get-started/) - [All release notes](/releases/) - [Current changes page](/user-manual/changes/) - [History of previous changes](/user-manual/changes-history/)