P.S.  I filed bug #37735 on this and attached the patch to it.

Jess Holle wrote:
Okay, first off, I must apologize for going off half-cocked and somewhat rudely after running into issues earlier this week.

Secondly, I must admit that I was way offbase on some of my analysis of the binary compatibility issue due to:
  1. Too much haste (making waste) in trying to get the problem addressed
  2. Too much reading of the 1.3 compatibility/conversion recipes and not enough reading of the code, etc.
    • The docs really led me to believe that Priority and Category were being removed.  Nothing could be further from the truth, of course, when one looks at the code and examines binary compatibility from various angles.
That said I found the cause of the main binary compatibility issue I was running into (after I had addressed all source-level compatibilities):
In log4j 1.3, Priority extends Level
    but in 1.2, Level extends Priority.
This flip-flop of the inheritance hierarchy avoided removing any classes and made things look cleaner.  Unfortunately, it drives the class verifier absolutely nuts in some cases -- at least in Java 5 Update 5, which is my target JVM.

I am attaching a patch that I'd like to see incorporated in log4j 1.3.  It fixes this issue while keeping the code pretty clean as I see it.  Yes, the Level constants move back to the Priority class, but, no, they're no longer repeated in both Level and Priority -- they're just Level objects in the Priority class.  I also made Priority abstract and its constructor package-private to avoid anyone creating non-Level Priority instances.

This would seem to clear up the most common binary compatibility issues I could find: those involving Level/Priority and Logger/Category.  Most of those I raised previously were figments of my imagination due to reading too much into the 1.3 recipe, but this one is quite real.

This does not address the remaining source and binary compatibility issues between log4j 1.2 and 1.3 -- and I'd urge the log4j community to round off some of these rough edges as well.  That said, I did manage to produce one set of source code that compiles and works with both versions (and now compiles against one version and runs with the other) and I believe the other issues will effect far fewer log4j users than the one addressed here.

I would also like to strongly urge a clearer statement of what is and is not happening in the 1.3 recipes.  Staying away from Category and Priority is good advice, but a little more information as to the fact that they're not going away, that the inheritance hierarchy is not changing, etc, would be helpful.

Finally, I hope to get a chance to chase the lack of appender removal and log level change event firings and propose patches for these issues as well.

--
Jess Holle


Index: Level.java =================================================================== --- Level.java (revision 349818) +++ Level.java (working copy) @@ -36,99 +36,9 @@ @author Ceki G&uuml;lc&uuml; @author Yoav Shapira */ -public class Level implements Serializable { - /** - * OFF level integer value. - */ - public static final int OFF_INT = Integer.MAX_VALUE; +public class Level extends Priority { /** - * FATAL level integer value. - */ - public static final int FATAL_INT = 50000; - - /** - * ERROR level integer value. - */ - public static final int ERROR_INT = 40000; - - /** - * WARN level integer value. - */ - public static final int WARN_INT = 30000; - - /** - * INFO level integer value. - */ - public static final int INFO_INT = 20000; - - /** - * DEBUG level integer value. - */ - public static final int DEBUG_INT = 10000; - - /** - * TRACE level integer value. - * @since 1.2.12 - */ - public static final int TRACE_INT = 5000; - - /** - * ALL level integer value. - */ - public static final int ALL_INT = Integer.MIN_VALUE; - - /** - * The <code>OFF</code> has the highest possible rank and is - * intended to turn off logging. - */ - public static final Level OFF = new Level(OFF_INT, "OFF", 0); - - /** - * The <code>FATAL</code> level designates very severe error - * events that will presumably lead the application to abort. - */ - public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0); - - /** - * The <code>ERROR</code> level designates error events that - * might still allow the application to continue running. - */ - public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3); - - /** - * The <code>WARN</code> level designates potentially harmful situations. - */ - public static final Level WARN = new Level(WARN_INT, "WARN", 4); - - /** - * The <code>INFO</code> level designates informational messages - * that highlight the progress of the application at coarse-grained - * level. - */ - public static final Level INFO = new Level(INFO_INT, "INFO", 6); - - /** - * The <code>DEBUG</code> Level designates fine-grained - * informational events that are most useful to debug an - * application. - */ - public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7); - - /** - * The <code>TRACE</code> Level designates finer-grained - * informational events than the <code>DEBUG</code level. - * @since 1.2.12 - */ - public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7); - - /** - * The <code>ALL</code> has the lowest possible rank and is intended to - * turn on all logging. - */ - public static final Level ALL = new Level(ALL_INT, "ALL", 7); - - /** * The integer value of this Level instance. */ transient int level; Index: Priority.java =================================================================== --- Priority.java (revision 349818) +++ Priority.java (working copy) @@ -18,7 +18,9 @@ // Contributors: Kitching Simon <[EMAIL PROTECTED]> package org.apache.log4j; +import java.io.Serializable; + /** * <font color="#AA4444">Refrain from using this class directly, use the * [EMAIL PROTECTED] Level} class instead</font>. @@ -26,77 +28,104 @@ * @author Ceki G&uuml;lc&uuml; * @deprecated */ -public class Priority extends Level { +public abstract class Priority implements Serializable { - private Priority(int level, String levelStr, int syslogEquivalent) { - super(level, levelStr, syslogEquivalent); - } + /** + * OFF level integer value. + */ + public static final int OFF_INT = Integer.MAX_VALUE; - /** - The <code>FATAL</code> level designates very severe error - events that will presumably lead the application to abort. + * FATAL level integer value. */ - //public static final Priority FATAL = new Level(FATAL_INT, "FATAL", 0); + public static final int FATAL_INT = 50000; /** - The <code>ERROR</code> level designates error events that - might still allow the application to continue running. */ - // public static final Priority ERROR = new Level(ERROR_INT, "ERROR", 3); + * ERROR level integer value. + */ + public static final int ERROR_INT = 40000; /** - The <code>WARN</code> level designates potentially harmful situations. - */ - // public static final Priority WARN = new Level(WARN_INT, "WARN", 4); + * WARN level integer value. + */ + public static final int WARN_INT = 30000; /** - The <code>INFO</code> level designates informational messages - that highlight the progress of the application at coarse-grained - level. */ - // public static final Priority INFO = new Level(INFO_INT, "INFO", 6); + * INFO level integer value. + */ + public static final int INFO_INT = 20000; /** - The <code>DEBUG</code> priority designates fine-grained - informational events that are most useful to debug an - application. */ - //public static final Priority DEBUG = new Level(DEBUG_INT, "DEBUG", 7); + * DEBUG level integer value. + */ + public static final int DEBUG_INT = 10000; + /** + * TRACE level integer value. + * @since 1.2.12 + */ + public static final int TRACE_INT = 5000; /** - Convert the string passed as argument to a priority. If the - conversion fails, then this method returns [EMAIL PROTECTED] #DEBUG}. + * ALL level integer value. + */ + public static final int ALL_INT = Integer.MIN_VALUE; - @deprecated Please use the [EMAIL PROTECTED] Level#toLevel(String)} method instead.} + /** + * The <code>OFF</code> has the highest possible rank and is + * intended to turn off logging. + */ + public static final Level OFF = new Level(OFF_INT, "OFF", 0); + /** + * The <code>FATAL</code> level designates very severe error + * events that will presumably lead the application to abort. + */ + public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0); - */ -// public static Level toPriority(String sArg) { -// return Level.toLevel(sArg); -// } + /** + * The <code>ERROR</code> level designates error events that + * might still allow the application to continue running. + */ + public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3); /** - Convert an integer passed as argument to a priority. If the - conversion fails, then this method returns [EMAIL PROTECTED] #DEBUG}. + * The <code>WARN</code> level designates potentially harmful situations. + */ + public static final Level WARN = new Level(WARN_INT, "WARN", 4); - */ -// public static Priority toPriority(int val) { -// return toPriority(val, Priority.DEBUG); -// } + /** + * The <code>INFO</code> level designates informational messages + * that highlight the progress of the application at coarse-grained + * level. + */ + public static final Level INFO = new Level(INFO_INT, "INFO", 6); /** - Convert an integer passed as argument to a priority. If the - conversion fails, then this method returns the specified default. - */ -// public static Priority toPriority(int val, Priority defaultPriority) { -// return Level.toLevel(val, (Level) defaultPriority); -// } + * The <code>DEBUG</code> Level designates fine-grained + * informational events that are most useful to debug an + * application. + */ + public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7); /** - Convert the string passed as argument to a priority. If the - conversion fails, then this method returns the value of - <code>defaultPriority</code>. - */ -// public static Priority toPriority(String sArg, Priority defaultPriority) { -// return Level.toLevel(sArg, (Level) defaultPriority); -// } + * The <code>TRACE</code> Level designates finer-grained + * informational events than the <code>DEBUG</code level. + * @since 1.2.12 + */ + public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7); + + /** + * The <code>ALL</code> has the lowest possible rank and is intended to + * turn on all logging. + */ + public static final Level ALL = new Level(ALL_INT, "ALL", 7); + + + /** + Prevent construction except from this package (i.e. by Level). + */ + Priority() { + // nothing to do here + } }

  

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

Reply via email to