diff --git a/pom.xml b/pom.xml index 03f22f7ce00..c1e0319d8e6 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ LTS releases. These are 8, 11, 12 and 21 currently, see: https://github.com/apache/commons-lang/blob/master/.github/workflows/maven.yml - + Please ensure your build environment is up-to-date and kindly report any build issues. @@ -111,7 +111,7 @@ ggregory at apache.org https://www.garygregory.com The Apache Software Foundation - https://www.apache.org/ + https://www.apache.org/ PMC Member @@ -775,6 +775,38 @@ ${basedir}/src/conf/spotbugs-exclude-filter.xml + + org.moditect + moditect-maven-plugin + + + add-module-infos + package + + add-module-info + + + ${moditect.java.version} + ${project.build.directory} + true + false + + + ${commons.module.name} + + *; + + + static java.desktop; + *; + + ${commons.moditect-maven-plugin.addServiceUses} + + + + + + @@ -945,10 +977,10 @@ maven-surefire-plugin - org/apache/commons/lang3/time/Java15BugFastDateParserTest.java + org/apache/commons/lang3/time/Java15BugFastDateParserTest.java - + diff --git a/src/main/java/org/apache/commons/lang3/concurrent/AbstractCircuitBreaker.java b/src/main/java/org/apache/commons/lang3/concurrent/AbstractCircuitBreaker.java index 1d6762928a3..fd4ec3012de 100644 --- a/src/main/java/org/apache/commons/lang3/concurrent/AbstractCircuitBreaker.java +++ b/src/main/java/org/apache/commons/lang3/concurrent/AbstractCircuitBreaker.java @@ -86,14 +86,21 @@ protected static boolean isOpen(final State state) { /** The current state of this circuit breaker. */ protected final AtomicReference state = new AtomicReference<>(State.CLOSED); + /** + * Monitor for usages of change support to enable lazy initialization of that field. + * This lets us require the {@code java.desktop} module statically, significantly reducing + * the jlink-ed size of all downstream apache commons libraries. + */ + private final Object changeSupportMonitor = new Object(); + /** An object for managing change listeners registered at this instance. */ - private final PropertyChangeSupport changeSupport; + private PropertyChangeSupport changeSupport; /** * Creates an {@link AbstractCircuitBreaker}. It also creates an internal {@link PropertyChangeSupport}. */ public AbstractCircuitBreaker() { - changeSupport = new PropertyChangeSupport(this); + changeSupport = null; } /** @@ -101,10 +108,21 @@ public AbstractCircuitBreaker() { * the state of this circuit breaker changes. If the listener is * null, it is silently ignored. * + *

+ * If the {@code java.desktop} module is not present in the JRE, + * calling this method will throw an exception. + *

+ * * @param listener the listener to be added */ public void addChangeListener(final PropertyChangeListener listener) { - changeSupport.addPropertyChangeListener(listener); + synchronized (changeSupportMonitor) { + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + + changeSupport.addPropertyChangeListener(listener); + } } /** @@ -115,7 +133,11 @@ public void addChangeListener(final PropertyChangeListener listener) { */ protected void changeState(final State newState) { if (state.compareAndSet(newState.oppositeState(), newState)) { - changeSupport.firePropertyChange(PROPERTY_NAME, !isOpen(newState), isOpen(newState)); + synchronized (changeSupportMonitor) { + if (changeSupport != null) { + changeSupport.firePropertyChange(PROPERTY_NAME, !isOpen(newState), isOpen(newState)); + } + } } } @@ -169,7 +191,11 @@ public void open() { * @param listener the listener to be removed */ public void removeChangeListener(final PropertyChangeListener listener) { - changeSupport.removePropertyChangeListener(listener); + synchronized (changeSupportMonitor) { + if (changeSupport != null) { + changeSupport.removePropertyChangeListener(listener); + } + } } }