Commons Logging
  1. Commons Logging
  2. LOGGING-45

Default LogFactory Implementation fails for Log4J : ClassCastException

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0
    • Fix Version/s: 1.0.3
    • Labels:
      None
    • Environment:

      Operating System: other
      Platform: Other

      Description

      I've got Log4J 1.1.3 JAR in my classpath. Upon startup of my application
      (actually a JUnit test case), I immediately get:

      java.lang.ExceptionInInitializerError:
      org.apache.commons.logging.LogConfigurationException:
      java.lang.ClassCastException

      So I downloaded the Commons Logging 1.0 source and debugged. The problem is in
      org.apache.commons.logging.impl.LogFactoryImpl.guessConfig().

      Class proxyClass=findClassLoader().
      loadClass( "org.apache.commons.logging.Log4jFactory" );

      The above loadClass call should be changed to:

      Class proxyClass=findClassLoader().
      loadClass( "org.apache.commons.logging.impl.Log4jFactory" );

      However, after I make the above change I still get a ClassCastException, now
      from org.apache.commons.logging.LogFactory.newFactory(). This exception
      baffles me. It happens at:

      return (LogFactory) clazz.newInstance();

      So I modify newFactory() to do the newInstance() and the return in two steps
      instead of one.

      Object result = clazz.newInstance();
      return (LogFactory)result;

      The exception occurs during the cast of result. If I print result's class name
      I get org.apache.commons.logging.impl.LogFactoryImpl. But checking if result
      is an instanceof org.apache.commons.logging.impl.LogFactoryImpl returns false.

      Object result = clazz.newInstance();
      System.out.println("Got Factory: " + result.getClass().getName());

      if (result instanceof LogFactory)

      { System.out.println("result is a LogFactory"); }

      if (result instanceof org.apache.commons.logging.impl.LogFactoryImpl)

      { System.out.println("result is a LogFactoryImpl"); }

      return (LogFactory) result;

      The code above just prints:
      Got Factory: org.apache.commons.logging.impl.LogFactoryImpl

      And then throws the ClassCastException. I'm confused.

        Activity

        Hide
        Dave Wallace added a comment -

        I second this: I am seeing very much similiar behavior with Jdk 1.3 & 1.4 with
        the latest logging release and the 2002-7-30 snapshot. Somehow, the classname
        looks right but the class programmatically is not recognized as being a subclass
        of its parent.

        Show
        Dave Wallace added a comment - I second this: I am seeing very much similiar behavior with Jdk 1.3 & 1.4 with the latest logging release and the 2002-7-30 snapshot. Somehow, the classname looks right but the class programmatically is not recognized as being a subclass of its parent.
        Hide
        David Campbell added a comment -

        I'm seeing the same thing, with jdk 1.3.

        Show
        David Campbell added a comment - I'm seeing the same thing, with jdk 1.3.
        Hide
        Richard A. Sitze added a comment -

        This is a KNOWN problem with J2EE and (other) managed environments where there
        are multiple instances of commons-logging.jar (and/or commons-logging-api.jar).

        [I'm changing this to 'LATER' to move it out of the open problem category,
        but also to leave it open for futher comment/suggestions/discussion]

        The problem is that you have different parts of commons-logging being loaded
        by different classloaders, and though they have the same NAME, they are not
        the same class (diff classloader). So... class cast exception.

        This is NOT easily fixed in commons-logging, though providing details on your
        environments and any work-arounds you might be able to provide would be usefull.

        Any JUnit Guru's out there? Can this be caused by using commons-logging at
        various levels within the test suites?

        <ras>

        Show
        Richard A. Sitze added a comment - This is a KNOWN problem with J2EE and (other) managed environments where there are multiple instances of commons-logging.jar (and/or commons-logging-api.jar). [I'm changing this to 'LATER' to move it out of the open problem category, but also to leave it open for futher comment/suggestions/discussion] The problem is that you have different parts of commons-logging being loaded by different classloaders, and though they have the same NAME, they are not the same class (diff classloader). So... class cast exception. This is NOT easily fixed in commons-logging, though providing details on your environments and any work-arounds you might be able to provide would be usefull. Any JUnit Guru's out there? Can this be caused by using commons-logging at various levels within the test suites? <ras>
        Hide
        rdonkin@apache.org added a comment -

        commons-logging 1.0.3 released.

        Show
        rdonkin@apache.org added a comment - commons-logging 1.0.3 released.
        Hide
        Mohan Kishore added a comment -

        The reporters might like to check with the nightly build, whether the problem
        still persists. The guessConfig() method has been removed from
        org.apache.commons.logging.impl.LogFactoryImpl.

        Show
        Mohan Kishore added a comment - The reporters might like to check with the nightly build, whether the problem still persists. The guessConfig() method has been removed from org.apache.commons.logging.impl.LogFactoryImpl.
        Hide
        Craig McClanahan added a comment -

        Marking as closed, because as far as I can tell this works correctly with 1.0.3.

        As a side note, one cause for ClassCastException problems would be having
        commons-logging classes available from more than one class loader, and not being
        careful to ensure that all the c-l classes are loaded from the same class
        loader. A class "foo" loaded from class loader A and a class "foo" loaded from
        class loader B are not the same class, even if the bytecodes happen to be identical.
        Attempts to do assignments or casts between them will fail.

        Show
        Craig McClanahan added a comment - Marking as closed, because as far as I can tell this works correctly with 1.0.3. As a side note, one cause for ClassCastException problems would be having commons-logging classes available from more than one class loader, and not being careful to ensure that all the c-l classes are loaded from the same class loader. A class "foo" loaded from class loader A and a class "foo" loaded from class loader B are not the same class, even if the bytecodes happen to be identical. Attempts to do assignments or casts between them will fail.

          People

          • Assignee:
            Unassigned
            Reporter:
            Jerome Jacobsen
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development