Browse Source

Merge branch '5.1.x'

pull/23006/head
Juergen Hoeller 7 years ago
parent
commit
a363fed209
  1. 2
      build.gradle
  2. 19
      spring-beans/src/test/java/org/springframework/beans/factory/xml/support/DefaultNamespaceHandlerResolverTests.java
  3. 54
      spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java
  4. 4
      spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java
  5. 4
      spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
  6. 4
      spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd

2
build.gradle

@ -33,7 +33,7 @@ ext {
freemarkerVersion = "2.3.28" freemarkerVersion = "2.3.28"
groovyVersion = "2.5.7" groovyVersion = "2.5.7"
hsqldbVersion = "2.4.1" hsqldbVersion = "2.4.1"
jackson2Version = "2.9.8" jackson2Version = "2.9.9"
jettyVersion = "9.4.18.v20190429" jettyVersion = "9.4.18.v20190429"
junit5Version = "5.4.2" junit5Version = "5.4.2"
kotlinVersion = "1.3.31" kotlinVersion = "1.3.31"

19
spring-beans/src/test/java/org/springframework/beans/factory/xml/support/DefaultNamespaceHandlerResolverTests.java

@ -51,7 +51,7 @@ public class DefaultNamespaceHandlerResolverTests {
} }
@Test @Test
public void testNonExistentHandlerClass() throws Exception { public void testNonExistentHandlerClass() {
String mappingPath = "org/springframework/beans/factory/xml/support/nonExistent.properties"; String mappingPath = "org/springframework/beans/factory/xml/support/nonExistent.properties";
try { try {
new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), mappingPath); new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), mappingPath);
@ -63,29 +63,18 @@ public class DefaultNamespaceHandlerResolverTests {
} }
@Test @Test
public void testResolveInvalidHandler() throws Exception { public void testCtorWithNullClassLoaderArgument() {
String mappingPath = "org/springframework/beans/factory/xml/support/invalid.properties";
try {
new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), mappingPath);
fail("Should not be able to map a class that doesn't implement NamespaceHandler");
}
catch (Throwable expected) {
}
}
@Test
public void testCtorWithNullClassLoaderArgument() throws Exception {
// simply must not bail... // simply must not bail...
new DefaultNamespaceHandlerResolver(null); new DefaultNamespaceHandlerResolver(null);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testCtorWithNullClassLoaderArgumentAndNullMappingLocationArgument() throws Exception { public void testCtorWithNullClassLoaderArgumentAndNullMappingLocationArgument() {
new DefaultNamespaceHandlerResolver(null, null); new DefaultNamespaceHandlerResolver(null, null);
} }
@Test @Test
public void testCtorWithNonExistentMappingLocationArgument() throws Exception { public void testCtorWithNonExistentMappingLocationArgument() {
// simply must not bail; we don't want non-existent resources to result in an Exception // simply must not bail; we don't want non-existent resources to result in an Exception
new DefaultNamespaceHandlerResolver(null, "738trbc bobabloobop871"); new DefaultNamespaceHandlerResolver(null, "738trbc bobabloobop871");
} }

54
spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -66,6 +66,8 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
private boolean connectLazily = false; private boolean connectLazily = false;
private boolean recoverOnException = true;
private int concurrentConsumers = 1; private int concurrentConsumers = 1;
@Nullable @Nullable
@ -94,6 +96,21 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
this.connectLazily = connectLazily; this.connectLazily = connectLazily;
} }
/**
* Specify whether to explicitly recover the shared JMS Connection and the
* associated Sessions and MessageConsumers whenever a JMSException is reported.
* <p>Default is "true": refreshing the shared connection and re-initializing the
* consumers whenever the connection propagates an exception to its listener.
* Set this flag to "false" in order to rely on automatic recovery within the
* provider, holding on to the existing connection and consumer handles.
* @since 5.1.8
* @see #onException(JMSException)
* @see Connection#setExceptionListener
*/
public void setRecoverOnException(boolean recoverOnException) {
this.recoverOnException = recoverOnException;
}
/** /**
* Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or a simple * Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or a simple
* upper limit String, e.g. "10". * upper limit String, e.g. "10".
@ -227,8 +244,11 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
/** /**
* JMS ExceptionListener implementation, invoked by the JMS provider in * JMS ExceptionListener implementation, invoked by the JMS provider in
* case of connection failures. Re-initializes this listener container's * case of connection failures. Re-initializes this listener container's
* shared connection and its sessions and consumers. * shared connection and its sessions and consumers, if necessary.
* @param ex the reported connection exception * @param ex the reported connection exception
* @see #setRecoverOnException
* @see #refreshSharedConnection()
* @see #initializeConsumers()
*/ */
@Override @Override
public void onException(JMSException ex) { public void onException(JMSException ex) {
@ -236,21 +256,23 @@ public class SimpleMessageListenerContainer extends AbstractMessageListenerConta
invokeExceptionListener(ex); invokeExceptionListener(ex);
// Now try to recover the shared Connection and all consumers... // Now try to recover the shared Connection and all consumers...
if (logger.isDebugEnabled()) { if (this.recoverOnException) {
logger.debug("Trying to recover from JMS Connection exception: " + ex); if (logger.isDebugEnabled()) {
} logger.debug("Trying to recover from JMS Connection exception: " + ex);
try { }
synchronized (this.consumersMonitor) { try {
this.sessions = null; synchronized (this.consumersMonitor) {
this.consumers = null; this.sessions = null;
this.consumers = null;
}
refreshSharedConnection();
initializeConsumers();
logger.debug("Successfully refreshed JMS Connection");
}
catch (JMSException recoverEx) {
logger.debug("Failed to recover JMS Connection", recoverEx);
logger.error("Encountered non-recoverable JMSException", ex);
} }
refreshSharedConnection();
initializeConsumers();
logger.debug("Successfully refreshed JMS Connection");
}
catch (JMSException recoverEx) {
logger.debug("Failed to recover JMS Connection", recoverEx);
logger.error("Encountered non-recoverable JMSException", ex);
} }
} }

4
spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java

@ -202,8 +202,8 @@ public class MultipartHttpMessageWriter extends LoggingCodecSupport
if (contentType != null) { if (contentType != null) {
return MediaType.MULTIPART_FORM_DATA.includes(contentType); return MediaType.MULTIPART_FORM_DATA.includes(contentType);
} }
for (String name : map.keySet()) { for (List<?> values : map.values()) {
for (Object value : map.get(name)) { for (Object value : values) {
if (value != null && !(value instanceof String)) { if (value != null && !(value instanceof String)) {
return true; return true;
} }

4
spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java

@ -280,8 +280,8 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
if (contentType != null) { if (contentType != null) {
return MediaType.MULTIPART_FORM_DATA.includes(contentType); return MediaType.MULTIPART_FORM_DATA.includes(contentType);
} }
for (String name : map.keySet()) { for (List<?> values : map.values()) {
for (Object value : map.get(name)) { for (Object value : values) {
if (value != null && !(value instanceof String)) { if (value != null && !(value instanceof String)) {
return true; return true;
} }

4
spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd

@ -601,8 +601,8 @@
<xsd:attribute name="stale-if-error" type="xsd:int" use="optional"> <xsd:attribute name="stale-if-error" type="xsd:int" use="optional">
<xsd:annotation> <xsd:annotation>
<xsd:documentation><![CDATA[ <xsd:documentation><![CDATA[
Adds a "s-maxage" directive in the Cache-Control header. Adds a "stale-if-error" directive in the Cache-Control header.
This directive has the same meaning as the "max-age" directive, except it only applies to shared caches. When an error is encountered, a cached stale response may be used for the given number of seconds.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
</xsd:attribute> </xsd:attribute>

Loading…
Cancel
Save