Skip to content

Register and filter glue classes - #3120

Merged
mpkorstanje merged 46 commits into
mainfrom
feature/manual-glue-class-registration
Sep 2, 2026
Merged

mpkorstanje merged 46 commits into
mainfrom
feature/manual-glue-class-registration

Conversation

@mpkorstanje

@mpkorstanje mpkorstanje commented Nov 25, 2025 •

Copy link
Copy Markdown
Member

🤔 What's changed?

Adds supports for registering individual glue classes via the cucumber.glue.classes property or the --glue-classes CLI option.

Additionally, supports filtering glue classes by name when scanning the class-path via the cucumber.glue.{included,excluded}-class-name-pattern properties and --glue-{included,excluded}-class-name-pattern CLI options.

Only classes that are included by one of the include patterns and not excluded by any of the exclude patterns will be loaded during classpath scanning. This should speed up Cucumber significantly. The filters are not applied against classes that registered explicitly.

No include pattern is configured by default. Cucumber-JVM has been around for 14 years now and it would be quite complicated for existing implementations to either rename their glue classes to fit the existing pattern, or work out a pattern that matches existing classes.

To facilitate registering and filtering glue classes the Backend now has a new loadGlue(Glue glue, GlueDiscoveryRequest request) method. With the GlueDiscoveryRequest containing a collection of what exactly should be discovered. Currently only classes and URIs are supported but this can be trivially expanded to include packages, modules, ect.

⚡️ What's your motivation?

Closes: #3118
Closes: #3137

🏷️ What kind of change is this?

  • ⚡ New feature (non-breaking change which adds new behaviour)

📋 Checklist:

  • I agree to respect and uphold the Cucumber Community Code of Conduct
  • I've changed the behaviour of the code
    • I have added/updated tests to cover my changes.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.
  • Users should know about my change
    • I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.

@mpkorstanje
mpkorstanje force-pushed the feature/manual-glue-class-registration branch from b03dd28 to c3ddc6f Compare December 18, 2025 14:29
@mpkorstanje mpkorstanje added this to the v7.x.x milestone Dec 28, 2025
@mpkorstanje mpkorstanje modified the milestones: v7.x.x, v8.0.0 Feb 1, 2026
@mpkorstanje
mpkorstanje force-pushed the feature/manual-glue-class-registration branch from 31fe2f4 to be1b4dd Compare March 18, 2026 13:14
@jkronegg

jkronegg commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Regarding ChatGPT divination: I would not buy the list and frequency as-is, of course. We all know that the provided patterns and frequencies are invented, but it's a plausible answer, potentially correct, but potentially wrong.
But it's the same when I wrote "Thus *StepDefinitions or *StepDefs would be okay.": it's a plausible answer, potentially correct, but potentially wrong. 😁😉

@mpkorstanje

Copy link
Copy Markdown
Member Author

Ah. I see. I was hoping you'd have a codebase you could grep through for glue class names. Or really anything that contains io.cucumber and provide a summary based of that.

@jkronegg

jkronegg commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

I built a Python script to build the frequency based on GitHub Search results (with GitHub Copilot help). These are the results:

 Other                  437  ( 43.7%)
 Steps                  329  ( 32.9%)
 StepDefinitions         61  (  6.1%)
 StepDef                 48  (  4.8%)
 StepDefs                43  (  4.3%)
 StepDefinition          37  (  3.7%)
 Step                    33  (  3.3%)
 Definitions              8  (  0.8%)
 StepsDefinitions         3  (  0.3%)
 Glue                     1  (  0.1%)

So to summarize:

  • Variant of Step and plurals total about 36%
  • Variants of StepDefinition and plurals total about 10%.
  • Variants of StepDef and plurals total about 9%
  • Definitions is about 1%

Note that these figures are sorted the same as the "hallucinated" ChatGPT answer. Maybe by chance? (or is this a confirmation biais?)

Limitations:

  • max 1000 results on the search API, so it's not very significative
  • the repos quality is not guaranteed

See source code
detectpatterns.py

When working on the repos from Cucumber user only, the results are a bit different:

StepDefinitions         23  ( 33.3%)
Steps                   21  ( 30.4%)
Other                   20  ( 29.0%)
StepDefs                 4  (  5.8%)
StepDef                  1  (  1.4%)

To pass the 1000 result limit, Copilot suggests to aggregate the result on a list of reference repos (which also guarantee the result quality). But then which repos need to be chosen?

So in the end, you end up with true number (not hallucinations), but still biased by the repos that are selected by you or by GitHub Search.... Thus I don't know whether we are in a better position or not to decide...😅

@mpkorstanje

mpkorstanje commented Aug 1, 2026 •

Copy link
Copy Markdown
Member Author

But then which repos need to be chosen?

Ideally? The ones you contribute to. Don't you have work repo's you can query? 😄

@laeubi

laeubi commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

But then which repos need to be chosen?

Ideally? The ones you contribute to. Don't you have work repo's you can query? 😄

I think in the end one should choose whats reasonable / workable ... trying to fit everyone's need will likely fail and it is the projects privilege to decide and users can either adapt to such common standard or simply reconfigure.

I would more go the opposite: What should we choose that likely not matches something else, so StepDefinitions seems sound for me as its unlikely chosen for something else (32 results on github) while e.g. Steps seem to be generic enough to match something by accident (98k results on github).

@mpkorstanje

mpkorstanje commented Aug 2, 2026 •

Copy link
Copy Markdown
Member Author

I think in the end one should choose whats reasonable / workable ... trying to fit everyone's need will likely fail and it is the projects privilege to decide and users can either adapt to such common standard or simply reconfigure.

I'm certainly not going to be able to make everyone happy. I know that there is no perfect solution. But before picking a good enough default (if any) I'd like to have a better idea of what people call their step definition classes in the real world in projects they use.

Thinking about the problem, I'd like to do is come up with a set of conventional suffixes that cover nearly all use cases and then one extra suffix to catch everything else. For example .*StepDefinitions, .*Hooks and .*Glue. The first two would cover the steps and hooks, then the last one could be used for everything else - though I'm not a fan of the word glue, it is not a countable noun.

We can then inform users that they can either configure the property or rename their classes to follow the conventional names.

I would more go the opposite: What should we choose that likely not matches something else, so StepDefinitions seems sound for me as its unlikely chosen for something else (32 results on github) while e.g. Steps seem to be generic enough to match something by accident (98k results on github).

Good point.

@jkronegg

jkronegg commented Aug 2, 2026 •

Copy link
Copy Markdown
Contributor

What about defining a single standard like *StepDefinitions in v8 default configuration, and provide an open rewrite recipe to migrate v7 to v8? This cooking recipe would find all classes that define steps in the user's project, and change the configuration accordingly.

@mpkorstanje

Copy link
Copy Markdown
Member Author

What about defining a single standard like *StepDefinitions in v8 default configuration, and provide an open rewrite recipe to migrate v7 to v8? This cooking recipe would find all classes that define steps in the user's project, and change the configuration accordingly.

That's a good possibility too.

@mpkorstanje
mpkorstanje force-pushed the feature/manual-glue-class-registration branch from 656f5f6 to 441888e Compare September 1, 2026 19:15
@mpkorstanje
mpkorstanje marked this pull request as ready for review September 2, 2026 11:24
@mpkorstanje

Copy link
Copy Markdown
Member Author

Having thought about the default include pattern problem.

Ideally when starting Cucumber JVM, all step definitions, hooks, ect would have been places in classes with a well known suffix. Unfortunately that ship sailed 14 years ago.

Setting a default filter now would require that users either rename all their glue code to match the pattern or working out what the pattern should be. Renaming the glue code might be difficult. There seems to be a tendency for people to package step definitions rather APIs into libraries - I don't understand why, but here we are. Likewise working out what all the glue classes are will be difficult as it can be anything on the classpath.

Then keeping in mind that v8 will require Java 17+ I don't want to increase the migration burden any more than strictly necessary.

Another angle to consider is the typical user of Cucumber JVM. While I reckon most people who've commented on this issue know their way around this isn't the case for every one using Cucumber. So it is sensible to ensure Cucumber works out of the box. Even if this is a little bit slower.

@mpkorstanje
mpkorstanje merged commit 3c908df into main Sep 2, 2026
7 checks passed
@mpkorstanje
mpkorstanje deleted the feature/manual-glue-class-registration branch September 2, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Filter glue class candidates before loading Add API to Manually Register Step Classes

3 participants