Skip to content

fix(deps): EOL replace commons-collections 3.2.2 with commons-collections4 4.5.0 (issue #86) - #87

Merged
natechadwick merged 1 commit into
mainfrom
security/72-commons-collections-eol
Aug 28, 2026
Merged

fix(deps): EOL replace commons-collections 3.2.2 with commons-collections4 4.5.0 (issue #86)#87
natechadwick merged 1 commit into
mainfrom
security/72-commons-collections-eol

Conversation

@natechadwick-intsof

Copy link
Copy Markdown
Collaborator

Summary

EOL replace commons-collections:commons-collections:3.2.2 (EOL since 2015) with org.apache.commons:commons-collections4:4.5.0 project-wide. commons-collections4:4.5.0 was already in the root pom's dependencyManagement — only the 3.x line was in active use, so no new dep is added.

The 3.x line has been EOL since 2015 and has 2 CVEs in the analysis report (one CRITICAL, one HIGH). The 4.x line is the maintained successor with the same API surface (most class names are identical; the package is just collections4 instead of collections).

What changes (4 categories)

1. Bulk package rename (71 .java files)

Every import org.apache.commons.collections.X.Y; becomes import org.apache.commons.collections4.X.Y;. Most class names are identical between the two lines (CollectionUtils, MapUtils, ListUtils, MapIterator, Predicate, Transformer, IterableMap, IteratorUtils, FilterIterator, IteratorEnumeration, AbstractListDecorator, HashedMap, etc.) so this is mostly an import-line change with no API impact.

2. Pom cleanup (1 + 13 files)

  • Root pom.xml: removed the <dependency>commons-collections:commons-collections:3.2.2</dependency> block (line 561-564) and the <commons.collections3.version>3.2.2</commons.collections3.version> property
  • 13 module poms: removed the direct <dependency> blocks (and 5 exclusion blocks) that referenced the 3.x line
  • 1 module pom (modules/jcadf-master/pom.xml): added a direct <dependency>org.apache.commons:commons-collections4</dependency> entry, since the original commons-collections:commons-collections direct dep was the sole source of the collections classes in this module — the 4.x version is in dependencyManagement but a child pom that doesn't inherit transitive deps from a parent that uses them needs a direct declaration to bring them in

3. Special-case API moves in 4.x (6 files)

File What was moved / removed in 4.x Fix
projects/sitemanage/.../PSPageUtils.java MapUtils.getString(Map, String) 2-arg signature changed to a generic <K> String getString(Map<? super K, ?>, K); doesn't type-infer when input is Map<?, ?> cast to raw Map with @SuppressWarnings({"unchecked", "rawtypes"}) to anchor K=String
modules/extensions-sfp/.../PSCalendarMonthModel.java, system/services/.../PSContentRepository.java, system/services/.../PSItemUtilities.java (+ 2 callers: PSActionPanelServlet, PSItemUtilitiesTest) org.apache.commons.collections.MultiHashMap was removed in 4.x; MultiMap interface (deprecated but still present) is unrelated to the new MultiValuedMap interface that replaced it change MultiHashMapmultimap.ArrayListValuedHashMap; change MultiMap field/local types → MultiValuedMap; change new MultiHashMap()new ArrayListValuedHashMap()
projects/sitemanage/.../PSLegacyExtensionUtils.java, deployer/.../PSContentTypeSetter.java (iteratorToList helper), deployer/.../PSContentTypeFieldSetter.java (excludes loop), system/.../PSConditionalCloneHandler.java CollectionUtils.addAll(Collection, Iterator) was removed in 4.x (the new signatures are addAll(Collection, Iterable) and addAll(Collection, Enumeration) only) inline to a while (it.hasNext()) list.add((...) it.next()) loop (with a cast for the raw-Iterator case)
projects/sitemanage/.../PSConcurrentRegionsAssembler.java AbstractListDecorator.getCollection() and getList() were renamed to decorated() in 4.x (the 4.x base class declares it as protected) rename the FutureList.getCollection() override to decorated() (and remove the @Override since decorated() is protected); update internal getList() and getCollection() calls to decorated()

The 7 other CollectionUtils.addAll(...) call sites pass Iterable / Collection (not Iterator) and work unchanged in 4.x.

4. jcadf-master/pom.xml direct dep

The modules/jcadf-master (artifactId auditlogger) module's direct <dependency>commons-collections:commons-collections</dependency> was the only source of the collections classes for that module (it doesn't inherit them transitively from a sibling). After removing the 3.x line, added a corresponding direct <dependency>org.apache.commons:commons-collections4</dependency> entry (version inherited from the parent pom's dependencyManagement). This is the only module where the direct dep is structurally required.

Verification

  • ./mvn-env.sh clean install -DskipTestsBUILD SUCCESS in 3:41 (61 modules, Java 1.8.0_504)
  • ./mvn-env.sh spotless:check (run by the validate phase; no manual violations)
  • No UnsupportedClassVersionError in the build log
  • commons-collections:3.2.2 no longer in the project's own dependency graph
    • mvn dependency:tree -Dincludes=commons-collections:commons-collections is now empty
    • commons-collections:2.5 is still pulled in transitively by legacy system-scoped jars like axe:axe-saaj:1.4.1, caja, smartgwt; that is independent of this PR
  • commons-collections4:4.5.0 resolves correctly: mvn dependency:tree -Dincludes=org.apache.commons:commons-collections4 shows the dep at 4.5.0

Out of scope (separate issues under #73)

References

Co-Authored by Mavis v1.0.0 using minimax-m3 with agent mavis.

…ions4 4.5.0 (issue #86)

Closes #86. Mechanical migration of every `org.apache.commons.collections.*`
import to `org.apache.commons.collections4.*` across the codebase, plus
removal of the 3.2.2 dep from the root pom and 13 module poms. The
`commons-collections4:4.5.0` line was already in the root pom's
dependencyManagement (only the 3.x line was in active use), so no new
dep is added.

Scope:
  - 71 .java files: `org.apache.commons.collections.` -> `org.apache.commons.collections4.`
  - 1 root pom + 13 module poms: drop the `commons-collections:commons-collections:3.2.2`
    dependency and the `<commons.collections3.version>3.2.2</commons.collections3.version>` property
  - 1 module pom (jcadf-master): add a direct `org.apache.commons:commons-collections4` dep,
    since the original `commons-collections:commons-collections` direct dep was the
    sole source of the collections classes in this module
  - 6 special-case files (see API notes below)

API differences between commons-collections 3.x and 4.5.0 that this PR
addresses (all behavioural, no semantic change for the call sites
involved):

  1. `org.apache.commons.collections.MultiHashMap` was **removed** in 4.x.
     The 3 call sites now use `org.apache.commons.collections4.multimap.ArrayListValuedHashMap`.
     The `MultiMap` interface (deprecated in 4.x but still present) was
     replaced with `MultiValuedMap` (the new 4.x interface that replaced
     it; `ArrayListValuedHashMap` implements `MultiValuedMap`, not
     `MultiMap`).
     Files: PSCalendarMonthModel, PSContentRepository, PSItemUtilities +
     2 callers (PSActionPanelServlet, PSItemUtilitiesTest).

  2. `CollectionUtils.addAll(Collection, Iterator)` was **removed** in 4.x
     (the new signatures are `addAll(Collection, Iterable)` and
     `addAll(Collection, Enumeration)` only). The 4 call sites
     that pass an Iterator are inlined to a `while (it.hasNext()) list.add(it.next())` loop.
     The 7 sites that pass an Iterable/Collection work unchanged.
     Files: PSLegacyExtensionUtils, PSContentTypeSetter (iteratorToList),
     PSContentTypeFieldSetter (excludes loop), PSConditionalCloneHandler.

  3. `AbstractListDecorator.getCollection()` / `getList()` were renamed
     to `decorated()` in 4.x. The 1 call site in
     PSConcurrentRegionsAssembler.FutureList inlines the override as
     `decorated()` (and calls it from the iterator/toString overrides
     that previously used the public `getList()` / `getCollection()`).

  4. `MapUtils.getString(Map, String)` (2-arg) and the new 3-arg
     `getString(Map, String, String)` (default) in 4.x use a generic
     signature `<K> String getString(Map<? super K, ?>, K)` that does
     not type-infer when the input is `Map<?, ?>`. The 1 call site
     in PSPageUtils casts to a raw `Map` to anchor the K-inference to
     String (with a `@SuppressWarnings({unchecked, rawtypes})`
     on the line).

Verification:
  - ./mvn-env.sh clean install -DskipTests: BUILD SUCCESS in 3:41
    (61 modules, Java 1.8.0_504)
  - ./mvn-env.sh spotless:check: clean (the build runs spotless:apply
    during validate; nothing needed reformatting beyond the inline
    raw-type cast above)
  - No UnsupportedClassVersionError in the build log
  - commons-collections 3.x no longer in the project's own dependency
    graph (only commons-collections4 4.5.0 remains; `commons-collections` 2.5
    may still be pulled in transitively by legacy system-scoped jars, but
    that is independent of this PR)

Out of scope (separate issues under #73):
  - commons-beanutils 1.11.0 -> beanutils2 EOL replacement
    (Jakarta migration; large blast radius)
  - commons-httpclient 3.1 -> HttpClient 5 (the project already has
    HttpClient 5 from #79; just remove the 3.1 dep)
  - commons-configuration 1.10 -> commons-configuration2 EOL replacement
  - T2.11 SnakeYAML SafeConstructor hardening (16 CVEs)
  - T2.6 size caps on the other zip sites (follow-up to #83)

Refs #86, #73, #72
@natechadwick
natechadwick merged commit fa12293 into main Aug 28, 2026
3 checks passed
@natechadwick
natechadwick deleted the security/72-commons-collections-eol branch August 28, 2026 21:55
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.

deps: EOL replace commons-collections 3.2.2 with commons-collections4 4.5.0 (closes 2 CVEs)

2 participants