I have a code which collects all the system-properties keys which starts with a given prefix
private static List<String> getKeysByPrefix(String prefix) {
Set<?> keySet = System.getProperties().keySet();
Iterator<?> iterator = keySet.iterator();
List<String> list = new ArrayList<>();
while (iterator.hasNext()) {
String key = (String) iterator.next();
if (key.startsWith(prefix)) {
list.add(key);
}
}
return list;
}
This code is running inside a Jetty web-server, and while a request is executing this code, it can happen that another request write a new key inside the java System properties like a simple System.setProperty("test", "foo");
With this scenario I'm getting a ConcurrentModificationException
while I'm iterating the properties and another request changes it.
java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1378)
The code which set the new property is totally another flow compared to the one is iterating the keys, but because the SystemProperties are shared among all the JVM instance, I'm getting this error.
I already found other topics which treats this topic, and the most suggested solution is using ConcurrentHashMap. This option is unavailable for me because I'm not the one which creates the SystemProperties map but i'm only reading/writing it.
In order to reproduce the issue you can simply add a setProperty
call right before the closing bracket of the iterator loop
Which is a suggested practice here in order to solve the problem?