In JMeter, how do the search_paths, user.classpath and plugin_dependency_paths properties differ?
answer
- Three properties, all shipped commented out
- One extends plugins, two extend dependencies
- Only one of the three is scanned, not just loaded
- The separator is not the same throughout
basics
~10 ssearch_paths adds directories JMeter scans for plugin components, alongside lib/ext. user.classpath and plugin_dependency_paths add directories of dependency jars alongside lib; user.classpath also joins the system classpath, plugin_dependency_paths reaches JMeter's own loader only.
solid answer
~60 sAll three live in `bin/jmeter.properties`, all three are shipped commented out, and all three name **path items**: each entry is either a directory, whose `.jar` files are then added automatically, or a single `.jar` file added on its own. What none of them do is recurse - jars in sub-directories are ignored. `search_paths` extends the component search path: its directories are searched for plugin classes *in addition to* `lib/ext`. `user.classpath` and `plugin_dependency_paths` both extend the dependency path *in addition to* `lib`. The difference between those two is reach: entries from `search_paths` and `user.classpath` are added to JMeter's loader **and** appended to the `java.class.path` system property, while `plugin_dependency_paths` entries reach JMeter's internal loader only - which is why the properties file tells you to prefer `plugin_dependency_paths` for plugin dependencies. Scanning is decided separately and by neither flag: JMeter's class finder walks exactly `JMeterUtils.getSearchPaths()`, which is `lib/ext` followed by the `search_paths` entries and nothing else, so a `user.classpath` directory is loadable but is never scanned for components. Separators differ too: `search_paths` and `plugin_dependency_paths` split on `;`, `user.classpath` on the platform path separator.
go deeper
Know that these three properties exist so plugin and dependency jars can live outside the JMeter installation, and that each entry is a path item - a directory whose jars are picked up automatically, or a single jar file.
Explain the split: search_paths extends the plugin search path beside lib/ext, while user.classpath and plugin_dependency_paths extend the dependency path beside lib.
Demonstrate reading the startup log to tell 'Adding to classpath and loader' from 'Adding to loader', and diagnosing a silently skipped path from a separator or typo.
Decide whether injectors get a fixed installation with vendored jars or a properties-driven layout per project, and who owns the resulting startup cost and reproducibility.
In Apache JMeter 6.0.0 the shipped directories `lib` and `lib/ext` cover the ordinary case, but plenty of teams cannot write into the JMeter installation at all - it is baked into a container image, owned by another team, or shared between projects that need different plugin sets. Three properties in `bin/jmeter.properties` exist for that, and they are not interchangeable. ## What each one is for - **`search_paths`** - "List of directories to search for additional JMeter plugin classes, for example new GUI elements and samplers." Its value is *in addition to* any jars found in `lib/ext`. The properties file adds a warning: do not use this for utility or plugin dependency jars. - **`user.classpath`** - directories JMeter searches for utility and plugin dependency classes, *in addition to* any jars found in `lib`. All entries are added to the class path of the system class loader **and** to the path of JMeter's internal loader. - **`plugin_dependency_paths`** - the same purpose as `user.classpath`, but all entries are added to the path of the JMeter internal loader **only**. The file states outright that for plugin dependencies this property should be used instead of `user.classpath`. ## The mechanism behind the difference JMeter calls a small helper once per property at startup. Two of them take a flag meaning "also put this on the system classpath": 1. `search_paths` is processed with that flag **on**. 2. `user.classpath` is processed with that flag **on**. 3. `plugin_dependency_paths` is processed with that flag **off**. When the flag is on, the entry itself, plus each `.jar` inside it when it is a directory, is added to JMeter's dynamic loader *and* appended to the `java.class.path` system property; when it is off, only the loader is touched. What the flag does **not** decide is scanning. `ClassFinder` never reads `java.class.path` - it walks exactly the array it is handed, and for JMeter components that array is `JMeterUtils.getSearchPaths()`: `JMETER_HOME/lib/ext` followed by the `search_paths` entries. So `search_paths` is scanned because `getSearchPaths()` names it, while `user.classpath`, flag on though it is, is loaded but never scanned - `NewDriver`'s own "ClassFinder needs this" comment beside the append is a leftover from a much older release, so do not take it at face value. All the flag still buys is a place on the classpath *string* for the handful of things that inspect it, which is narrow; a dependency jar needs neither that nor the scan, which is exactly why the properties file steers plugin dependencies to `plugin_dependency_paths`. | Property | Adds to | Scanned for components | Separator | In addition to | |---|---|---|---|---| | `search_paths` | loader + system classpath | yes | `;` | `lib/ext` | | `user.classpath` | loader + system classpath | no | platform path separator | `lib` | | `plugin_dependency_paths` | JMeter loader only | no | `;` | `lib` | ## Details that decide whether it works - **A directory or a single jar.** The manual says of all three that "a path item can either be a jar file or a directory". Name a directory and any `.jar` directly inside it is included automatically; name one jar file and just that jar is added. Either way there is no recursion - jars in sub-directories are ignored, exactly as for `lib` and `lib/ext`. - **Unreadable entries are warnings, not errors.** A path that is neither readable nor a directory is logged as a warning and skipped, so a typo produces a plugin that is simply absent rather than a failed startup. Check the log for the `search_paths=` / `user.classpath=` line JMeter prints back, and for `Adding to classpath and loader:` versus `Adding to loader:`. - **The separator really is `;` for two of them.** `search_paths` and `plugin_dependency_paths` are split on a literal semicolon on every platform, while `user.classpath` is split on the platform path separator - a colon on Linux and macOS. Writing a colon-separated `search_paths` on Linux yields one long nonsense path. - **Spaces in paths may cause problems for the JVM**, which the properties file warns about directly. - **They are all unset by default.** Every one of the three is commented out in the shipped `bin/jmeter.properties`, so nothing changes until you set it, typically in `user.properties` rather than by editing the shipped file. ## Choosing between them Use `search_paths` when the plugin JARs themselves live outside the installation - a per-project directory of vendored plugins, for instance. Use `plugin_dependency_paths` for the libraries those plugins need, so JMeter can load them without putting them on the system class loader as well. Reach for `user.classpath` only when something genuinely needs the jars on the system class loader as well, which is the narrower case; the JUnit Request sampler's class chooser, for example, reads `user.classpath` explicitly when it looks for test classes. Whatever you choose, set it in `user.properties` or pass it with a property flag rather than editing the shipped `jmeter.properties`, so the next JMeter upgrade does not quietly discard it.
- Why does the properties file tell you to prefer plugin_dependency_paths over user.classpath for plugin dependencies?Because `user.classpath` entries are also pushed onto the system class path, while `plugin_dependency_paths` entries reach JMeter's internal loader alone. A plugin's dependency only has to resolve inside JMeter, so the narrower loader gives identical class resolution without widening what the rest of the JVM can see - which is exactly the reason `bin/jmeter.properties` says to use `plugin_dependency_paths` instead of `user.classpath` for plugin dependencies. Note that neither property is scanned for JMeter components: the class finder walks `lib/ext` plus `search_paths` only.
- Where should you set these properties so a JMeter upgrade does not lose them?In `bin/user.properties`, which JMeter loads after `jmeter.properties`, or on the command line. Editing the shipped `jmeter.properties` works but the file is replaced by the next installation, so any local edits have to be re-applied by hand.
- A search_paths value written with colons on Linux finds nothing. Why?`search_paths` is split on a literal semicolon on every platform, not on the platform path separator, so a colon-separated value is read as a single path name that does not exist. JMeter logs it as unreadable and moves on. Only `user.classpath` uses the platform path separator.
Think of a workshop. The tool rack by the door is walked past and inventoried every morning, so anything on it gets noticed; the parts bins at the back are only opened when a job asks for a part. search_paths adds another rack to the morning walk; user.classpath and plugin_dependency_paths add parts bins, the first of them shared with the rest of the workshop.
saying these in an interview costs you the question
- Treats the three properties as interchangeable aliases
- Thinks the entries are read per test run rather than once at startup
- Assumes every entry is scanned for JMeter components
- Uses the platform path separator for search_paths everywhere
- Expects jars in sub-directories of an entry to be picked up