diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java index 0a186d7889..7d2c7bce47 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java @@ -17,6 +17,7 @@ package org.springframework.jms.listener; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; @@ -25,7 +26,6 @@ import jakarta.jms.JMSException; import jakarta.jms.MessageConsumer; import jakarta.jms.Session; -import org.springframework.core.Constants; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskExecutor; import org.springframework.jms.JmsException; @@ -115,6 +115,7 @@ import org.springframework.util.backoff.FixedBackOff; * before listener execution, with no redelivery in case of an exception. * * @author Juergen Hoeller + * @author Sam Brannen * @since 2.0 * @see #setTransactionManager * @see #setCacheLevel @@ -171,7 +172,17 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe public static final int CACHE_AUTO = 4; - private static final Constants constants = new Constants(DefaultMessageListenerContainer.class); + /** + * Map of constant names to constant values for the cache constants defined + * in this class. + */ + private static final Map constants = Map.of( + "CACHE_NONE", CACHE_NONE, + "CACHE_CONNECTION", CACHE_CONNECTION, + "CACHE_SESSION", CACHE_SESSION, + "CACHE_CONSUMER", CACHE_CONSUMER, + "CACHE_AUTO", CACHE_AUTO + ); @Nullable @@ -266,10 +277,10 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe * @see #CACHE_AUTO */ public void setCacheLevelName(String constantName) throws IllegalArgumentException { - if (!constantName.startsWith("CACHE_")) { - throw new IllegalArgumentException("Only cache constants allowed"); - } - setCacheLevel(constants.asNumber(constantName).intValue()); + Assert.hasText(constantName, "'constantName' must not be null or blank"); + Integer cacheLevel = constants.get(constantName); + Assert.notNull(cacheLevel, "Only cache constants allowed"); + setCacheLevel(cacheLevel); } /** diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java index a7a6e993d0..0d7fabdc30 100644 --- a/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/listener/DefaultMessageListenerContainerTests.java @@ -16,8 +16,11 @@ package org.springframework.jms.listener; +import java.lang.reflect.Field; +import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import jakarta.jms.Connection; import jakarta.jms.ConnectionFactory; @@ -27,11 +30,14 @@ import org.junit.jupiter.api.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.springframework.util.ReflectionUtils; import org.springframework.util.backoff.BackOff; import org.springframework.util.backoff.BackOffExecution; import org.springframework.util.backoff.FixedBackOff; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -42,6 +48,7 @@ import static org.mockito.Mockito.verify; * * @author Stephane Nicoll * @author Juergen Hoeller + * @author Sam Brannen */ class DefaultMessageListenerContainerTests { @@ -138,6 +145,32 @@ class DefaultMessageListenerContainerTests { container.destroy(); } + @Test + void setCacheLevelNameToUnsupportedValues() { + DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); + assertThatIllegalArgumentException().isThrownBy(() -> container.setCacheLevelName(null)); + assertThatIllegalArgumentException().isThrownBy(() -> container.setCacheLevelName(" ")); + assertThatIllegalArgumentException().isThrownBy(() -> container.setCacheLevelName("bogus")); + } + + /** + * This test effectively verifies that the internal 'constants' map is properly + * configured for all cache constants defined in {@link DefaultMessageListenerContainer}. + */ + @Test + void setCacheLevelNameToAllSupportedValues() { + DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); + streamCacheConstants() + .map(Field::getName) + .forEach(name -> assertThatNoException().isThrownBy(() -> container.setCacheLevelName(name))); + } + + + private static Stream streamCacheConstants() { + return Arrays.stream(DefaultMessageListenerContainer.class.getFields()) + .filter(ReflectionUtils::isPublicStaticFinal) + .filter(field -> field.getName().startsWith("CACHE_")); + } private static DefaultMessageListenerContainer createRunningContainer() { DefaultMessageListenerContainer container = createContainer(createSuccessfulConnectionFactory());