LANG-369 - must use fixed object as lock target

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@755391 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2009-03-17 20:54:52 +00:00
parent c57a47f9cc
commit e8512544ed
1 changed files with 15 additions and 7 deletions

View File

@ -28,6 +28,9 @@
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.NullArgumentException; import org.apache.commons.lang.NullArgumentException;
@ -46,6 +49,7 @@
* @since 1.0 * @since 1.0
* @version $Id$ * @version $Id$
*/ */
@ThreadSafe
public class ExceptionUtils { public class ExceptionUtils {
/** /**
@ -56,9 +60,13 @@ public class ExceptionUtils {
*/ */
static final String WRAPPED_MARKER = " [wrapped] "; static final String WRAPPED_MARKER = " [wrapped] ";
// Lock object for CAUSE_METHOD_NAMES
private static final Object CAUSE_METHOD_NAMES_LOCK = new Object();
/** /**
* <p>The names of methods commonly used to access a wrapped exception.</p> * <p>The names of methods commonly used to access a wrapped exception.</p>
*/ */
@GuardedBy("CAUSE_METHOD_NAMES_LOCK")
private static String[] CAUSE_METHOD_NAMES = { private static String[] CAUSE_METHOD_NAMES = {
"getCause", "getCause",
"getNextException", "getNextException",
@ -123,7 +131,7 @@ public static void addCauseMethodName(String methodName) {
if (StringUtils.isNotEmpty(methodName) && !isCauseMethodName(methodName)) { if (StringUtils.isNotEmpty(methodName) && !isCauseMethodName(methodName)) {
List<String> list = getCauseMethodNameList(); List<String> list = getCauseMethodNameList();
if (list.add(methodName)) { if (list.add(methodName)) {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
CAUSE_METHOD_NAMES = toArray(list); CAUSE_METHOD_NAMES = toArray(list);
} }
} }
@ -142,7 +150,7 @@ public static void removeCauseMethodName(String methodName) {
if (StringUtils.isNotEmpty(methodName)) { if (StringUtils.isNotEmpty(methodName)) {
List<String> list = getCauseMethodNameList(); List<String> list = getCauseMethodNameList();
if (list.remove(methodName)) { if (list.remove(methodName)) {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
CAUSE_METHOD_NAMES = toArray(list); CAUSE_METHOD_NAMES = toArray(list);
} }
} }
@ -222,7 +230,7 @@ private static String[] toArray(List<String> list) {
* @return {@link #CAUSE_METHOD_NAMES} as a List. * @return {@link #CAUSE_METHOD_NAMES} as a List.
*/ */
private static ArrayList<String> getCauseMethodNameList() { private static ArrayList<String> getCauseMethodNameList() {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
return new ArrayList<String>(Arrays.asList(CAUSE_METHOD_NAMES)); return new ArrayList<String>(Arrays.asList(CAUSE_METHOD_NAMES));
} }
} }
@ -237,7 +245,7 @@ private static ArrayList<String> getCauseMethodNameList() {
* @since 2.1 * @since 2.1
*/ */
public static boolean isCauseMethodName(String methodName) { public static boolean isCauseMethodName(String methodName) {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
return ArrayUtils.indexOf(CAUSE_METHOD_NAMES, methodName) >= 0; return ArrayUtils.indexOf(CAUSE_METHOD_NAMES, methodName) >= 0;
} }
} }
@ -274,7 +282,7 @@ public static boolean isCauseMethodName(String methodName) {
* @since 1.0 * @since 1.0
*/ */
public static Throwable getCause(Throwable throwable) { public static Throwable getCause(Throwable throwable) {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
return getCause(throwable, CAUSE_METHOD_NAMES); return getCause(throwable, CAUSE_METHOD_NAMES);
} }
} }
@ -304,7 +312,7 @@ public static Throwable getCause(Throwable throwable, String[] methodNames) {
Throwable cause = getCauseUsingWellKnownTypes(throwable); Throwable cause = getCauseUsingWellKnownTypes(throwable);
if (cause == null) { if (cause == null) {
if (methodNames == null) { if (methodNames == null) {
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
methodNames = CAUSE_METHOD_NAMES; methodNames = CAUSE_METHOD_NAMES;
} }
} }
@ -463,7 +471,7 @@ public static boolean isNestedThrowable(Throwable throwable) {
} }
Class<? extends Throwable> cls = throwable.getClass(); Class<? extends Throwable> cls = throwable.getClass();
synchronized(CAUSE_METHOD_NAMES) { synchronized(CAUSE_METHOD_NAMES_LOCK) {
for (int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++) { for (int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++) {
try { try {
Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], (Class[]) null); Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], (Class[]) null);