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-lang.git
commit d74371539f821f52d0ed79188afd8a76e0c183fe Author: Gary Gregory <[email protected]> AuthorDate: Sat Aug 22 11:21:32 2026 -0400 Fix SpotBugs USO_UNSAFE_METHOD_SYNCHRONIZATION in CharSet. --- src/changes/changes.xml | 1 + .../java/org/apache/commons/lang3/CharSet.java | 7 +++++- .../apache/commons/lang3/SerializableObject.java | 29 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 7143d6d8e..14902e8c6 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -246,6 +246,7 @@ java.lang.NullPointerException: Cannot invoke <action type="fix" dev="ggregory" due-to="codeAnqiang-ma, Gary Gregory">Fix the month/day example in DurationFormatUtils.formatPeriod Javadoc (#1772).</action> <action type="fix" dev="ggregory" due-to="gaurav kumar pandey, Gary Gregory">Fix typos in Javadoc and example comments (#1774).</action> <action type="fix" dev="ggregory" due-to="alhuda, Gary Gregory">Fix CharRange.contains(CharRange) for negated argument ranges (#1775).</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix SpotBugs USO_UNSAFE_METHOD_SYNCHRONIZATION in CharSet.</action> <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_27.</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_JAVA_27.</action> diff --git a/src/main/java/org/apache/commons/lang3/CharSet.java b/src/main/java/org/apache/commons/lang3/CharSet.java index 415e763d4..b2504323c 100644 --- a/src/main/java/org/apache/commons/lang3/CharSet.java +++ b/src/main/java/org/apache/commons/lang3/CharSet.java @@ -174,6 +174,11 @@ public static CharSet getInstance(final String... setStrs) { /** The set of CharRange objects. */ private final Set<CharRange> set = Collections.synchronizedSet(new LinkedHashSet<>()); + /** + * Lock object for synchronizing access. + */ + private final Serializable lock = new SerializableObject(); + /** * Constructs a new CharSet using the set syntax. * Each string is merged in with the set. @@ -237,7 +242,7 @@ protected void add(final String str) { * @return {@code true} if the set contains the characters. */ public boolean contains(final char ch) { - synchronized (set) { + synchronized (lock) { return set.stream().anyMatch(range -> range.contains(ch)); } } diff --git a/src/main/java/org/apache/commons/lang3/SerializableObject.java b/src/main/java/org/apache/commons/lang3/SerializableObject.java new file mode 100644 index 000000000..ed41c759c --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/SerializableObject.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.lang3; + +import java.io.Serializable; + +/** + * A simple serializable object for allowing Object locks to be final. + */ +final class SerializableObject implements Serializable { + + private static final long serialVersionUID = 1L; +} +
