In Cucumber-JVM, what does the glue option point at, and what happens when it is wrong?
answer
- Two things share the name glue
- It is a package, not a path
- The scan reaches subpackages too
- Uniform failure means configuration, local means code
- A hook outside the scan never fires
basics
~20 sThe glue option lists package names that Cucumber scans recursively for step definitions and hooks — packages, never file paths. Point it at the wrong package and every step of every scenario reports undefined, not just one line.
solid answer
~50 s`cucumber.glue` — the `--glue` argument on the command-line runner, the `glue` element of the JUnit 4 options annotation — is a comma-separated list of **package names**. Cucumber loads the classes in those packages and their subpackages and registers the methods carrying step-definition and hook annotations; type registrations are picked up in the same scan. Two failures then look alike and are not. A wrong or missing glue package makes *every* step of *every* scenario undefined and prints a suggested snippet for each distinct step: a uniform wall of undefined steps is a configuration symptom, not a coding gap. A genuinely missing step definition is local — the steps above it pass, that one line is undefined, and the rest of the scenario is skipped. The quiet variant is worse: a hook class outside the glue never runs, so setup silently does not happen.
code
java · 7 lines// wrong: a source folder path is not a package name
@ConfigurationParameter(key = GLUE_PROPERTY_NAME,
value = "src/test/java/com/vinylmarket/steps")
// right: packages, comma separated, each scanned recursively
@ConfigurationParameter(key = GLUE_PROPERTY_NAME,
value = "com.vinylmarket.steps,com.vinylmarket.hooks")go deeper
Be able to say that the glue option takes package names, that the scan includes subpackages, and that the feature path and the glue package are two different values. That is the everyday knowledge here.
Explain the diagnostic difference between a wrong glue path and a genuinely missing step definition, and why an unregistered hook fails silently rather than loudly.
Show how you keep an uncheckable string safe in a real repository: a narrow dedicated package, one place that sets the option, and a dry-run stage that turns a misconfiguration into a fast build failure.
Own the layout convention across teams so that glue paths stay narrow, and decide whether step definitions may be shared between suites at all — the wide glue path that makes sharing easy is the same one that couples teams together.
## Two meanings of one word "Glue" is overloaded in Cucumber-JVM, and interviews exploit it. It means (a) the step-definition and hook **code** that binds Gherkin lines to Java, and (b) the **option** that tells Cucumber where that code lives. This question is about the option. Its value is a package name, and everything confusing about it follows from the fact that a package name is just a string: the compiler cannot check it, a refactor will not rename it, and a typo produces a run that works perfectly and finds nothing. You set it in whichever place your entry point uses — `@ConfigurationParameter` with the glue key on a JUnit Platform suite, `--glue` on the command-line runner, the `glue` element on the JUnit 4 or TestNG options annotation, or the `cucumber.glue` key in a properties file. Multiple packages are comma-separated. ## What the scan actually collects Cucumber loads every class in each listed package **and all its subpackages**, then registers: - methods annotated with step keywords, such as the `@Given`, `@When` and `@Then` annotations of the English language package; - hook methods — `@Before`, `@After`, `@BeforeStep`, `@AfterStep`, `@BeforeAll`, `@AfterAll`; - parameter-type and data-table type registrations declared in those classes; - the classes themselves as candidates for instantiation, with the dependency-injection container chosen separately. Note what is *not* in that list: feature files. The glue option and the feature selector are two different values pointing at two different things, and mirroring your package layout in `src/test/resources` makes them look deceptively alike. ## Wrong glue versus a genuinely undefined step This is the diagnostic that separates someone who has run Cucumber from someone who has read about it. | Symptom | Wrong glue path | Missing step definition | |---|---|---| | Scope | every step of every scenario | one step line | | Steps before it | also undefined | pass normally | | Steps after it | undefined | skipped | | Suggested snippets | one per distinct step in the whole run | one | | Fix | correct the package or the classpath | write the definition | A run where the first `Given` of a scenario is undefined while nothing else in the run is defined either is a configuration failure. A run where two scenarios pass and a third has one undefined line is a genuine gap. Reading that difference off the summary saves half an hour of poking at expressions that were never the problem. ## The six ways it goes wrong 1. **A source path instead of a package.** `src/test/java/com/vinylmarket/steps` is a directory; `com.vinylmarket.steps` is the package. Only the second is a legal glue value. 2. **Code in another module.** The glue package is spelled correctly but the module holding it is not a test dependency, so nothing is on the classpath to scan. 3. **A rename that missed the string.** Someone moves the step classes; the IDE updates every import and leaves the glue string pointing at a package that no longer exists. 4. **Glue too wide.** Pointing at a parent package pulls in another team's definitions, which is how a suite acquires duplicate matches — the step-definition side of that is its own topic, but the *cause* is often an over-broad glue path. 5. **Hooks outside the glue.** A `@Before` that starts a session and lives one package outside the scan simply never fires. There is no error, only a null reference a few steps later. 6. **Relying on a default.** Whatever a given entry point falls back to when the option is unset, depending on it couples your step layout to where the runner class happens to sit. Set it explicitly. ## Keeping it honest A few conventions remove almost all of this: - keep step definitions and hooks in one dedicated package tree, and point glue at its root; - set the option in exactly one place per entry point, so nobody has to work out which layer won; - keep the glue package narrower than the package holding unrelated test helpers; - run the suite with Cucumber's dry-run option in CI, which walks discovery and matching without executing step bodies, so a broken glue path fails fast and loudly instead of surfacing as a wall of undefined steps in a nightly run. The last one is the habit worth naming in an interview. Dry run turns a configuration mistake into a build failure that takes seconds, which is exactly the treatment a string the compiler cannot check deserves.
- Your @Before hook never runs, but every step passes. What is happening?The hook class sits outside every configured glue package, so Cucumber never registered it. Nothing reports an error, because an unregistered hook is indistinguishable from no hook at all. Either move the class under the glue root or add its package to the option — and prefer the first, so one package tree holds all the glue.
- Why not point the glue option at a broad parent package to be safe?Because the scan is recursive and takes everything it finds. A wide glue path pulls in step definitions from unrelated suites, which slows discovery, couples two teams' code, and is a common cause of a step suddenly matching more than one definition. Narrow glue is a boundary, and it should be as tight as the layout allows.
- How do you catch a broken glue path before a nightly run does?Run the suite with Cucumber's dry-run option in the pipeline. Discovery and step matching still run, step bodies do not, so a glue path pointing nowhere shows up as undefined steps in seconds rather than as a failed nightly. It costs almost nothing and guards a string the compiler cannot check.
The glue option is an address book, not the code itself. Give Cucumber the wrong street and the problem is not that nobody is home; it is that it never went to the right street.
saying these in an interview costs you the question
- Gives the glue option a source folder path
- Thinks the glue value names the feature files
- Treats a wall of undefined steps as missing step definitions
- Points glue at a broad parent package for safety
- Assumes hooks are found wherever they are written