Please check this long addition carefully. Hopefully the in-code comments should describe the reasons for this change but I'll outline them here as well. ClassLoader#getParent can return null to indicate the bootstrap classloader. Sun's implementations do not but this behaviour might be encountered in other JVMs. I haven't been able to test this patch so please check this very carefully.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@375631 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -839,6 +839,11 @@ public class LogFactoryImpl extends LogFactory {
|
|||||||
Class logAdapterClass = null;
|
Class logAdapterClass = null;
|
||||||
ClassLoader currentCL = getBaseClassLoader();
|
ClassLoader currentCL = getBaseClassLoader();
|
||||||
|
|
||||||
|
//
|
||||||
|
// This variable is used to ensure that the system classloader
|
||||||
|
// is tried only once when getParent is null.
|
||||||
|
boolean systemClassloaderTried = false;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// Loop through the classloader hierarchy trying to find
|
// Loop through the classloader hierarchy trying to find
|
||||||
// a viable classloader.
|
// a viable classloader.
|
||||||
@@ -934,7 +939,66 @@ public class LogFactoryImpl extends LogFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try the parent classloader
|
// try the parent classloader
|
||||||
currentCL = currentCL.getParent();
|
final ClassLoader parentCL = currentCL.getParent();
|
||||||
|
|
||||||
|
//
|
||||||
|
// getParent may return null to indicate that the parent
|
||||||
|
// is the 'bootstrap classloader'. This term is difficult.
|
||||||
|
// A reasonable way to interpret this is as
|
||||||
|
// the system classloader which is provided as a base
|
||||||
|
// for delegating classloaders.
|
||||||
|
//
|
||||||
|
// Note that this functionality cannot be easily tested
|
||||||
|
// since it depends upon an optional behaviour of the basic
|
||||||
|
// java libraries. The Sun libraries do not behave in this
|
||||||
|
// fashion. It may be possible to create a test that
|
||||||
|
// uses a customized boot classpath containing a special
|
||||||
|
// implementation but this approach
|
||||||
|
// would need to wait until an open source Java implementation
|
||||||
|
// exists. So sadly, this code path is not unit tested.
|
||||||
|
//
|
||||||
|
if (parentCL == null) {
|
||||||
|
if (systemClassloaderTried == true)
|
||||||
|
{
|
||||||
|
logDiagnostic("Parent classloader is NULL. But System ClassLoader has already been tried.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// try system classloader
|
||||||
|
try {
|
||||||
|
final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
if (systemClassLoader == null) {
|
||||||
|
logDiagnostic("System classloader is NULL. Cannot find parent of classloader "
|
||||||
|
+ objectId(currentCL));
|
||||||
|
break;
|
||||||
|
} else if (systemClassLoader.equals(currentCL)) {
|
||||||
|
// the system classloader has already been tried and failed
|
||||||
|
logDiagnostic("System classloader tried and failed.");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// the parent is null indicating that the parent is the boot classloader
|
||||||
|
// so retry with system classloader
|
||||||
|
currentCL = systemClassLoader;
|
||||||
|
|
||||||
|
//
|
||||||
|
// avoid infinite loops by trying the system loader only the
|
||||||
|
// first time a classloader
|
||||||
|
systemClassloaderTried = true;
|
||||||
|
logDiagnostic("Parent classloader is NULL. Trying System ClassLoader.");
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// getSystemClassLoader is allowed to fail in
|
||||||
|
// many strange ways: so need to catch everything
|
||||||
|
// including errors
|
||||||
|
logDiagnostic("Failed to get system classloader: '"
|
||||||
|
+ t.getMessage()
|
||||||
|
+ "'. Cannot find parent of classloader "
|
||||||
|
+ objectId(currentCL));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentCL = parentCL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((logAdapter != null) && affectState) {
|
if ((logAdapter != null) && affectState) {
|
||||||
|
|||||||
Reference in New Issue
Block a user