419 Commits

Author SHA1 Message Date
Lukasz Lenart 94a8fcb26c WW-3784 Order annotated wildcard actions most-specific-first (#1813)
* WW-3784 docs: design for specificity-ordered wildcard matching in annotated actions

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 docs: implementation plan for annotated wildcard specificity ordering

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 feat(convention): add action-name specificity comparator

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 fix(convention): add Apache License header to test file

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 feat(core): add PackageConfig.Builder.reorderActionConfigs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 docs: add javadoc for PackageConfig.Builder.reorderActionConfigs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 feat(convention): order annotated wildcard actions most-specific-first

Sorts each convention-built package's action configs by pattern specificity so a
specific pattern (some/usefull/*) is matched before a general one (some/*),
regardless of class-scan order. Also makes convention action ordering deterministic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 docs: correct wildcard cross-segment claims and note comparator limitations

The spec incorrectly stated that WildcardHelper's single `*` is greedy
and crosses `/`, and that `some/*` shadows `some/usefull/*`. Verified
against WildcardHelper.java and NamedVariablePatternMatcher.java: only
`**` crosses `/`, so those two patterns are actually disjoint (different
segment counts) and never compete for the same request. Correct the
Problem narrative, ticket example, and matcher bullets to state this
accurately, and document two known limitations of the specificity
comparator (raw wildcard-token-count key can misrank `**` ahead of
narrower multi-token patterns; parent-package actions bypass sorting).
Also add a test asserting the natural-order alphabetical tiebreak key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-3784 test(convention): prove specificity ordering fixes wildcard shadowing end-to-end

Adds an end-to-end routing test driving the production reorder
(PackageConfig.Builder.reorderActionConfigs + ActionNameSpecificityComparator)
through the real ActionConfigMatcher/WildcardHelper. some/** and some/usefull/*
genuinely overlap for some/usefull/sleeping (** crosses '/'), so the test asserts
the general pattern shadows the specific one when registered first, and that
specificity ordering makes the specific action reachable again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 07:56:58 +02:00
Lukasz Lenart 50c16e93b1 Release 7.2.1-RC1 (#1744)
* [maven-release-plugin] prepare release STRUTS_7_2_1

* [maven-release-plugin] prepare for next development iteration
2026-06-26 07:18:26 +02:00
Lukasz Lenart 489445c78d Release 7.2.0-RC1 (#1742)
* [maven-release-plugin] prepare release STRUTS_7_2_0

* [maven-release-plugin] prepare for next development iteration
2026-06-15 12:07:02 +02:00
Lukasz Lenart 2215b6873c WW-5537 Resolve classloader/memory leaks during Tomcat hot deployment (#1632)
* WW-5537 Add InternalDestroyable and ContextAwareDestroyable interfaces

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 ContainerHolder: ThreadLocal with AtomicLong generation counter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 FinalizableReferenceQueue: volatile instance, join, classloader null

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 ScopeInterceptor.clearLocks: add synchronized block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 CompoundRootAccessor, DefaultFileManager: implement InternalDestroyable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Add InternalDestroyable adapter classes for static cache cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Register InternalDestroyable beans in struts-beans.xml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 JSON plugin: add JSONCacheDestroyable for BeanInfo cache cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Dispatcher.cleanup: refactor into focused methods with InternalDestroyable discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Rewrite DispatcherCleanupTest for InternalDestroyable discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Add log4j-web for proper Log4j2 lifecycle in Servlet container

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Dispatcher.destroyObjectFactory: add early return on null, use pattern matching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Fix @since annotations: 7.1.0 -> 7.2.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Add Container.destroy() to clear internal caches on undeploy

Container now exposes a destroy() method that clears factories, injectors,
constructors, and ThreadLocals. This releases Class<?> keys and JDK
DelegatingClassLoader instances that pin the webapp classloader.

DefaultConfiguration.destroy() calls container.destroy() and
reloadContainer() delegates to destroy() to avoid duplication.

Also fixes JSONCacheDestroyable referencing non-existent DefaultJSONWriter
(renamed to StrutsJSONWriter).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Fix Container.destroy(): don't clear factories, don't call from reloadContainer

factories must remain intact because existing code holds direct
references to the Container after destroyConfiguration() and expects
it to still resolve dependencies (e.g. during configuration reload).

reloadContainer() reverted to clearing packageContexts/loadedFileNames
directly — calling destroy() there nulled the container reference and
cleared state needed during the bootstrap transition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Restore destroy() call in reloadContainer()

The test failures were caused by factories.clear() in
Container.destroy(), not by calling destroy() from reloadContainer().
Now that factories.clear() is removed, destroy() is safe to call
here — it clears packageContexts, loadedFileNames, and the container's
reflection caches in one place.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WW-5537 Fix Sonar issues: thread-safe FinalizableReferenceQueue, empty method comments

- Replace volatile field with AtomicReference in FinalizableReferenceQueue
  for proper thread safety using getAndSet()
- Add comments to empty destroy() implementations in test mocks
- Replace deprecated new URL() with URI.toURL() in DispatcherCleanupTest
- Add comments to empty listener methods in DispatcherCleanupTest

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 07:17:57 +02:00
Lukasz Lenart a9ce3e3c99 fix(convention): WW-4421 detect duplicate @Action names when execute() is annotated (#1579)
The duplicate @Action name detection in PackageBasedActionConfigBuilder
was embedded inside a conditional block that only ran when execute() was
NOT annotated with @Action. This meant two methods could map to the same
action name silently when execute() had an @Action annotation, with one
overwriting the other non-deterministically.

Extract the duplicate check to run unconditionally before the conditional
block, so it applies to all annotated methods regardless of whether
execute() is annotated.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-21 09:12:52 +00:00
Lukasz Lenart 22b0fa9f12 chore: updates SNAPSHOT version to reflect current scope of changes (#1563) 2026-02-01 12:26:48 +00:00
Lukasz Lenart 1fef0e1f9b fix(convention): WW-5593 handle NoClassDefFoundError in action class scanning (#1469)
The PackageBasedActionConfigBuilder now catches NoClassDefFoundError in
addition to ClassNotFoundException when scanning for action classes.
This prevents application startup failures when classes have missing
optional dependencies (e.g., test classes depending on JUnit).

Changes:
- Add NoClassDefFoundError to catch block in getActionClassTest()
- Improve error message to suggest missing dependencies
- Add unit tests for both exception types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 20:01:25 +01:00
Lukasz Lenart 6d778ac9b7 fix(convention): WW-5594 exclude root package classes with wildcard patterns (#1468)
The exclusion pattern "org.apache.struts2.*" was not properly excluding
classes directly in the root package (like XWorkTestCase) because:

1. PackageBasedActionConfigBuilder extracts package names using
   substringBeforeLast(className, ".") which produces "org.apache.struts2"
   (no trailing dot)
2. The wildcard pattern requires a literal "." before "*"
3. Result: Pattern doesn't match root package classes

Fix: Enhanced checkExcludePackages() to automatically handle patterns
ending with ".*" by also checking if the package name equals the base
pattern (without ".*").

Now "org.apache.struts2.*" properly excludes both:
- Classes in root package: org.apache.struts2.XWorkTestCase
- Classes in subpackages: org.apache.struts2.dispatcher.SomeClass

Closes [WW-5594](https://issues.apache.org/jira/browse/WW-5594)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-14 19:41:59 +01:00
dependabot[bot] 1ee0ae0299 Bump org.apache.rat:apache-rat-plugin from 0.16.1 to 0.17 (#1406)
* Bump org.apache.rat:apache-rat-plugin from 0.16.1 to 0.17

Bumps org.apache.rat:apache-rat-plugin from 0.16.1 to 0.17.

---
updated-dependencies:
- dependency-name: org.apache.rat:apache-rat-plugin
  dependency-version: '0.17'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Updates exclusions

* Removes includes to include all the files

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Lukasz Lenart <lukaszlenart@apache.org>
2025-11-24 09:03:30 +01:00
Lukasz Lenart 6131c9364e Fixes site and JavaDocs generation (#1419) 2025-11-22 16:55:18 +01:00
Lukasz Lenart eba05e53da Reverse merge changes related to releasing Struts 7.1.1 (#1378)
* [maven-release-plugin] prepare release STRUTS_7_1_1

* [maven-release-plugin] rollback the release of STRUTS_7_1_1

* [maven-release-plugin] prepare release STRUTS_7_1_1

* [maven-release-plugin] prepare for next development iteration
2025-10-19 19:12:31 +02:00
Lukasz Lenart 4e308e2be0 [maven-release-plugin] prepare for next development iteration 2025-09-24 09:45:02 +02:00
Lukasz Lenart 02858b7ed5 [maven-release-plugin] prepare release STRUTS_7_1_0 2025-09-24 09:44:54 +02:00
Lukasz Lenart 8fcab78c5d [maven-release-plugin] rollback the release of STRUTS_7_1_0 2025-09-24 09:39:45 +02:00
Lukasz Lenart d50cfba32e [maven-release-plugin] prepare release STRUTS_7_1_0 2025-09-24 09:39:08 +02:00
Lukasz Lenart d727fbf6be [maven-release-plugin] prepare for next development iteration 2025-02-17 10:41:25 +01:00
Lukasz Lenart 4603706b40 [maven-release-plugin] prepare release STRUTS_7_0_3 2025-02-17 10:41:17 +01:00
Lukasz Lenart a1de1cfdeb [maven-release-plugin] prepare for next development iteration 2025-02-04 07:07:24 +01:00
Lukasz Lenart 9326279769 [maven-release-plugin] prepare release STRUTS_7_0_2 2025-02-04 07:07:15 +01:00
Lukasz Lenart b34665046c Improves code quality
Uses existing function to split input using comma
2025-02-02 17:22:42 +01:00
Lukasz Lenart 080263e93f [maven-release-plugin] prepare for next development iteration 2025-02-02 08:26:01 +01:00
Lukasz Lenart f6bf43ae0b [maven-release-plugin] prepare release STRUTS_7_0_1 2025-02-02 08:25:53 +01:00
Lukasz Lenart 9aa41f18ae [maven-release-plugin] prepare for next development iteration 2024-12-11 07:56:30 +01:00
Lukasz Lenart 1d95543fbf [maven-release-plugin] prepare release STRUTS_7_0_0 2024-12-11 07:56:16 +01:00
Lukasz Lenart 90c9dfa923 [maven-release-plugin] prepare for next development iteration 2024-11-03 14:51:02 +01:00
Lukasz Lenart 5760d45a3e [maven-release-plugin] prepare release STRUTS_7_0_0_M10 2024-11-03 14:50:53 +01:00
Lukasz Lenart 83cb936c3a WW-5459 Moves ActionChainResult into org.apache.struts2.result package 2024-11-02 15:23:54 +01:00
Lukasz Lenart dd6bb139f7 WW-5459 Moves Action interface into org.apache.struts2.action package 2024-11-02 15:09:51 +01:00
Kusal Kithul-Godage 87df4a229d WW-3714 Move new Result class into result package 2024-11-02 23:09:41 +11:00
Kusal Kithul-Godage a43f8a5239 Merge remote-tracking branch 'origin/master' into 7.0.x/merge-master-2024-11-02 2024-11-02 14:17:56 +11:00
Kusal Kithul-Godage fe46ad9f4a WW-5478 Deprecate DefaultResultFactory 2024-11-02 14:01:36 +11:00
Kusal Kithul-Godage 32bc4045ba WW-3714 Moves all classes from com.opensymphony.xwork2 into org.apache.struts2 2024-11-01 19:02:21 +11:00
Lukasz Lenart d33be1d43c [maven-release-plugin] prepare for next development iteration 2024-10-05 16:08:38 +02:00
Lukasz Lenart c812450292 [maven-release-plugin] prepare release STRUTS_6_6_1 2024-10-05 16:08:26 +02:00
Kusal Kithul-Godage aec78dd161 WW-5411 Misc code cleanup 2024-07-25 21:16:56 +10:00
Lukasz Lenart c5dfe61ecf [maven-release-plugin] prepare for next development iteration 2024-07-21 08:59:44 +02:00
Lukasz Lenart 571c7eff0a [maven-release-plugin] prepare release STRUTS_7_0_0_M9 2024-07-21 08:59:32 +02:00
Lukasz Lenart f977f0c0e5 [maven-release-plugin] prepare for next development iteration 2024-07-20 08:28:46 +02:00
Lukasz Lenart d6e30b45da [maven-release-plugin] prepare release STRUTS_6_6_0 2024-07-20 08:28:35 +02:00
Kusal Kithul-Godage 7b84357686 Merge remote-tracking branch 'origin/master' into 7.0.x/merge-master-2024-07-20 2024-07-20 13:36:38 +10:00
Kusal Kithul-Godage cb62cb4e9a WW-5440 Fix OGNL allowlist compat with Convention plugin 2024-07-14 00:34:06 +10:00
Kusal Kithul-Godage f9953938f7 WW-5440 Add missing annotations 2024-07-13 21:57:26 +10:00
Lukasz Lenart 54e387dc6f [maven-release-plugin] prepare for next development iteration 2024-07-12 07:27:19 +02:00
Lukasz Lenart dbfb59cb7c [maven-release-plugin] prepare release STRUTS_6_5_0 2024-07-12 07:27:08 +02:00
Lukasz Lenart e40703e8ad [maven-release-plugin] prepare for next development iteration 2024-07-11 09:48:25 +02:00
Lukasz Lenart 4f8cb5211f [maven-release-plugin] prepare release STRUTS_7_0_0_M8 2024-07-11 09:48:14 +02:00
Lukasz Lenart 28a68676ec [maven-release-plugin] prepare for next development iteration 2024-06-12 07:45:22 +02:00
Lukasz Lenart 1057d4149b [maven-release-plugin] prepare release STRUTS_7_0_0_M7 2024-06-12 07:45:12 +02:00
Lukasz Lenart 2352c68631 [maven-release-plugin] prepare for next development iteration 2024-04-20 09:24:32 +02:00
Lukasz Lenart af53f0d93b [maven-release-plugin] prepare release STRUTS_7_0_0_M6 2024-04-20 09:24:22 +02:00