From 165a6f186d64ef1d51a3c0f4954a6d5fe6700e4d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 19 Jul 2020 19:53:01 +0200 Subject: [PATCH 1/5] Expose setExceptionListener on AbstractJmsListenerContainerFactory Closes gh-22102 --- .../AbstractJmsListenerContainerFactory.java | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java index 46eb71333aa..39007467a0b 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerContainerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.jms.config; import javax.jms.ConnectionFactory; +import javax.jms.ExceptionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -48,10 +49,13 @@ public abstract class AbstractJmsListenerContainerFactory Date: Sun, 19 Jul 2020 19:53:29 +0200 Subject: [PATCH 2/5] Enforce ConditionalContentCachingResponseWrapper in ShallowEtagHeaderFilter Closes gh-24976 --- .../web/filter/ShallowEtagHeaderFilter.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index fb7abfeb8ed..6ef912a0bf7 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -99,7 +99,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { throws ServletException, IOException { HttpServletResponse responseToUse = response; - if (!isAsyncDispatch(request) && !(response instanceof ContentCachingResponseWrapper)) { + if (!isAsyncDispatch(request) && !(response instanceof ConditionalContentCachingResponseWrapper)) { responseToUse = new ConditionalContentCachingResponseWrapper(response, request); } @@ -111,10 +111,8 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { } private void updateResponse(HttpServletRequest request, HttpServletResponse response) throws IOException { - - ContentCachingResponseWrapper wrapper = - WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class); - + ConditionalContentCachingResponseWrapper wrapper = + WebUtils.getNativeResponse(response, ConditionalContentCachingResponseWrapper.class); Assert.notNull(wrapper, "ContentCachingResponseWrapper not found"); HttpServletResponse rawResponse = (HttpServletResponse) wrapper.getResponse(); @@ -219,7 +217,6 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { private final HttpServletRequest request; - ConditionalContentCachingResponseWrapper(HttpServletResponse response, HttpServletRequest request) { super(response); this.request = request; From 7b6924522a3c2c5e480550d88258096e39a07778 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 19 Jul 2020 19:55:19 +0200 Subject: [PATCH 3/5] Avoid unnecessarily alarming stack trace logged during scheduler resolution Closes gh-23268 --- .../ScheduledAnnotationBeanPostProcessor.java | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index f03d55f46ef..0ab8433a09f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -256,7 +256,10 @@ public class ScheduledAnnotationBeanPostProcessor this.registrar.setTaskScheduler(resolveSchedulerBean(this.beanFactory, TaskScheduler.class, false)); } catch (NoUniqueBeanDefinitionException ex) { - logger.trace("Could not find unique TaskScheduler bean", ex); + if (logger.isTraceEnabled()) { + logger.trace("Could not find unique TaskScheduler bean - attempting to resolve by name: " + + ex.getMessage()); + } try { this.registrar.setTaskScheduler(resolveSchedulerBean(this.beanFactory, TaskScheduler.class, true)); } @@ -271,13 +274,19 @@ public class ScheduledAnnotationBeanPostProcessor } } catch (NoSuchBeanDefinitionException ex) { - logger.trace("Could not find default TaskScheduler bean", ex); + if (logger.isTraceEnabled()) { + logger.trace("Could not find default TaskScheduler bean - attempting to find ScheduledExecutorService: " + + ex.getMessage()); + } // Search for ScheduledExecutorService bean next... try { this.registrar.setScheduler(resolveSchedulerBean(this.beanFactory, ScheduledExecutorService.class, false)); } catch (NoUniqueBeanDefinitionException ex2) { - logger.trace("Could not find unique ScheduledExecutorService bean", ex2); + if (logger.isTraceEnabled()) { + logger.trace("Could not find unique ScheduledExecutorService bean - attempting to resolve by name: " + + ex2.getMessage()); + } try { this.registrar.setScheduler(resolveSchedulerBean(this.beanFactory, ScheduledExecutorService.class, true)); } @@ -292,7 +301,10 @@ public class ScheduledAnnotationBeanPostProcessor } } catch (NoSuchBeanDefinitionException ex2) { - logger.trace("Could not find default ScheduledExecutorService bean", ex2); + if (logger.isTraceEnabled()) { + logger.trace("Could not find default ScheduledExecutorService bean - falling back to default: " + + ex2.getMessage()); + } // Giving up -> falling back to default scheduler within the registrar... logger.info("No TaskScheduler/ScheduledExecutorService bean found for scheduled processing"); } From 30bc5e09e72c340f92e224515f1198bd88ab6a3d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 19 Jul 2020 19:56:33 +0200 Subject: [PATCH 4/5] Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal Closes gh-22263 --- .../support/DefaultListableBeanFactory.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index dc0812cd6b2..9f0cb3c2635 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -558,6 +558,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto // Register exception, in case the bean was accidentally unresolvable. onSuppressedException(ex); } + catch (NoSuchBeanDefinitionException ex) { + // Bean definition got removed while we were iterating -> ignore. + } } } @@ -649,7 +652,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public String[] getBeanNamesForAnnotation(Class annotationType) { List result = new ArrayList<>(); for (String beanName : this.beanDefinitionNames) { - BeanDefinition beanDefinition = getBeanDefinition(beanName); + BeanDefinition beanDefinition = this.beanDefinitionMap.get(beanName); if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { result.add(beanName); } @@ -1721,18 +1724,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto */ private void checkBeanNotOfRequiredType(Class type, DependencyDescriptor descriptor) { for (String beanName : this.beanDefinitionNames) { - RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); - Class targetType = mbd.getTargetType(); - if (targetType != null && type.isAssignableFrom(targetType) && - isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) { - // Probably a proxy interfering with target type match -> throw meaningful exception. - Object beanInstance = getSingleton(beanName, false); - Class beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class ? - beanInstance.getClass() : predictBeanType(beanName, mbd)); - if (beanType != null && !type.isAssignableFrom(beanType)) { - throw new BeanNotOfRequiredTypeException(beanName, type, beanType); + try { + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + Class targetType = mbd.getTargetType(); + if (targetType != null && type.isAssignableFrom(targetType) && + isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) { + // Probably a proxy interfering with target type match -> throw meaningful exception. + Object beanInstance = getSingleton(beanName, false); + Class beanType = (beanInstance != null && beanInstance.getClass() != NullBean.class ? + beanInstance.getClass() : predictBeanType(beanName, mbd)); + if (beanType != null && !type.isAssignableFrom(beanType)) { + throw new BeanNotOfRequiredTypeException(beanName, type, beanType); + } } } + catch (NoSuchBeanDefinitionException ex) { + // Bean definition got removed while we were iterating -> ignore. + } } BeanFactory parent = getParentBeanFactory(); From 43e315f10c6021ef46f403f17b473ffd98c8474a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 19 Jul 2020 19:59:15 +0200 Subject: [PATCH 5/5] Unwrap SqlParameterValue for disposable value detection in cleanupParameters Closes gh-22972 --- .../jdbc/core/StatementCreatorUtils.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java index 60223545ac2..4d9da27bb55 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -312,7 +312,6 @@ public abstract class StatementCreatorUtils { else { ps.setClob(paramIndex, new StringReader(strVal), strVal.length()); } - return; } else { // Fallback: setString or setNString binding @@ -460,12 +459,17 @@ public abstract class StatementCreatorUtils { public static void cleanupParameters(@Nullable Collection paramValues) { if (paramValues != null) { for (Object inValue : paramValues) { - if (inValue instanceof DisposableSqlTypeValue) { - ((DisposableSqlTypeValue) inValue).cleanup(); + // Unwrap SqlParameterValue first... + if (inValue instanceof SqlParameterValue) { + inValue = ((SqlParameterValue) inValue).getValue(); } - else if (inValue instanceof SqlValue) { + // Check for disposable value types + if (inValue instanceof SqlValue) { ((SqlValue) inValue).cleanup(); } + else if (inValue instanceof DisposableSqlTypeValue) { + ((DisposableSqlTypeValue) inValue).cleanup(); + } } } }