This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new 4e1b3f3c JEXL: use cheap read-write lock pattern for loader (volatile
ensures visibility);
4e1b3f3c is described below
commit 4e1b3f3cfaf2b802af48785570e2d8e1721b64b6
Author: Henrib <[email protected]>
AuthorDate: Thu Jan 1 18:36:04 2026 +0100
JEXL: use cheap read-write lock pattern for loader (volatile ensures
visibility);
---
.../jexl3/internal/introspection/Introspector.java | 27 +++++++++-------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git
a/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java
b/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java
index adef421b..99fb8f6f 100644
---
a/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java
+++
b/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java
@@ -104,7 +104,7 @@ public final class Introspector {
private final Map<String, Class<?>> constructibleClasses = new HashMap<>();
/**
* The class loader used to solve constructors if needed.
- * <p>Field is read/written under lock.</p>
+ * <p>Cheap read-write lock pattern: exclusive lock for write, read
visibility through volatile.</p>
*/
@SuppressWarnings("java:S3077")
private volatile ClassLoader loader;
@@ -140,7 +140,7 @@ public final class Introspector {
*/
public Class<?> getClassByName(final String className) {
try {
- final Class<?> clazz = Class.forName(className, false,
getLoader());
+ final Class<?> clazz = Class.forName(className, false, loader);
return permissions.allow(clazz)? clazz : null;
} catch (final ClassNotFoundException xignore) {
return null;
@@ -266,12 +266,7 @@ public final class Introspector {
* @return the class loader
*/
public ClassLoader getLoader() {
- lock.readLock().lock();
- try {
- return loader;
- } finally {
- lock.readLock().unlock();
- }
+ return loader;
}
/**
@@ -384,12 +379,12 @@ public final class Introspector {
final ClassLoader previous = loader;
if (!current.equals(previous)) {
// clean up constructor and class maps
- final Iterator<Map.Entry<MethodKey, Constructor<?>>>
constructorEntries = constructorsMap.entrySet().iterator();
- while (constructorEntries.hasNext()) {
- final Map.Entry<MethodKey, Constructor<?>> entry =
constructorEntries.next();
+ final Iterator<Map.Entry<MethodKey, Constructor<?>>>
constructors = constructorsMap.entrySet().iterator();
+ while (constructors.hasNext()) {
+ final Map.Entry<MethodKey, Constructor<?>> entry =
constructors.next();
final Class<?> clazz =
entry.getValue().getDeclaringClass();
if (isLoadedBy(previous, clazz)) {
- constructorEntries.remove();
+ constructors.remove();
if (!CTOR_MISS.equals(entry.getValue())) {
// the method name is the name of the class
constructibleClasses.remove(entry.getKey().getMethod());
@@ -397,12 +392,12 @@ public final class Introspector {
}
}
// clean up method maps
- final Iterator<Map.Entry<Class<?>, ClassMap>> classMapEntries
= classMethodMaps.entrySet().iterator();
- while (classMapEntries.hasNext()) {
- final Map.Entry<Class<?>, ClassMap> entry =
classMapEntries.next();
+ final Iterator<Map.Entry<Class<?>, ClassMap>> methods =
classMethodMaps.entrySet().iterator();
+ while (methods.hasNext()) {
+ final Map.Entry<Class<?>, ClassMap> entry = methods.next();
final Class<?> clazz = entry.getKey();
if (isLoadedBy(previous, clazz)) {
- classMapEntries.remove();
+ methods.remove();
}
}
loader = current;