lukaszlenart opened a new pull request, #1813: URL: https://github.com/apache/struts/pull/1813
Fixes [WW-3784](https://issues.apache.org/jira/browse/WW-3784) ## Problem Wildcard action patterns are matched **first-match-wins, in insertion order** (`AbstractMatcher.match()` iterates `compiledPatterns` and breaks on the first hit). In XML you control precedence by physically ordering mappings (specific before general). Annotation-based configs (Convention plugin `@Action` wildcards) have **no ordering guarantee** — registration order comes from `Set<Class<?>>` class-scan order, which is arbitrary and non-deterministic across JVMs/classloaders. So when two annotated wildcard patterns genuinely overlap, the general one can be evaluated first and shadow the specific one, leaving the specific action unreachable. ## Solution Order each Convention-built package's wildcard action patterns **most-specific-first**, so first-match-wins does the right thing — without touching XML or core matchers. - **`ActionNameSpecificityComparator`** (convention) — a `Comparator<String>` ranking action-name patterns by: (1) fewer wildcard tokens, (2) more literal characters, (3) fewer path-spanning `**` tokens, (4) natural order (deterministic tiebreak). Matcher-agnostic: recognises both `*`/`**` (`WildcardHelper`) and `{var}` (`NamedVariablePatternMatcher`). - **`PackageConfig.Builder.reorderActionConfigs(Comparator<String>)`** (core) — a neutral, generic helper that re-inserts the action-config `LinkedHashMap` in comparator order. Core does not depend on the plugin; XML providers never call it. - **`PackageBasedActionConfigBuilder`** — applies the comparator to every package in `buildConfiguration(...)`, after `buildIndexActions(...)` and before registration. **Scope:** annotation-sourced configs only. XML keeps its explicit file-order semantics untouched. No config flag — always on for Convention (safe, since the prior order was non-deterministic). A welcome side effect is that Convention action ordering is now **deterministic**. ## Known limitations (documented in the design spec) - Ordering is **per-package**. Convention places all actions of a namespace into one package, so the common case is covered; competing wildcards spread across different convention packages sharing a namespace remain in package-registration order. - The comparator's primary key (fewer wildcard tokens) can rank a broad `**` (one token) ahead of a narrower `*/*` (two tokens). Accepted as a known limitation and noted for a possible future refinement. ## Testing - `ActionNameSpecificityComparatorTest` — ranking rules incl. the ticket case, `*` vs `**`, `{var}`, literals, shuffle-invariance, and the alphabetical tiebreak. - `PackageConfigBuilderReorderTest` (core) — the reorder helper genuinely re-sorts by the supplied comparator. - `PackageBasedActionConfigBuilderReorderTest` — the wiring orders general-before-specific input into specific-first output. - Full suites green: `core` 3053/0, `plugins/convention` 51/0; apache-rat clean. Design and plan: `docs/superpowers/specs/2026-07-26-WW-3784-...-design.md`, `docs/superpowers/plans/2026-07-26-WW-3784-...md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
