diff --git a/pom.xml b/pom.xml
index 1f50b8ef50..41f2aa6a1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -237,6 +237,11 @@
commons-lang3
3.12.0
+
+ org.apache.commons
+ commons-collections4
+ 4.4
+
org.apache.maven.plugin-testing
maven-plugin-testing-harness
diff --git a/versions-common/pom.xml b/versions-common/pom.xml
index 6983325c1c..2a0cbfe89b 100644
--- a/versions-common/pom.xml
+++ b/versions-common/pom.xml
@@ -60,7 +60,10 @@
org.apache.commons
commons-lang3
-
+
+ org.apache.commons
+ commons-collections4
+
org.apache.maven.plugin-testing
maven-plugin-testing-harness
diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java
index 0b8695680f..fe5a5f0190 100644
--- a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java
+++ b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/ComparableVersion.java
@@ -29,7 +29,9 @@
import java.util.Map;
import java.util.Properties;
import java.util.Stack;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.commons.collections4.map.LRUMap;
/**
* Generic implementation of version comparison.
@@ -39,7 +41,9 @@
* Note: The implementation of the maven core should be used.
*/
public class ComparableVersion implements Comparable {
- private static final Map CACHE = new ConcurrentHashMap<>();
+ private static final int MAX_CACHE_SIZE = 0x200;
+ private static final Map CACHE = new LRUMap<>(MAX_CACHE_SIZE);
+ private static final ReentrantReadWriteLock CACHE_LOCK = new ReentrantReadWriteLock();
private String value;
@@ -291,7 +295,21 @@ public String toString() {
* Get a ComparableVersion representing the version in a string.
*/
public static ComparableVersion of(String version) {
- return CACHE.computeIfAbsent(version, ComparableVersion::new);
+ try {
+ CACHE_LOCK.readLock().lock();
+ ComparableVersion result = CACHE.get(version);
+ if (result != null) {
+ return result;
+ }
+ } finally {
+ CACHE_LOCK.readLock().unlock();
+ }
+ try {
+ CACHE_LOCK.writeLock().lock();
+ return CACHE.computeIfAbsent(version, ComparableVersion::new);
+ } finally {
+ CACHE_LOCK.writeLock().unlock();
+ }
}
/**