Your order pipeline uses a protocol no stock JMeter sampler speaks. How would you decide how to drive it?
answer
- Check what is missing before writing anything
- Reuse a hook the tool already owns
- Compiled code must reach every machine
- The sample result is the only output
basics
~20 sWork outward from the cheapest hook. A pluggable TCPClient class, a Java Request client class, a scripted sampler and a third-party plugin all reach the protocol. They differ in who maintains the code and how it reaches every injector.
solid answer
~50 sJMeter's shipped sampler list is fixed: HTTP with its AJP and GraphQL variants, FTP, JDBC, LDAP, SMTP and Mail Reader, TCP, the three JMS elements, OS Process, Bolt, JUnit, Java Request and the scripting samplers. When a protocol falls outside it there are four hooks, and the choice is an ownership decision more than a technical one: - a **custom TCPClient class** named on the TCP Sampler, if the protocol is a framing problem over a socket JMeter already manages; - a **Java Request** client class implementing `org.apache.jmeter.protocol.java.sampler.JavaSamplerClient`, compiled and dropped on the classpath; - a **scripted sampler**, which keeps the code inside the `.jmx`; - a **third-party plugin**, which puts the protocol on someone else's release cadence. Whatever you pick must fill in a sample result honestly — label, timings, success flag, response code — because every listener, assertion and report downstream reads that and nothing else.
go deeper
Recall that JMeter ships a fixed list of samplers and that anything outside it needs an extension point rather than a configuration setting.
Explain the hooks by name - a custom TCPClient, a JavaSamplerClient class, a scripted sampler, a third-party plugin - and what each one requires to be present at run time.
Show that you weigh distribution and review, not only feasibility: a compiled JAR must reach every engine, and code inside a .jmx is reviewed as XML.
Own the call and its aftermath: which transports justify a maintained internal library, how injector images are versioned, and when to retire your class for an official client.
Sooner or later an order pipeline moves onto a transport that JMeter has no element for. The temptation is to reach straight for a script because it is the fastest thing to demonstrate. That is a decision about who owns a piece of production tooling for the next three years, and it deserves to be made deliberately. ## Establish what is actually missing First check whether the gap is the *protocol* or only the *framing*. The TCP Sampler already owns connection reuse, timeouts, socket options and result handling; it delegates only the question of where a message ends to a handler class named in **TCPClient classname**. If your protocol is bytes over a socket with an unusual frame, implementing `org.apache.jmeter.protocol.tcp.sampler.TCPClient` is a fraction of the work of a sampler and inherits everything else. Likewise, a protocol with a JMS or Bolt binding is already covered. Only when none of that applies is the gap real. ## The four hooks, and what each one costs | Hook | What you write | What it costs | |---|---|---| | Custom `TCPClient` | one small class | a JAR on every injector; framing only | | **Java Request** client | a class implementing `JavaSamplerClient` | a JAR on every injector; full control | | Scripted sampler | code inside the `.jmx` | reviews badly, ships with the plan | | Third-party plugin | nothing | someone else's roadmap and Java support | The trade-offs that actually decide it: 1. **Who reviews it.** A compiled class lives in a repository with a build, tests and a diff a reviewer can read. Code inside a `.jmx` is reviewed as XML, if at all. 2. **How it reaches the machines.** Compiled options need the JAR in `lib` on the controller *and* every remote engine, because a distributed run replicates the plan, not the classpath. Scripted code travels inside the plan for free — that is the one genuine advantage, and on a fleet you do not control it is a large one. 3. **Who fixes it when the client library moves.** A third-party plugin removes today's work and adds a standing dependency on another project's release cadence and Java-version support. That is a fine trade for a well-known add-on and a bad one for a protocol only your organisation speaks. 4. **How long the code lives.** A one-off spike does not deserve a repository. A transport carrying your main revenue path does. ## The obligation nothing exempts you from Whichever hook you use, the sampler is the only thing that decides what your results *say*. It must set a stable label, start and end the timing around the real network work, set the success flag from a real check rather than from "no exception was thrown", set a response code, and record the bytes. It also has to be safe to run from many threads at once, since JMeter will call it concurrently. Get that wrong and the run is not merely inaccurate — it is confidently wrong, which is worse, because the dashboard, the assertions and the pass rule all read the sample result and have no other source of truth. Two smaller obligations follow: errors must surface as failed samples rather than as log lines, and anything expensive — a client, a connection pool, a parsed schema — should be built once per thread rather than per sample, or the injector's own cost swamps the measurement. ## Deciding, in practice - Prototype in the scripted sampler to prove the protocol is reachable at all. Treat it as a spike, not the answer. - If the transport is strategic and long-lived, promote it to a compiled class with its own build and tests, and version the JAR the way you version any other internal library. - Prefer extending a hook JMeter already owns — a `TCPClient` over a whole sampler — because everything you do not write is something you do not maintain. - Write down which injector image carries which version of the JAR, because the failure mode of getting that wrong is a run that produces plausible numbers on the wrong code. - Revisit the decision when the protocol gets an official client, and be willing to throw your class away. The failure to avoid is the middle state: a script pasted into three plans, edited differently in each, that nobody owns and nobody can reproduce.
- Which interface must a Java Request client class implement, and where must the JAR go?`org.apache.jmeter.protocol.java.sampler.JavaSamplerClient`, usually by extending `AbstractJavaSamplerClient`. The class has to be on JMeter's classpath before the GUI's **Classname** dropdown can list it, which means a JAR in the installation's directories and a restart — on every machine that will run the plan, controller and remote engines alike.
- Why is extending the TCP Sampler often cheaper than writing a new sampler?Because the TCP Sampler already owns the socket lifecycle: connect and response timeouts, connection reuse keyed on host and port, `SO_LINGER`, Nagle, closing on error, and building the sample result. A custom `TCPClient` supplies only the write and read framing, so the amount of code you own — and can get wrong — is a fraction of a full sampler.
- What should a custom sampler set on its sample result for a run to be trustworthy?A stable label, timings started and ended around the real work, a success flag derived from an actual check of the response, a response code and message, and the byte counts. Listeners, assertions, the dashboard and any pass rule read only the sample result, so a sampler that reports success whenever no exception was thrown makes the whole run confidently wrong.
saying these in an interview costs you the question
- Reaching for a script without checking existing hooks first
- Assuming a distributed run ships JARs to remote engines
- Marking a sample successful whenever no exception was thrown
- Building an expensive client once per sample
- Adopting a plugin for a protocol only your team speaks