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:
parent
c57a47f9cc
commit
e8512544ed
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue