rsitze      2002/06/11 15:29:14

  Modified:    logging/src/java/org/apache/commons/logging LogFactory.java
  Log:
  Resolve NullPointerExceptions, remove redundant checks, minor refactoring to 
facilitate readability.
  
  Revision  Changes    Path
  1.8       +110 -67   
jakarta-commons/logging/src/java/org/apache/commons/logging/LogFactory.java
  
  Index: LogFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/LogFactory.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LogFactory.java   4 May 2002 19:50:29 -0000       1.7
  +++ LogFactory.java   11 Jun 2002 22:29:14 -0000      1.8
  @@ -71,6 +71,7 @@
   import java.util.Enumeration;
   import java.util.Hashtable;
   import java.util.Properties;
  +import java.lang.SecurityException;
   
   
   /**
  @@ -257,22 +258,21 @@
       public static LogFactory getFactory() throws LogConfigurationException {
   
           // Identify the class loader we will be using
  -        ClassLoader classLoader = findClassLoader();
  +        ClassLoader contextClassLoader = getContextClassLoader();
   
           // Return any previously registered factory for this class loader
  -        LogFactory factory = (LogFactory) factories.get(classLoader);
  -        if (factory != null) {
  -            return (factory);
  -        }
  -        
  +        LogFactory factory = getCachedFactory(contextClassLoader);
  +        if (factory != null)
  +            return factory;
  +
           // First, try the system property
           try {
               String factoryClass = System.getProperty(FACTORY_PROPERTY);
               if (factoryClass != null) {
  -                factory = newFactory(factoryClass, classLoader);
  +                factory = newFactory(factoryClass, contextClassLoader);
               }
           } catch (SecurityException e) {
  -            ;
  +            ;  // ignore
           }
   
           // Second, try to find a service by using the JDK1.3 jar
  @@ -281,14 +281,11 @@
           // CLASSPATH or equivalent ). This is similar with the second
           // step, except that it uses the (standard?) jdk1.3 location in the jar.
   
  -        if( factory==null ) {
  +        if (factory == null) {
               try {
  -                InputStream is=null;
  -                if (classLoader == null) {
  -                    is=ClassLoader.getSystemResourceAsStream( SERVICE_ID );
  -                } else {
  -                    is=classLoader.getResourceAsStream( SERVICE_ID );
  -                }
  +                InputStream is = (contextClassLoader == null
  +                                  ? ClassLoader.getSystemResourceAsStream( 
SERVICE_ID )
  +                                  : contextClassLoader.getResourceAsStream( 
SERVICE_ID ));
   
                   if( is != null ) {
                       // This code is needed by EBCDIC and other strange systems.
  @@ -306,7 +303,7 @@
                       if (factoryClassName != null &&
                           ! "".equals(factoryClassName)) {
                           
  -                        factory= newFactory( factoryClassName, classLoader );
  +                        factory= newFactory( factoryClassName, contextClassLoader );
                       }
                   }
               } catch( Exception ex ) {
  @@ -327,7 +324,7 @@
   
           try {
               InputStream stream =
  -                classLoader.getResourceAsStream(FACTORY_PROPERTIES);
  +                contextClassLoader.getResourceAsStream(FACTORY_PROPERTIES);
               if (stream != null) {
                   props = new Properties();
                   props.load(stream);
  @@ -337,7 +334,7 @@
                       if (factoryClass == null) {
                           factoryClass = FACTORY_DEFAULT;
                       }
  -                    factory = newFactory(factoryClass, classLoader);
  +                    factory = newFactory(factoryClass, contextClassLoader);
                   }
               }
               // the properties will be set at the end.
  @@ -359,10 +356,7 @@
               }
           }
           
  -        // Cache and return the new factory instance
  -        factories.put(classLoader, factory);
  -        return (factory);
  -
  +        return factory;
       }
   
   
  @@ -428,51 +422,92 @@
   
   
       /**
  -     * Return the class loader to be used for loading the selected
  -     * <code>LogFactory</code> implementation class.  On a JDK 1.2 or later
  -     * system, the context class loader for the current thread will be used
  -     * if it is present.
  +     * 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
  +     * cannot be identified.
        */
  -    protected static ClassLoader findClassLoader()
  -        throws LogConfigurationException {
  +    protected static ClassLoader getContextClassLoader()
  +        throws LogConfigurationException
  +    {
  +        ClassLoader classLoader = null;
   
  -        // Are we running on a JDK 1.2 or later system?
  -        Method method = null;
           try {
  -            method = Thread.class.getMethod("getContextClassLoader", null);
  -        } catch (NoSuchMethodException e) {
  -            // Assume we are running on JDK 1.1
  -            return (LogFactory.class.getClassLoader());
  -        }
  +            // 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)
  -        ClassLoader classLoader = null;
  -        try {
  -            classLoader = (ClassLoader)
  -                method.invoke(Thread.currentThread(), null);
  -            if (classLoader == null) {
  -                classLoader = LogFactory.class.getClassLoader();
  +            // 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 (IllegalAccessException e) {
  -            throw new LogConfigurationException
  -                ("Unexpected IllegalAccessException", e);
  -        } catch (InvocationTargetException e) {
  -            throw new LogConfigurationException
  -                ("Unexpected InvocationTargetException", e);
  +        } catch (NoSuchMethodException e) {
  +            // Assume we are running on JDK 1.1
  +            classLoader = LogFactory.class.getClassLoader();
           }
   
           // Return the selected class loader
  -        return (classLoader);
  -
  +        return classLoader;
       }
   
  +    /**
  +     * Check cached factories (keyed by classLoader)
  +     */
  +    private static LogFactory getCachedFactory(ClassLoader contextClassLoader)
  +    {
  +        LogFactory factory = null;
  +        
  +        if (contextClassLoader != null)
  +            factory = (LogFactory) factories.get(contextClassLoader);
  +            
  +        if (factory==null)
  +            factory = (LogFactory) factories.get(LogFactory.class.getClassLoader());
  +        
  +        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
  @@ -487,24 +522,32 @@
       {
           
           try {
  +            if (classLoader == null)
  +                classLoader = LogFactory.class.getClassLoader();
  +
               Class clazz = null;
  -            if (classLoader == null) {
  -                clazz = Class.forName(factoryClass);
  -            } else {
  -                try {
  -                    // first the thread class loader
  +            try {
  +                // first the thread class loader
  +                clazz = classLoader.loadClass(factoryClass);
  +            } catch (ClassNotFoundException ex) {
  +                // if this failed (i.e. no implementation is
  +                // found in the webapp), try the caller's loader
  +                // if we haven't already...
  +                if (classLoader != LogFactory.class.getClassLoader()) {
  +                    classLoader = LogFactory.class.getClassLoader();
                       clazz = classLoader.loadClass(factoryClass);
  -                } catch( ClassNotFoundException ex ) {
  -                    // if this failed ( i.e. no implementation is
  -                    // found in the webapp itself ) try the
  -                    // caller's loader 
  -                    clazz = Class.forName( factoryClass );
                   }
               }
  -            return ((LogFactory) clazz.newInstance());
  +            
  +            LogFactory factory = (LogFactory)clazz.newInstance();
  +            
  +            // Cache using correct classLoader
  +            cacheFactory(classLoader, factory);
  +            
  +            return factory;
           } catch (Exception e) {
               throw new LogConfigurationException(e);
           }
   
       }
  -}
  +}
  \ No newline at end of file
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to