skip to content

Which property files does JMeter load at startup, and in what order?

level: middleimportance: must knowfreq 60%

answer

  1. Three files, and one names the others
  2. Only the first has a fixed location
  3. Check the shipped jmeter.properties for two keys
  4. Working directory before bin

basics

~10 s

JMeter loads bin/jmeter.properties first, then the file named by its user.properties key, whose entries override it, then the file named by its system.properties key, which updates the JVM's system properties instead.

solid answer

~40 s

At startup `JMeter.initializeProperties` loads `bin/jmeter.properties` into one static map. It then reads two keys **out of that map** to find the next two files: `user.properties=user.properties` and `system.properties=system.properties` are ordinary entries in the shipped `jmeter.properties`, so the extra files load only because a property names them. The file named by `user.properties` is merged in with `putAll`, so its entries **overwrite** whatever `jmeter.properties` set. The file named by `system.properties` is loaded into `System.getProperties()` instead, updating the JVM's own system properties rather than JMeter's map. Each filename is resolved by `JMeterUtils.findFile`: the name is tried as given, relative to the working directory, and only then under JMeter's `bin` directory. A missing or unreadable file is skipped silently. Command-line property options are processed after all three files.

code

properties · 10 lines
properties
# bin/jmeter.properties, as shipped with JMeter 6.0.0
# ---- Additional property files to load ----

# Should JMeter automatically load additional JMeter properties?
# File name to look for (comment to disable)
user.properties=user.properties

# Should JMeter automatically load additional system properties?
# File name to look for (comment to disable)
system.properties=system.properties

go deeper

for a junior

Know that JMeter has a bin/jmeter.properties and that user.properties next to it is the file you are meant to edit. Recall that the second file wins where both set the same key.

for a middle

Explain the load sequence and the merge. Say that jmeter.properties itself carries the keys naming the other two files, and that user.properties is merged over the baseline while system.properties goes to the JVM.

for a senior

Diagnose the silent cases. A missing file is skipped without an error, and the working directory is searched before bin, so be able to say how you would confirm which file a running instance actually loaded.

for a principal

Decide how the team ships configuration. Fix which file holds environment overrides and which stays stock, so an upgrade of the distribution never silently drops a setting the whole team depends on.

JMeter reads three property files at startup, and the mechanism that finds the second and third of them surprises most people: they are not hard-coded filenames, they are values of ordinary properties defined in the first file. ## The startup sequence `JMeter.initializeProperties` runs before the plan is touched and does the following, in this order: 1. Load `bin/jmeter.properties` into JMeter's single static property map. This is the only file whose location JMeter knows without being told. 2. Read the property named `user.properties` out of the map just built, and if it is not empty, load the file it names, merging the entries in on top. 3. Read the property named `system.properties` out of the same map, and if it is not empty, load the file it names into the JVM's own system properties. 4. Process command-line property options, which are handled last of all and belong to JMeter's invocation flags rather than to the files. ## The two files are named by properties In the JMeter 6.0.0 distribution, `bin/jmeter.properties` contains these two lines under a heading that reads "Additional property files to load": - `user.properties=user.properties` - `system.properties=system.properties` The shipped comment above each one says "File name to look for (comment to disable)", which is exactly right: comment out the line and JMeter stops looking for that file altogether. Nothing else makes `user.properties` special. Point the key at `env-staging.properties` and that becomes the auto-loaded file instead. This has a consequence worth knowing. If you replace `jmeter.properties` with your own stripped-down copy and forget to carry these two keys across, `user.properties` silently stops being read and every override you put in it disappears from the run. ## Merge behaviour differs between the two The two extra files are not treated the same way, and this is the part that decides who wins: | File | Loaded into | Effect on an existing key | |---|---|---| | `bin/jmeter.properties` | JMeter's property map | establishes the baseline | | the file named by `user.properties` | JMeter's property map, via `putAll` | overwrites the `jmeter.properties` value | | the file named by `system.properties` | the JVM's system properties | does **not** overwrite a JMeter map entry | So `user.properties` is the file to edit when you want to change what `${__P(...)}` returns. It is also the file the JMeter project recommends editing, precisely so that upgrading the distribution does not discard your changes along with the stock `jmeter.properties`. ## How each filename is resolved Both extra filenames go through `JMeterUtils.findFile`, which is deliberately simple: - Try the name exactly as given, which for a relative name means relative to the process working directory. - If that does not exist, try it under JMeter's `bin` directory. The working directory is checked **first**. A `user.properties` sitting in the directory you launched from therefore shadows `bin/user.properties` entirely rather than adding to it, and only one of the two is ever read. ## Failure is silent by design If the named file does not exist, or exists but is not readable, JMeter skips it. There is no error, the run continues, and `${__P(base.url,http://localhost:8080)}` quietly returns its default. When a run behaves as though your overrides were never applied, the first two things to check are which directory the process actually started in and whether the file is readable at all — the JMeter log records the resolved path of each property file it did load, which settles the question quickly.

  • Why does the JMeter project recommend editing user.properties rather than jmeter.properties?
    Because user.properties is merged in after jmeter.properties and overwrites it, so every override lives in one small file. Upgrading the distribution replaces the stock jmeter.properties, and keeping your changes out of it means the upgrade cannot discard them.
  • You launch JMeter from a directory that also contains a user.properties. Which file is read?
    The one in your working directory. JMeterUtils.findFile tries the name as given before falling back to JMeter's bin directory, so a local copy shadows bin/user.properties completely rather than adding to it. Only one of the two is ever loaded.
  • What happens if the file named by the user.properties key does not exist?
    Nothing visible. JMeter checks that the resolved file is readable and simply skips it otherwise, with no error and no failed startup. The run proceeds with whatever jmeter.properties established, which is why a missing overrides file looks like overrides that were ignored.

saying these in an interview costs you the question

  • Thinks user.properties is a hard-coded filename JMeter always knows
  • Says jmeter.properties overrides user.properties because it loads first
  • Expects JMeter to fail loudly when a named property file is missing
  • Assumes property files are only ever read from the bin directory
  • Believes system.properties entries land in JMeter's own property map