This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new 21d682119 Bump org.apache.commons:commons-parent from 104 to 105.
21d682119 is described below

commit 21d6821190e0325022510393f41faa8ec95b6397
Author: Gary Gregory <[email protected]>
AuthorDate: Mon Sep 7 14:48:33 2026 -0400

    Bump org.apache.commons:commons-parent from 104 to 105.
    
    - Fix AbstractReferenceMap.ReferenceEntry.setValue(V) to throw
    NullPointerException on null input (contract).
    - Legacy tests were previously skipped.
    Before:
    ```
    [INFO] Tests run: 18050, Failures: 0, Errors: 0, Skipped: 75
    ```
    Now:
    ```
    [INFO] Tests run: 22257, Failures: 0, Errors: 0, Skipped: 82
    ```
---
 pom.xml                                            |  2 +-
 src/changes/changes.xml                            |  2 ++
 .../collections4/map/AbstractReferenceMap.java     |  6 +++--
 .../commons/collections4/GuavaTestlibTest.java     | 24 ++++++++++---------
 .../commons/collections4/map/ReferenceMapTest.java | 27 ++++++++++++++++++++++
 5 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6be1dbe8d..de4443aa0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-parent</artifactId>
-    <version>104</version>
+    <version>105</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>commons-collections4</artifactId>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 0edfc7365..f893895a7 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -34,8 +34,10 @@
     <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Fix 
map and bidimap nextKey() skipping a key and throwing for keys not in the map 
(#728).</action>
     <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Reset 
last element in EnumerationIterator.remove() (#729).</action>
     <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Fix 
TransformedMultiValuedMap.putAll(K, Iterable) NPE for null value transformer 
(#731).</action>
+    <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix 
AbstractReferenceMap.ReferenceEntry.setValue(V) to throw NullPointerException 
on null input (contract).</action>
     <!-- ADD -->
     <!-- UPDATE -->
+    <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
org.apache.commons:commons-parent from 104 to 105.</action>
     <action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump 
com.google.guava:guava-testlib from 33.6.0-jre to 33.7.1-jre (#733).</action>
     <action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump 
org.easymock:easymock from 5.6.0 to 5.7.0 (#732).</action>
     <!-- REMOVE -->
diff --git 
a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java 
b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
index 7ef0095d2..554f0ea8b 100644
--- 
a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
+++ 
b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
@@ -335,12 +335,14 @@ public abstract class AbstractReferenceMap<K, V> extends 
AbstractHashedMap<K, V>
         /**
          * Sets the value of the entry.
          *
-         * @param value  The object to store
-         * @return The previous value
+         * @param value  The object to store, must not be null.
+         * @return The previous value.
+         * @throws NullPointerException if the value is null.
          */
         @Override
         @SuppressWarnings("unchecked")
         public V setValue(final V value) {
+            Objects.requireNonNull(value, "value");
             final V old = getValue();
             if (parent.valueType != ReferenceStrength.HARD) {
                 ((Reference<V>) this.value).clear();
diff --git 
a/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java 
b/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
index 169bbed80..da5ffc78e 100644
--- a/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
+++ b/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
@@ -55,9 +55,9 @@ public final class GuavaTestlibTest extends TestCase {
     public static Test suite() {
         final TestSuite test = new TestSuite();
         // Map
-        test.addTest(suiteMap("HashedMap", HashedMap::new));
-        test.addTest(suiteMap("LinkedMap", LinkedMap::new));
-        test.addTest(suiteMap("LRUMap", LRUMap::new));
+        test.addTest(suiteMap("HashedMap", HashedMap::new, 
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
+        test.addTest(suiteMap("LinkedMap", LinkedMap::new, 
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
+        test.addTest(suiteMap("LRUMap", LRUMap::new, 
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
         test.addTest(suiteMap("ReferenceMap", ReferenceMap::new));
         // List
         test.addTest(suiteList("TreeList", TreeList::new));
@@ -71,10 +71,10 @@ public final class GuavaTestlibTest extends TestCase {
 
     /**
      * Programmatically create a JUnit (3, 4) Test Suite for Guava testlib 
tests with Lists.
-     * @param name name of the test
-     * @param factory factory to create new Lists
-     * @param features test features used in the tests
-     * @return A JUnit 3, 4 Test Suite
+     * @param name name of the test.
+     * @param factory factory to create new Lists.
+     * @param features test features used in the tests.
+     * @return A JUnit 3, 4 Test Suite.
      */
     private static Test suiteList(final String name, final 
Supplier<List<String>> factory, final Feature<?>... features) {
         final ListTestSuiteBuilder<String> suite = 
ListTestSuiteBuilder.using(new TestStringListGenerator() {
@@ -99,11 +99,12 @@ public final class GuavaTestlibTest extends TestCase {
 
     /**
      * Programmatically create a JUnit (3, 4) Test Suite for Guava testlib 
tests with Maps.
-     * @param name name of the test
-     * @param factory factory to create new Maps
-     * @return A JUnit 3, 4 Test Suite
+     * @param name name of the test.
+     * @param factory factory to create new Maps.
+     * @param features test features used in the tests.
+     * @return A JUnit 3, 4 Test Suite.
      */
-    private static Test suiteMap(final String name, final Supplier<Map<String, 
String>> factory) {
+    private static Test suiteMap(final String name, final Supplier<Map<String, 
String>> factory, final Feature<?>... features) {
         return MapTestSuiteBuilder.using(new TestStringMapGenerator() {
             @Override
             protected Map<String, String> create(final Map.Entry<String, 
String>[] entries) {
@@ -118,6 +119,7 @@ public final class GuavaTestlibTest extends TestCase {
                 .withFeatures(
                         CollectionSize.ANY, MapFeature.GENERAL_PURPOSE,
                         MapFeature.ALLOWS_ANY_NULL_QUERIES, 
CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
+                .withFeatures(features)
                 .createTestSuite();
     }
 }
diff --git 
a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java 
b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
index 40d9d4525..41a9ca836 100644
--- a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
+++ b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
@@ -34,11 +34,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Consumer;
 
+import org.apache.commons.collections4.MapIterator;
 import org.apache.commons.collections4.map.AbstractHashedMap.HashEntry;
 import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceEntry;
 import 
org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
 import org.junit.jupiter.params.provider.ValueSource;
 
 /**
@@ -308,6 +310,18 @@ public class ReferenceMapTest<K, V> extends 
AbstractIterableMapTest<K, V> {
         assertThrows(InvalidObjectException.class, () -> 
serializeDeserialize(map));
     }
 
+    @ParameterizedTest
+    @EnumSource(ReferenceStrength.class)
+    void testEntrySetValueRejectsNull(final ReferenceStrength valueType) {
+        final ReferenceMap<String, String> map = new 
ReferenceMap<>(ReferenceStrength.HARD, valueType);
+        map.put("key", "value");
+        final Map.Entry<String, String> entry = 
map.entrySet().iterator().next();
+        assertThrows(NullPointerException.class, () -> entry.setValue(null));
+        assertEquals("value", entry.getValue());
+        assertEquals("value", map.get("key"));
+        assertEquals(1, map.size());
+    }
+
     /**
      * Test whether remove is not removing last entry after calling hasNext.
      * <p>
@@ -326,6 +340,19 @@ public class ReferenceMapTest<K, V> extends 
AbstractIterableMapTest<K, V> {
         assertTrue(map.isEmpty(), "Expect empty but have entry: " + map);
     }
 
+    @ParameterizedTest
+    @EnumSource(ReferenceStrength.class)
+    void testMapIteratorSetValueRejectsNull(final ReferenceStrength valueType) 
{
+        final ReferenceMap<String, String> map = new 
ReferenceMap<>(ReferenceStrength.HARD, valueType);
+        map.put("key", "value");
+        final MapIterator<String, String> iterator = map.mapIterator();
+        iterator.next();
+        assertThrows(NullPointerException.class, () -> 
iterator.setValue(null));
+        assertEquals("value", iterator.getValue());
+        assertEquals("value", map.get("key"));
+        assertEquals(1, map.size());
+    }
+
     @Test
     @SuppressWarnings("unchecked")
     void testNullHandling() {

Reply via email to