Which JMeter element types come in a JSR223 variant?
answer
- Same base class, different plan slots
- Count the slots a script can fill
- One is a sampler, one a timer
- Six variants in JMeter 6.0.0
basics
~20 sApache JMeter 6.0.0 ships six: JSR223 Sampler, JSR223 PreProcessor, JSR223 PostProcessor, JSR223 Assertion, JSR223 Timer and JSR223 Listener. All six extend one base class, so they share the same configuration fields and one process-wide compiled-script cache; each invocation still gets a fresh ScriptEngine from JMeter's single ScriptEngineManager.
solid answer
~40 sJMeter exposes one JSR-223 scripting engine through six separate elements, each occupying a different slot in a test plan: **JSR223 Sampler**, **JSR223 PreProcessor**, **JSR223 PostProcessor**, **JSR223 Assertion**, **JSR223 Timer** and **JSR223 Listener**. All six extend the same `JSR223TestElement` base class, so the GUI is identical: `Language`, `Parameters`, a `Script File` field whose group is labelled *Script file (overrides script)*, the `Cache compiled script if available` checkbox, and the inline `Script` area. Leave `Language` blank and you get Groovy, the bundled default engine. What differs between the six is the slot each fills and what JMeter does with the value the script returns — the Timer parses it as a delay in milliseconds and the Sampler turns it into response data, while the PreProcessor, PostProcessor and Listener discard it.
go deeper
Be able to name the JSR223 variants and say that the Language field falls back to Groovy. Knowing that a sampler produces its own result row while a pre-processor does not is enough here.
Explain that all six extend one base class and share the same fields, and that only the Sampler and the Timer do anything with the value a script returns.
Show that you choose the variant by the slot you need, and know where a script error becomes visible in the results and where it only reaches jmeter.log.
Own the convention: which variants a team may use at all, what is allowed to live in a script, and how a script failure is made visible instead of being left in a log file nobody reads.
## One engine, six sockets Apache JMeter 6.0.0 bundles Groovy as its default JSR-223 engine and offers it through six test elements. Every one of them extends `org.apache.jmeter.util.JSR223TestElement`, which is why the configuration surface is identical in all six: - **Language** — the short name of a `ScriptEngine` on the classpath. The drop-down is built at startup from the engine factories JMeter can see, so it is not a fixed list; the manual notes that a language can be usable without appearing there if its jar is dropped into `lib/`. - **Parameters** — free text handed to the script. - **Script File** — a path. The GUI group is labelled *Script file (overrides script)* and that is literal: a non-empty path makes JMeter ignore the inline `Script` area entirely. A relative path resolves against the `user.dir` system property. - **Cache compiled script if available** — the compilation-cache switch. - **Script** — the inline source. Leave **Language** blank and the base class falls back to the string `groovy`. Name an engine JMeter cannot resolve and the element throws `Cannot find engine named: '<name>'`. ## What each variant is for | Element | Slot it fills | What JMeter does with the return value | |---|---|---| | JSR223 Sampler | a sampler, producing its own `SampleResult` | becomes the response data, unless the script already set one | | JSR223 PreProcessor | a pre-processor | discarded | | JSR223 PostProcessor | a post-processor | discarded | | JSR223 Assertion | an assertion, handed an `AssertionResult` to mark | discarded — you mark the `AssertionResult` instead | | JSR223 Timer | a timer | parsed with `Long.parseLong` and used as a delay in milliseconds | | JSR223 Listener | a sample listener | discarded | The Timer shows most sharply why the variants are not interchangeable. `JSR223Timer.delay()` calls `Long.parseLong` on the returned object's `toString()`; a `null` return logs *Script did not return a value* and yields `0`, and a non-numeric return raises a `NumberFormatException` that is logged and also yields `0`. The Sampler is the only variant that manufactures a result of its own. It labels the result with the element name, records the script text (or `File: <path>`) as the sampler data, and copies the script's return value into the response data if the script has not already set one. ## Where a script error surfaces The six do not agree on this, and the difference matters when you are reading a run afterwards: 1. **JSR223 Sampler** — a `ScriptException` or `IOException` is caught, the result is marked unsuccessful, the response code is set to `500` and the response message is the exception's text. 2. **JSR223 Assertion** — the `AssertionResult` is flagged as an error and carries the exception text as its failure message. 3. **JSR223 PreProcessor, PostProcessor and Listener** — the exception is only logged, as `Problem in JSR223 element named: '<name>'`, and the thread carries on. 4. **JSR223 Timer** — problems are logged and the delay collapses to zero. So a broken script inside a Sampler is loud, and the same broken script inside a PreProcessor is quiet. ## What one looks like in the plan file All six serialise to the same five properties; only the element name changes: ```xml <JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="Sign request" enabled="true"> <stringProp name="cacheKey">true</stringProp> <stringProp name="filename"></stringProp> <stringProp name="parameters"></stringProp> <stringProp name="script">vars.put("nonce", UUID.randomUUID().toString())</stringProp> <stringProp name="scriptLanguage">groovy</stringProp> </JSR223PreProcessor> ``` ## Picking the right one Reach for the variant whose slot you actually need rather than defaulting to the Sampler. A signature that must exist before a request goes out belongs in a JSR223 PreProcessor attached to that request; a value that must be pulled out of a reply belongs in a JSR223 PostProcessor; a computed pause belongs in a JSR223 Timer, which is the only variant whose return value becomes a delay. Using a JSR223 Sampler for work that is not itself a request adds a result row you then have to explain, unless the script calls `SampleResult.setIgnore()` to keep it out of listeners and later processing.
- In JMeter, what happens if a JSR223 element has both a Script File path and inline Script text?The file wins. `processFileOrScript` tests the file name first, and the GUI group is labelled *Script file (overrides script)*. The inline text is never evaluated. If the path is not an existing readable file the element throws a `ScriptException` naming the absolute path rather than quietly falling back to the inline script.
- What does a JMeter JSR223 Timer do when its script returns something that is not a number?`JSR223Timer.delay()` calls `Long.parseLong` on the returned object's `toString()`. A `null` return logs *Script did not return a value* and produces a zero delay; a non-numeric value raises a `NumberFormatException` that is logged and also produces zero. Either way the thread does not pause and the run continues.
saying these in an interview costs you the question
- Says JSR223 exists only as a sampler
- Thinks each variant has its own scripting subsystem or its own set of configuration fields
- Expects a PreProcessor's return value to be used
- Assumes Script File is only a fallback for the inline script
- Believes the Language field must always be filled in