Code Monkey home page Code Monkey logo

Comments (2)

HelloCoCooo avatar HelloCoCooo commented on August 16, 2024

Code snippet of org.apache.commons.logging.LogFactory.getFactory in org.slf4j:jcl-over-slf4j:1.7.5 (shadowed but expected to invoke method):

static LogFactory logFactory = new SLF4JLogFactory();	//line 40

public static LogFactory getFactory() throws LogConfigurationException {	//line 258
  return logFactory;
}

Code snippet of org.apache.commons.logging.LogFactory.getFactory in commons-logging:commons-logging:1.1.3 (loaded version):

public static LogFactory getFactory() throws LogConfigurationException {	//line 419
  // Identify the class loader we will be using
  ClassLoader contextClassLoader = getContextClassLoaderInternal();

  if (contextClassLoader == null) {
    // This is an odd enough situation to report about. This
    // output will be a nuisance on JDK1.1, as the system
    // classloader is null in that environment.
    if (isDiagnosticsEnabled()) {
      logDiagnostic("Context classloader is null.");
    }
  }

  // Return any previously registered factory for this class loader
  LogFactory factory = getCachedFactory(contextClassLoader);
  if (factory != null) {
    return factory;
  }

  if (isDiagnosticsEnabled()) {
    logDiagnostic(
      "[LOOKUP] LogFactory implementation requested for the first time for context classloader " +
      objectId(contextClassLoader));
    logHierarchy("[LOOKUP] ", contextClassLoader);
  }

  // Load properties file.
  //
  // If the properties file exists, then its contents are used as
  // "attributes" on the LogFactory implementation class. One particular
  // property may also control which LogFactory concrete subclass is
  // used, but only if other discovery mechanisms fail..
  //
  // As the properties file (if it exists) will be used one way or
  // another in the end we may as well look for it first.

  Properties props = getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES);

  // Determine whether we will be using the thread context class loader to
  // load logging classes or not by checking the loaded properties file (if any).
  ClassLoader baseClassLoader = contextClassLoader;
  if (props != null) {
    String useTCCLStr = props.getProperty(TCCL_KEY);
    if (useTCCLStr != null) {
      // The Boolean.valueOf(useTCCLStr).booleanValue() formulation
      // is required for Java 1.2 compatibility.
      if (Boolean.valueOf(useTCCLStr).booleanValue() == false) {
        // Don't use current context classloader when locating any
        // LogFactory or Log classes, just use the class that loaded
        // this abstract class. When this class is deployed in a shared
        // classpath of a container, it means webapps cannot deploy their
        // own logging implementations. It also means that it is up to the
        // implementation whether to load library-specific config files
        // from the TCCL or not.
        baseClassLoader = thisClassLoader;
      }
    }
  }

  // Determine which concrete LogFactory subclass to use.
  // First, try a global system property
  if (isDiagnosticsEnabled()) {
    logDiagnostic("[LOOKUP] Looking for system property [" + FACTORY_PROPERTY +
                  "] to define the LogFactory subclass to use...");
  }

  try {
    String factoryClass = getSystemProperty(FACTORY_PROPERTY, null);
    if (factoryClass != null) {
      if (isDiagnosticsEnabled()) {
        logDiagnostic("[LOOKUP] Creating an instance of LogFactory class '" + factoryClass +
                      "' as specified by system property " + FACTORY_PROPERTY);
      }
      factory = newFactory(factoryClass, baseClassLoader, contextClassLoader);
    } else {
      if (isDiagnosticsEnabled()) {
        logDiagnostic("[LOOKUP] No system property [" + FACTORY_PROPERTY + "] defined.");
      }
    }
  } catch (SecurityException e) {
    if (isDiagnosticsEnabled()) {
      logDiagnostic("[LOOKUP] A security exception occurred while trying to create an" +
                    " instance of the custom factory class" + ": [" + trim(e.getMessage()) +
                    "]. Trying alternative implementations...");
    }
    // ignore
  } catch (RuntimeException e) {
    // This is not consistent with the behaviour when a bad LogFactory class is
    // specified in a services file.
    //
    // One possible exception that can occur here is a ClassCastException when
    // the specified class wasn't castable to this LogFactory type.
    if (isDiagnosticsEnabled()) {
      logDiagnostic("[LOOKUP] An exception occurred while trying to create an" +
                    " instance of the custom factory class" + ": [" +
                    trim(e.getMessage()) +
                    "] as specified by a system property.");
    }
    throw e;
  }

  // Second, try to find a service by using the JDK1.3 class
  // discovery mechanism, which involves putting a file with the name
  // of an interface class in the META-INF/services directory, where the
  // contents of the file is a single line specifying a concrete class
  // that implements the desired interface.

  if (factory == null) {
    if (isDiagnosticsEnabled()) {
      logDiagnostic("[LOOKUP] Looking for a resource file of name [" + SERVICE_ID +
                    "] to define the LogFactory subclass to use...");
    }
    try {
      final InputStream is = getResourceAsStream(contextClassLoader, SERVICE_ID);

      if( is != null ) {
        // This code is needed by EBCDIC and other strange systems.
        // It's a fix for bugs reported in xerces
        BufferedReader rd;
        try {
          rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        } catch (java.io.UnsupportedEncodingException e) {
          rd = new BufferedReader(new InputStreamReader(is));
        }

        String factoryClassName = rd.readLine();
        rd.close();

        if (factoryClassName != null && ! "".equals(factoryClassName)) {
          if (isDiagnosticsEnabled()) {
            logDiagnostic("[LOOKUP]  Creating an instance of LogFactory class " +
                          factoryClassName +
                          " as specified by file '" + SERVICE_ID +
                          "' which was present in the path of the context classloader.");
          }
          factory = newFactory(factoryClassName, baseClassLoader, contextClassLoader );
        }
      } else {
        // is == null
        if (isDiagnosticsEnabled()) {
          logDiagnostic("[LOOKUP] No resource file with name '" + SERVICE_ID + "' found.");
        }
      }
    } catch (Exception ex) {
      // note: if the specified LogFactory class wasn't compatible with LogFactory
      // for some reason, a ClassCastException will be caught here, and attempts will
      // continue to find a compatible class.
      if (isDiagnosticsEnabled()) {
        logDiagnostic(
          "[LOOKUP] A security exception occurred while trying to create an" +
          " instance of the custom factory class" +
          ": [" + trim(ex.getMessage()) +
          "]. Trying alternative implementations...");
      }
      // ignore
    }
  }

  // Third try looking into the properties file read earlier (if found)

  if (factory == null) {
    if (props != null) {
      if (isDiagnosticsEnabled()) {
        logDiagnostic(
          "[LOOKUP] Looking in properties file for entry with key '" + FACTORY_PROPERTY +
          "' to define the LogFactory subclass to use...");
      }
      String factoryClass = props.getProperty(FACTORY_PROPERTY);
      if (factoryClass != null) {
        if (isDiagnosticsEnabled()) {
          logDiagnostic(
            "[LOOKUP] Properties file specifies LogFactory subclass '" + factoryClass + "'");
        }
        factory = newFactory(factoryClass, baseClassLoader, contextClassLoader);

        // TODO: think about whether we need to handle exceptions from newFactory
      } else {
        if (isDiagnosticsEnabled()) {
          logDiagnostic("[LOOKUP] Properties file has no entry specifying LogFactory subclass.");
        }
      }
    } else {
      if (isDiagnosticsEnabled()) {
        logDiagnostic("[LOOKUP] No properties file available to determine" + " LogFactory subclass from..");
      }
    }
  }

  // Fourth, try the fallback implementation class

  if (factory == null) {
    if (isDiagnosticsEnabled()) {
      logDiagnostic(
        "[LOOKUP] Loading the default LogFactory implementation '" + FACTORY_DEFAULT +
        "' via the same classloader that loaded this LogFactory" +
        " class (ie not looking in the context classloader).");
    }

    // Note: unlike the above code which can try to load custom LogFactory
    // implementations via the TCCL, we don't try to load the default LogFactory
    // implementation via the context classloader because:
    // * that can cause problems (see comments in newFactory method)
    // * no-one should be customising the code of the default class
    // Yes, we do give up the ability for the child to ship a newer
    // version of the LogFactoryImpl class and have it used dynamically
    // by an old LogFactory class in the parent, but that isn't
    // necessarily a good idea anyway.
    factory = newFactory(FACTORY_DEFAULT, thisClassLoader, contextClassLoader);
  }

  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;
}

As a result, these conflicting method included in org.slf4j:jcl-over-slf4j:1.7.5 deals with different cases, which changes the control flows and data flows. So being forced to use these methods in commons-logging:commons-logging:1.1.3 may lead to inconsisitent semantic behaviors.

from travel.b2b.

HelloCoCooo avatar HelloCoCooo commented on August 16, 2024

@justinscript May I pull a request to fix it?

from travel.b2b.

Related Issues (10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.