You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2026/10/11 13:12:17 UTC
(tomcat) 13/20: Hand out a copy of the static members list
This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit ab90082aaa7e7d472d2c9a70148c26812052acfc
Author: opencode <re...@apache.org>
AuthorDate: Sun Oct 11 12:34:11 2026 +0200
Hand out a copy of the static members list
The accessor of the static members returned the internal list that the
membership provider iterates from its ping thread and at start and
stop. A caller that mutated the returned list at runtime raced that
iteration of an unsynchronized array list, with the member list
occasionally read in an inconsistent state and members silently
missing from pings and start notifications.
The accessor now hands out a copy, and its contract says so, leaving
the provider with the configured list, which only the service itself
still touches. The signature keeps the array list type, so callers
compiled against the accessor are unaffected, while the read only
callers in this repository keep working against the copy.
Add tests pinning the contract, an accessor that returns a different
list each call and mutations of the returned list that leave the
provider list untouched.
---
.../tribes/membership/StaticMembershipService.java | 7 ++++---
.../membership/TestStaticMembershipService.java | 22 ++++++++++++++++++++++
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/java/org/apache/catalina/tribes/membership/StaticMembershipService.java b/java/org/apache/catalina/tribes/membership/StaticMembershipService.java
index b4d9d3101e..2d4f8c399e 100644
--- a/java/org/apache/catalina/tribes/membership/StaticMembershipService.java
+++ b/java/org/apache/catalina/tribes/membership/StaticMembershipService.java
@@ -164,11 +164,12 @@ public class StaticMembershipService extends MembershipServiceBase implements St
}
/**
- * Returns the list of static members.
- * @return the static members list
+ * Returns a copy of the list of static members. Mutating the returned list has no effect on
+ * this service. The provider uses the configured list directly while it runs.
+ * @return a copy of the static members list
*/
public ArrayList<StaticMember> getStaticMembers() {
- return staticMembers;
+ return new ArrayList<>(staticMembers);
}
/**
diff --git a/test/org/apache/catalina/tribes/membership/TestStaticMembershipService.java b/test/org/apache/catalina/tribes/membership/TestStaticMembershipService.java
index ddafa78835..71d35f5c5c 100644
--- a/test/org/apache/catalina/tribes/membership/TestStaticMembershipService.java
+++ b/test/org/apache/catalina/tribes/membership/TestStaticMembershipService.java
@@ -16,6 +16,7 @@
*/
package org.apache.catalina.tribes.membership;
+import java.util.ArrayList;
import java.util.Properties;
import org.junit.Assert;
@@ -120,4 +121,25 @@ public class TestStaticMembershipService {
service.stop(level);
}
}
+
+ /*
+ * The accessor hands out the list that the provider iterates while it runs. A caller that
+ * mutated the returned list raced that iteration, so the accessor must hand out a copy
+ * instead of the live list.
+ */
+ @Test
+ public void testGetStaticMembersReturnsACopy() throws Exception {
+ StaticMembershipService service = new StaticMembershipService();
+ StaticMember member = new StaticMember("127.0.0.1", 4005, -1);
+ service.addStaticMember(member);
+
+ ArrayList<StaticMember> members = service.getStaticMembers();
+ Assert.assertNotSame("the accessor must not hand out the same list twice", members,
+ service.getStaticMembers());
+ Assert.assertTrue(members.remove(member));
+ Assert.assertFalse(members.contains(member));
+
+ // The live list that the provider reads must be untouched by the copy mutation
+ Assert.assertTrue(service.getStaticMembers().contains(member));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org