📄 logfactory.java
字号:
// should be used to set the attributes ( which may be specific to
// the webapp, even if a default logger is set at JVM level by a
// system property )
if (factory == null && props != null) {
String factoryClass = props.getProperty(FACTORY_PROPERTY);
if (factoryClass != null) {
factory = newFactory(factoryClass, contextClassLoader);
}
}
// Fourth, try the fallback implementation class
if (factory == null) {
factory = newFactory(FACTORY_DEFAULT, LogFactory.class.getClassLoader());
}
if (factory != null) {
/**
* Always cache using context class loader.
*/
cacheFactory(contextClassLoader, factory);
if( props!=null ) {
Enumeration names = props.propertyNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String value = props.getProperty(name);
factory.setAttribute(name, value);
}
}
}
return factory;
}
/**
* Convenience method to return a named logger, without the application
* having to care about factories.
*
* @param clazz Class from which a log name will be derived
*
* @exception LogConfigurationException if a suitable <code>Log</code>
* instance cannot be returned
*/
public static Log getLog(Class clazz)
throws LogConfigurationException {
return (getFactory().getInstance(clazz));
}
/**
* Convenience method to return a named logger, without the application
* having to care about factories.
*
* @param name Logical name of the <code>Log</code> instance to be
* returned (the meaning of this name is only known to the underlying
* logging implementation that is being wrapped)
*
* @exception LogConfigurationException if a suitable <code>Log</code>
* instance cannot be returned
*/
public static Log getLog(String name)
throws LogConfigurationException {
return (getFactory().getInstance(name));
}
/**
* Release any internal references to previously created {@link LogFactory}
* instances that have been associated with the specified class loader
* (if any), after calling the instance method <code>release()</code> on
* each of them.
*
* @param classLoader ClassLoader for which to release the LogFactory
*/
public static void release(ClassLoader classLoader) {
synchronized (factories) {
LogFactory factory = (LogFactory) factories.get(classLoader);
if (factory != null) {
factory.release();
factories.remove(classLoader);
}
}
}
/**
* Release any internal references to previously created {@link LogFactory}
* instances, after calling the instance method <code>release()</code> on
* each of them. This is useful in environments like servlet containers,
* which implement application reloading by throwing away a ClassLoader.
* Dangling references to objects in that class loader would prevent
* garbage collection.
*/
public static void releaseAll() {
synchronized (factories) {
Enumeration elements = factories.elements();
while (elements.hasMoreElements()) {
LogFactory element = (LogFactory) elements.nextElement();
element.release();
}
factories.clear();
}
}
// ------------------------------------------------------ Protected Methods
/**
* Return the thread context class loader if available.
* Otherwise return null.
*
* The thread context class loader is available for JDK 1.2
* or later, if certain security conditions are met.
*
* @exception LogConfigurationException if a suitable class loader
* cannot be identified.
*/
protected static ClassLoader getContextClassLoader()
throws LogConfigurationException
{
ClassLoader classLoader = null;
try {
// Are we running on a JDK 1.2 or later system?
Method method = Thread.class.getMethod("getContextClassLoader", null);
// Get the thread context class loader (if there is one)
try {
classLoader = (ClassLoader)method.invoke(Thread.currentThread(), null);
} catch (IllegalAccessException e) {
throw new LogConfigurationException
("Unexpected IllegalAccessException", e);
} catch (InvocationTargetException e) {
/**
* InvocationTargetException is thrown by 'invoke' when
* the method being invoked (getContextClassLoader) throws
* an exception.
*
* getContextClassLoader() throws SecurityException when
* the context class loader isn't an ancestor of the
* calling class's class loader, or if security
* permissions are restricted.
*
* In the first case (not related), we want to ignore and
* keep going. We cannot help but also ignore the second
* with the logic below, but other calls elsewhere (to
* obtain a class loader) will trigger this exception where
* we can make a distinction.
*/
if (e.getTargetException() instanceof SecurityException) {
; // ignore
} else {
// Capture 'e.getTargetException()' exception for details
// alternate: log 'e.getTargetException()', and pass back 'e'.
throw new LogConfigurationException
("Unexpected InvocationTargetException", e.getTargetException());
}
}
} catch (NoSuchMethodException e) {
// Assume we are running on JDK 1.1
classLoader = LogFactory.class.getClassLoader();
}
// Return the selected class loader
return classLoader;
}
/**
* Check cached factories (keyed by contextClassLoader)
*/
private static LogFactory getCachedFactory(ClassLoader contextClassLoader)
{
LogFactory factory = null;
if (contextClassLoader != null)
factory = (LogFactory) factories.get(contextClassLoader);
return factory;
}
private static void cacheFactory(ClassLoader classLoader, LogFactory factory)
{
if (classLoader != null && factory != null)
factories.put(classLoader, factory);
}
/**
* Return a new instance of the specified <code>LogFactory</code>
* implementation class, loaded by the specified class loader.
* If that fails, try the class loader used to load this
* (abstract) LogFactory.
*
* @param factoryClass Fully qualified name of the <code>LogFactory</code>
* implementation class
* @param classLoader ClassLoader from which to load this class
*
* @exception LogConfigurationException if a suitable instance
* cannot be created
*/
protected static LogFactory newFactory(final String factoryClass,
final ClassLoader classLoader)
throws LogConfigurationException
{
// This will be used to diagnose bad configurations
// and allow a useful message to be sent to the user
Class logFactoryClass = null;
try {
if (classLoader != null) {
try {
// First the given class loader param (thread class loader)
// Warning: must typecast here & allow exception
// to be generated/caught & recast properly.
logFactoryClass = classLoader.loadClass(factoryClass);
return (LogFactory) logFactoryClass.newInstance();
} catch (ClassNotFoundException ex) {
if (classLoader == LogFactory.class.getClassLoader()) {
// Nothing more to try, onwards.
throw ex;
}
// ignore exception, continue
} catch (NoClassDefFoundError e) {
if (classLoader == LogFactory.class.getClassLoader()) {
// Nothing more to try, onwards.
throw e;
}
} catch(ClassCastException e){
if (classLoader == LogFactory.class.getClassLoader()) {
// Nothing more to try, onwards (bug in loader implementation).
throw e;
}
}
// Ignore exception, continue
}
/* At this point, either classLoader == null, OR
* classLoader was unable to load factoryClass.
* Try the class loader that loaded this class:
* LogFactory.getClassLoader().
*
* Notes:
* a) LogFactory.class.getClassLoader() may return 'null'
* if LogFactory is loaded by the bootstrap classloader.
* b) The Java endorsed library mechanism is instead
* Class.forName(factoryClass);
*/
// Warning: must typecast here & allow exception
// to be generated/caught & recast properly.
logFactoryClass = Class.forName(factoryClass);
return (LogFactory) logFactoryClass.newInstance();
} catch (Exception e) {
// Check to see if we've got a bad configuration
if (logFactoryClass != null
&& !LogFactory.class.isAssignableFrom(logFactoryClass)) {
throw new LogConfigurationException(
"The chosen LogFactory implementation does not extend LogFactory."
+ " Please check your configuration.",
e);
}
throw new LogConfigurationException(e);
}
}
private static InputStream getResourceAsStream(final ClassLoader loader,
final String name)
{
if (loader != null) {
return loader.getResourceAsStream(name);
} else {
return ClassLoader.getSystemResourceAsStream(name);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -