Log4j 2
  1. Log4j 2
  2. LOG4J2-51

ClassCastException in Category logger

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: log4j 1.2 emulation
    • Labels:
      None

      Description

      When a Category is "created" with the same name as a previously created log4j2 Logger, a ClassCastException occurs when calling category.l7dlog(...) and others.

      See LOG4J2-50 for additional symptoms.

        Activity

        Hide
        Ralph Goers added a comment -

        Patch was applied. Please verify and close.

        Show
        Ralph Goers added a comment - Patch was applied. Please verify and close.
        Hide
        John Vasileff added a comment -

        Yes, the patch in LOG4J2-50 is required to fix CategoryTest.testClassName().

        Where is the ClassCastException occurring? I wonder if this is due to some interaction between the IDE and mvn build where a mix of old and new versions are being used. Something like this happened to me, but after clean, etc., it cleared up.

        $ git log --oneline | head
        276d6e1 cleanup FQCN code
        bac5439 remove dangerous logger factory override
        12a7861 fix for Category.getInstance returning cached Logger
        d6e9975 add test for Category when using a log4j2 Logger
        2db42d3 Enhance comments on getThrowable
        cdc19e5 Test that class name in log message is correct

        $ mvn clean test
        ...
        [INFO] ------------------------------------------------------------------------
        [INFO] Reactor Summary:
        [INFO] ------------------------------------------------------------------------
        [INFO] Apache Log4j 2 ........................................ SUCCESS [1.454s]
        [INFO] Log4J API ............................................. SUCCESS [2.689s]
        [INFO] Log4J2 Core ........................................... SUCCESS [1:03.924s]
        [INFO] Log4J Compatibility API ............................... SUCCESS [3.471s]
        [INFO] SLF4J Binding ......................................... SUCCESS [2.244s]
        [INFO] Log4J2 Commons Logging ................................ SUCCESS [1.964s]
        [INFO] ------------------------------------------------------------------------
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESSFUL
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 1 minute 16 seconds
        [INFO] Finished at: Mon Sep 26 11:55:33 EDT 2011
        [INFO] Final Memory: 37M/265M
        [INFO] ------------------------------------------------------------------------

        $ cat log4j12-api/target/surefire-reports/org.apache.log4j.CategoryTest.txt
        -------------------------------------------------------------------------------
        Test set: org.apache.log4j.CategoryTest
        -------------------------------------------------------------------------------
        Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.657 sec

        Show
        John Vasileff added a comment - Yes, the patch in LOG4J2-50 is required to fix CategoryTest.testClassName(). Where is the ClassCastException occurring? I wonder if this is due to some interaction between the IDE and mvn build where a mix of old and new versions are being used. Something like this happened to me, but after clean, etc., it cleared up. $ git log --oneline | head 276d6e1 cleanup FQCN code bac5439 remove dangerous logger factory override 12a7861 fix for Category.getInstance returning cached Logger d6e9975 add test for Category when using a log4j2 Logger 2db42d3 Enhance comments on getThrowable cdc19e5 Test that class name in log message is correct $ mvn clean test ... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] ------------------------------------------------------------------------ [INFO] Apache Log4j 2 ........................................ SUCCESS [1.454s] [INFO] Log4J API ............................................. SUCCESS [2.689s] [INFO] Log4J2 Core ........................................... SUCCESS [1:03.924s] [INFO] Log4J Compatibility API ............................... SUCCESS [3.471s] [INFO] SLF4J Binding ......................................... SUCCESS [2.244s] [INFO] Log4J2 Commons Logging ................................ SUCCESS [1.964s] [INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1 minute 16 seconds [INFO] Finished at: Mon Sep 26 11:55:33 EDT 2011 [INFO] Final Memory: 37M/265M [INFO] ------------------------------------------------------------------------ $ cat log4j12-api/target/surefire-reports/org.apache.log4j.CategoryTest.txt ------------------------------------------------------------------------------- Test set: org.apache.log4j.CategoryTest ------------------------------------------------------------------------------- Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.657 sec
        Hide
        Ralph Goers added a comment -

        I applied the patches above and LogManager.getLogger() is still throwing a ClassCastException. In addition a second unit test is failing but I believe you said that error is fixed by the patch for LOG4J2-50.

        Show
        Ralph Goers added a comment - I applied the patches above and LogManager.getLogger() is still throwing a ClassCastException. In addition a second unit test is failing but I believe you said that error is fixed by the patch for LOG4J2-50 .
        Hide
        John Vasileff added a comment -

        Attaching patch #3 in the series:

        remove dangerous logger factory override

        Remove LoggerContext support for custom logger factories. All Loggers returned
        by LoggerContext should be compatibile and of the same type.

        In the following:

        Logger getLogger(LoggerFactory factory, String name)

        the returned Logger was not guaranteed to be created by the provided factory.
        The value of specifying a custom logger is diminished without this guarantee.

        Since only one instance of each logger exists, behavior should not be defined
        by the caller of getLogger() that "wins" the race to be the one to determine
        the factory used to create the logger.

        Show
        John Vasileff added a comment - Attaching patch #3 in the series: remove dangerous logger factory override Remove LoggerContext support for custom logger factories. All Loggers returned by LoggerContext should be compatibile and of the same type. In the following: Logger getLogger(LoggerFactory factory, String name) the returned Logger was not guaranteed to be created by the provided factory. The value of specifying a custom logger is diminished without this guarantee. Since only one instance of each logger exists, behavior should not be defined by the caller of getLogger() that "wins" the race to be the one to determine the factory used to create the logger.
        Hide
        John Vasileff added a comment -

        re-attaching....

        Show
        John Vasileff added a comment - re-attaching....
        Hide
        John Vasileff added a comment -

        Patch to fix the problem. Commit notes:

        fix for Category.getInstance returning cached Logger

        When creating new Category instances, the Category class passed a custom
        Factory to context.getLogger(factory, name). The factory created loggers of
        type CategoryFactory.CategoryLogger, and code in the Category class casted the
        logger to this type.

        The problem was that context.getLogger(factory, name) only uses the provided
        factory if it has to create a new logger. Cached loggers would simply be
        returned. If the cached logger was created using a different factory, it was
        not of type CategoryFactory.CategoryLogger and a ClassCastException would occur
        during operations that called isEnabledFor or forcedLog.

        Show
        John Vasileff added a comment - Patch to fix the problem. Commit notes: fix for Category.getInstance returning cached Logger When creating new Category instances, the Category class passed a custom Factory to context.getLogger(factory, name). The factory created loggers of type CategoryFactory.CategoryLogger, and code in the Category class casted the logger to this type. The problem was that context.getLogger(factory, name) only uses the provided factory if it has to create a new logger. Cached loggers would simply be returned. If the cached logger was created using a different factory, it was not of type CategoryFactory.CategoryLogger and a ClassCastException would occur during operations that called isEnabledFor or forcedLog.
        Hide
        John Vasileff added a comment -

        Attached test case for this issue.

        Show
        John Vasileff added a comment - Attached test case for this issue.

          People

          • Assignee:
            Ralph Goers
            Reporter:
            John Vasileff
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development