From da758771fadc68ff6bb30db5d86e9b4ce277d5c1 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 1 Sep 2010 17:17:25 +0000 Subject: [PATCH] consistent use of JDK 1.5's ThreadLocal.remove() over ThreadLocal.set(null), preventing leaks (SPR-7441) git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3627 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../aop/framework/AopContext.java | 9 +++++++-- .../aop/target/ThreadLocalTargetSource.java | 4 ++-- .../factory/support/AbstractBeanFactory.java | 4 ++-- .../factory/xml/XmlBeanDefinitionReader.java | 2 +- .../quartz/SchedulerFactoryBean.java | 10 +++++----- .../context/i18n/LocaleContextHolder.java | 10 +++++----- .../UserCredentialsDataSourceAdapter.java | 4 ++-- ...serCredentialsConnectionFactoryAdapter.java | 4 ++-- .../hibernate3/LocalSessionFactoryBean.java | 18 +++++++++--------- .../orm/hibernate3/SessionFactoryUtils.java | 2 +- .../orm/ibatis/SqlMapClientFactoryBean.java | 4 ++-- ...ConnectionSpecConnectionFactoryAdapter.java | 4 ++-- .../TransactionSynchronizationManager.java | 4 ++-- .../context/request/RequestContextHolder.java | 10 +++++----- 14 files changed, 47 insertions(+), 42 deletions(-) diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/framework/AopContext.java b/org.springframework.aop/src/main/java/org/springframework/aop/framework/AopContext.java index 00317a97d8f..299ebfa31ac 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/framework/AopContext.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/framework/AopContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -76,7 +76,12 @@ public abstract class AopContext { */ static Object setCurrentProxy(Object proxy) { Object old = currentProxy.get(); - currentProxy.set(proxy); + if (proxy != null) { + currentProxy.set(proxy); + } + else { + currentProxy.remove(); + } return old; } diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java b/org.springframework.aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java index ccc4d2e32b7..ab6f213471b 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2010 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. @@ -106,7 +106,7 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource this.targetSet.clear(); } // Clear ThreadLocal, just in case. - this.targetInThread.set(null); + this.targetInThread.remove(); } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 4946a7f3a0a..b764e2efdb5 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -904,13 +904,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp protected void afterPrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { - this.prototypesCurrentlyInCreation.set(null); + this.prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set beanNameSet = (Set) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { - this.prototypesCurrentlyInCreation.set(null); + this.prototypesCurrentlyInCreation.remove(); } } } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java index 105bebef992..fb7f12c6292 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java @@ -344,7 +344,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { - this.resourcesCurrentlyBeingLoaded.set(null); + this.resourcesCurrentlyBeingLoaded.remove(); } } } diff --git a/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java index c52418dc952..24c42e341cb 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java +++ b/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -496,16 +496,16 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe finally { if (this.resourceLoader != null) { - configTimeResourceLoaderHolder.set(null); + configTimeResourceLoaderHolder.remove(); } if (this.taskExecutor != null) { - configTimeTaskExecutorHolder.set(null); + configTimeTaskExecutorHolder.remove(); } if (this.dataSource != null) { - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } if (this.nonTransactionalDataSource != null) { - configTimeNonTransactionalDataSourceHolder.set(null); + configTimeNonTransactionalDataSourceHolder.remove(); } } diff --git a/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java b/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java index f57e9b60d1c..bbe245e0964 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java +++ b/org.springframework.context/src/main/java/org/springframework/context/i18n/LocaleContextHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -51,8 +51,8 @@ public abstract class LocaleContextHolder { * Reset the LocaleContext for the current thread. */ public static void resetLocaleContext() { - localeContextHolder.set(null); - inheritableLocaleContextHolder.set(null); + localeContextHolder.remove(); + inheritableLocaleContextHolder.remove(); } /** @@ -75,11 +75,11 @@ public abstract class LocaleContextHolder { public static void setLocaleContext(LocaleContext localeContext, boolean inheritable) { if (inheritable) { inheritableLocaleContextHolder.set(localeContext); - localeContextHolder.set(null); + localeContextHolder.remove(); } else { localeContextHolder.set(localeContext); - inheritableLocaleContextHolder.set(null); + inheritableLocaleContextHolder.remove(); } } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java index 629b5a4953c..166c4d5477b 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -114,7 +114,7 @@ public class UserCredentialsDataSourceAdapter extends DelegatingDataSource { * @see #setCredentialsForCurrentThread */ public void removeCredentialsFromCurrentThread() { - this.threadBoundCredentials.set(null); + this.threadBoundCredentials.remove(); } diff --git a/org.springframework.jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java b/org.springframework.jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java index b8c2905efd5..bf4b44f6cc5 100644 --- a/org.springframework.jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java +++ b/org.springframework.jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -131,7 +131,7 @@ public class UserCredentialsConnectionFactoryAdapter * @see #setCredentialsForCurrentThread */ public void removeCredentialsFromCurrentThread() { - this.threadBoundCredentials.set(null); + this.threadBoundCredentials.remove(); } diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java index 5bc2c55ec2b..35039b2991d 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java @@ -776,19 +776,19 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen finally { if (dataSource != null) { - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } if (this.jtaTransactionManager != null) { - configTimeTransactionManagerHolder.set(null); + configTimeTransactionManagerHolder.remove(); } if (this.cacheRegionFactory != null) { - configTimeCacheProviderHolder.set(null); + configTimeCacheProviderHolder.remove(); } if (this.cacheProvider != null) { - configTimeCacheProviderHolder.set(null); + configTimeCacheProviderHolder.remove(); } if (this.lobHandler != null) { - configTimeLobHandlerHolder.set(null); + configTimeLobHandlerHolder.remove(); } if (overrideClassLoader) { // Reset original thread context ClassLoader. @@ -896,7 +896,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen finally { if (dataSource != null) { // Reset DataSource holder. - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } } } @@ -942,7 +942,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen } finally { if (dataSource != null) { - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } } } @@ -984,7 +984,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen } finally { if (dataSource != null) { - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } } } @@ -1054,7 +1054,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen } finally { if (dataSource != null) { - configTimeDataSourceHolder.set(null); + configTimeDataSourceHolder.remove(); } } } diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java index 7ee2a4d662a..cd6be8810ef 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java @@ -735,7 +735,7 @@ public abstract class SessionFactoryUtils { closeSession(session); } if (holderMap.isEmpty()) { - deferredCloseHolder.set(null); + deferredCloseHolder.remove(); } } diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java index dd3437d3a4e..cb317408661 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -306,7 +306,7 @@ public class SqlMapClientFactoryBean implements FactoryBean, Initi finally { if (this.lobHandler != null) { // Reset LobHandler holder. - configTimeLobHandlerHolder.set(null); + configTimeLobHandlerHolder.remove(); } } } diff --git a/org.springframework.transaction/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java b/org.springframework.transaction/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java index c2ab35369c2..f3baaf59bc2 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java +++ b/org.springframework.transaction/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -96,7 +96,7 @@ public class ConnectionSpecConnectionFactoryAdapter extends DelegatingConnection * @see #setConnectionSpecForCurrentThread */ public void removeConnectionSpecFromCurrentThread() { - this.threadBoundSpec.set(null); + this.threadBoundSpec.remove(); } diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java index e68398389fa..ff10f7fe0ef 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java +++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java @@ -223,7 +223,7 @@ public abstract class TransactionSynchronizationManager { Object value = map.remove(actualKey); // Remove entire ThreadLocal if empty... if (map.isEmpty()) { - resources.set(null); + resources.remove(); } if (value != null && logger.isTraceEnabled()) { logger.trace("Removed value [" + value + "] for key [" + actualKey + "] from thread [" + @@ -314,7 +314,7 @@ public abstract class TransactionSynchronizationManager { throw new IllegalStateException("Cannot deactivate transaction synchronization - not active"); } logger.trace("Clearing transaction synchronization"); - synchronizations.set(null); + synchronizations.remove(); } diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java b/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java index 6e980cafd42..0894644fd4e 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/request/RequestContextHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -57,8 +57,8 @@ public abstract class RequestContextHolder { * Reset the RequestAttributes for the current thread. */ public static void resetRequestAttributes() { - requestAttributesHolder.set(null); - inheritableRequestAttributesHolder.set(null); + requestAttributesHolder.remove(); + inheritableRequestAttributesHolder.remove(); } /** @@ -80,11 +80,11 @@ public abstract class RequestContextHolder { public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable) { if (inheritable) { inheritableRequestAttributesHolder.set(attributes); - requestAttributesHolder.set(null); + requestAttributesHolder.remove(); } else { requestAttributesHolder.set(attributes); - inheritableRequestAttributesHolder.set(null); + inheritableRequestAttributesHolder.remove(); } }