In JMeter, what changes in a run when you set beanshell.sampler.init?
answer
- Seven similar keys sit in one properties block
- None are set out of the box
- It affects more than a sourced file
- Look at what gates the lifecycle callbacks
basics
~20 sThe named file is sourced into every BeanShell Sampler interpreter as it is built, so once per element per thread. Setting it also switches on the element's threadStarted, threadFinished, testStarted and testEnded script callbacks, which are otherwise never dispatched.
solid answer
~40 s`beanshell.sampler.init` is one of seven BeanShell init properties in `bin/jmeter.properties` — six per-element, one (`beanshell.function.init`) for the `__BeanShell` function — and all seven ship commented out. When it is set, `BeanShellInterpreter.init()` sources that file into the interpreter it has just built — trying the path as given, then `<JMETER_HOME>/bin/` — and only logs a warning if it cannot find, read or source it. Because `init()` runs from the element's constructor and from `clone()`, the cost is one source per element per thread at ramp-up; with **Reset bsh.Interpreter before each call** ticked it becomes one per invocation. The less obvious effect is that `BeanShellTestElement` guards its `ThreadListener` and `TestStateListener` dispatch on whether an init file exists, so `threadStarted()` and `testEnded()` in your script only ever run when the property is set.
code
properties · 12 lines# bin/jmeter.properties - all seven ship commented out
#beanshell.sampler.init=BeanShellSampler.bshrc
#beanshell.function.init=BeanShellFunction.bshrc
#beanshell.assertion.init=BeanShellAssertion.bshrc
#beanshell.listener.init=etc
#beanshell.postprocessor.init=etc
#beanshell.preprocessor.init=etc
#beanshell.timer.init=etc
# separate keys in the same block, tied to no element or function:
#beanshell.init.file=
beanshell.server.file=../extras/startup.bshgo deeper
Know that JMeter ships sample .bshrc files in bin/ and that none of them load unless you set the matching init property yourself.
Explain when the file is sourced: inside the interpreter constructor, so once per element per thread, and once per call if the reset option is also ticked.
Recognise the two operational consequences: a mistyped path only warns, and the thread and test lifecycle callbacks are gated on the property rather than on the script.
Judge whether shared helper definitions in a .bshrc are worth the hidden coupling they create between a plan and one injector's properties file, especially across a distributed run.
## The property and the file it names `bin/jmeter.properties` ships a BeanShell block with seven init properties, and **all seven are commented out** — one per BeanShell element, plus `beanshell.function.init` for the `__BeanShell` function, which is sourced once per occurrence of the call rather than once per element per thread: - `beanshell.sampler.init` - `beanshell.function.init` - `beanshell.assertion.init` - `beanshell.listener.init` - `beanshell.postprocessor.init` - `beanshell.preprocessor.init` - `beanshell.timer.init` Setting one names a file that is sourced into that element type's interpreter — or, for the function, into the function's own interpreter — when the interpreter is constructed. JMeter ships four samples in `bin/`: `BeanShellSampler.bshrc`, `BeanShellFunction.bshrc`, `BeanShellAssertion.bshrc` and `BeanShellListeners.bshrc`. The first three define small helpers such as `getprop` and `setprop`; the last defines listener callbacks. Resolution is forgiving. `BeanShellInterpreter.init()` tries the path as given, and if that does not exist retries it under `<JMETER_HOME>/bin/`. If it still cannot find, read or source the file, it logs a warning — `Cannot find init file:`, `Cannot read init file:` or `Cannot source init file:` — and the run continues with an interpreter that simply lacks those definitions. A typo here does not fail the test; it produces a script error later, in a different place. ## What it adds to the run Two costs, both easy to miss: 1. **Per element, per thread, at clone time.** The interpreter is built in `init()`, which is called from the constructor and from `clone()`. Every thread's copy of every BeanShell element sources the file as the thread starts. 2. **Per call, if you also tick Reset.** `reset()` re-runs `init()`, so the init file is re-sourced on every invocation, not just once per thread. ## The part almost nobody knows: the lifecycle callbacks `BeanShellTestElement` implements `ThreadListener` and `TestStateListener`, and it forwards those events into the script as `threadStarted()`, `threadFinished()`, `testStarted()` and `testEnded()`. `BeanShellListeners.bshrc` exists precisely to show how to define them. But both dispatch helpers, `tryEval` and `tryEvalNoLog`, begin with the same guard: if there is no init file, return immediately. `hasInitFile` is set once in `init()` from whether the element's init property is defined at all. So the callbacks are gated on the property, not on the script. Defining `threadStarted()` in the element's own **Script** field does nothing — the field is only evaluated on invocation. The callbacks fire only when the element type's `beanshell.*.init` property points at a file, and since every one of them ships commented out, a stock JMeter installation never fires any of them. ## Two neighbours in the same block Do not confuse the six per-element properties with `beanshell.function.init`, which belongs to the shared `__BeanShell` function, or with the other two keys in that section: `beanshell.init.file` runs a script once at JMeter startup **in its own interpreter**, and `beanshell.server.port` / `beanshell.server.file` control the BeanShell server rather than any test element.
- What happens if beanshell.sampler.init names a file that does not exist?The run continues. `BeanShellInterpreter.init()` tries the path as given, retries it under `<JMETER_HOME>/bin/`, and if it still fails logs `Cannot find init file:` or `Cannot source init file:`. The interpreter is built without those definitions, so the failure surfaces later as a script error in an unrelated place rather than as a startup failure.
- Why does defining threadStarted() in the element's own Script field not work?The Script field is only evaluated when the element is invoked. The lifecycle callbacks are dispatched separately by `BeanShellTestElement`, whose `tryEval` helpers return immediately unless the element type's init property is set. The definitions have to be in the sourced init file, which is what `BeanShellListeners.bshrc` demonstrates.
saying these in an interview costs you the question
- Assuming a .bshrc is loaded by default without setting a property
- Confusing beanshell.init.file with the per-element init properties
- Expecting a missing init file to fail the run at startup
- Thinking the init file is sourced once per JVM rather than per element per thread
- Defining lifecycle callbacks in the Script field instead of the init file