Paul, Ooops. Thanks for refreshening my memory. I'll backtrack. Ceki At 08:46 26.06.2001 -0700, you wrote: >Ceki, > >I'm not sure you want to do this. Recall the mess about 6 months ago with >subclasses of Category not able to provide the method name in log >statements. The problem is the following. When the LocationInfo object >tries to glean the application method name from the stack, the stack looks >something like this. > > ... > 6 org.apache.log4j.PatternLayout.format > 5 org.apache.log4j.FileAppender.doAppend > 4 org.apache.log4j.Category.callAppenders > 3 org.apache.log4j.Category.forcedLog > 2 org.apache.log4j.Category.warn > 1 com.mycompany.myclass.myMethodCallingLog4j > ... > >When Category is subclassed, entries 2 or 3 or both or none may be >overridden by the subclass. In the AppServerCategory factory example, >forcedLog is overridden. But I don't want the AppServerCategory FQCN >passed into the LoggingEvent class. Otherwise the %M of PatternLayout will >say "Category.warn" rather than myclass.myethodCallingLog4j. > >You were the one who discovered the delicate solution that worked for all >four cases (2, 3, 2 and 3, neither). This was to always make the FQCN a >private static of Category and the subclass with no accessors. I'm pretty >sure the protected getFQCN will break this (if subclasses override getFQCN >()). > >- Paul > >Paul Glezen >IT Specialist >Software Services for WebSphere >818 539 3321 > > >[EMAIL PROTECTED] on 06/26/2001 03:52:40 AM > >Please respond to "LOG4J Developers Mailing List" > <[EMAIL PROTECTED]> > >To: [EMAIL PROTECTED] >cc: >Subject: cvs commit: jakarta-log4j/src/java/org/apache/log4j/net > SocketNode.java > > > >ceki 01/06/26 03:52:38 > > Modified: src/java/org/apache/log4j Category.java > src/java/org/apache/log4j/examples Makefile MyCategory.java > src/java/org/apache/log4j/helpers VersionHelper.java > VersionHelper11.java VersionHelper20.java > src/java/org/apache/log4j/net SocketNode.java > Log: > - Added the protected access getFQCN() method to Category class. The new >method is used > extensively. Subclasses of category should override this method. > > - Modified the MyCategory example to be easier to understand. > > - Changed indentation of VersionHelper* > > Revision Changes Path > 1.32 +31 -17 >jakarta-log4j/src/java/org/apache/log4j/Category.java > > Index: Category.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/Category.java,v > retrieving revision 1.31 > retrieving revision 1.32 > diff -u -r1.31 -r1.32 > --- Category.java 2001/06/23 08:49:22 1.31 > +++ Category.java 2001/06/26 10:51:42 1.32 > @@ -167,9 +167,9 @@ > volatile protected Category parent; > > /** > - The fully qualified name of the class that this Category > - object. Subclasses should create their own private FQCN > - variable. */ > + The fully qualified name of the Category class. See also the > + getSubclasses should > + create their own private FQCN variable. */ > private static final String FQCN = Category.class.getName(); > > protected ResourceBundle resourceBundle; > @@ -310,7 +310,7 @@ > if(hierarchy.disable >= Priority.DEBUG_INT) > return; > if(Priority.DEBUG.isGreaterOrEqual(this.getChainedPriority())) { > - forcedLog(FQCN, Priority.DEBUG, message, null); > + forcedLog(getFQCN(), Priority.DEBUG, message, null); > } > } > > @@ -328,7 +328,7 @@ > void debug(Object message, Throwable t) { > if(hierarchy.disable >= Priority.DEBUG_INT) return; > if(this.isEnabledFor(Priority.DEBUG)) > - forcedLog(FQCN, Priority.DEBUG, message, t); > + forcedLog(getFQCN(), Priority.DEBUG, message, t); > } > > //public > @@ -362,7 +362,7 @@ > void error(Object message) { > if(hierarchy.disable >= Priority.ERROR_INT) return; > if(this.isEnabledFor(Priority.ERROR)) > - forcedLog(FQCN, Priority.ERROR, message, null); > + forcedLog(getFQCN(), Priority.ERROR, message, null); > } > > /** > @@ -378,7 +378,7 @@ > void error(Object message, Throwable t) { > if(hierarchy.disable >= Priority.ERROR_INT) return; > if(this.isEnabledFor(Priority.ERROR)) > - forcedLog(FQCN, Priority.ERROR, message, t); > + forcedLog(getFQCN(), Priority.ERROR, message, t); > > } > > @@ -418,7 +418,7 @@ > void fatal(Object message) { > if(hierarchy.disable >= Priority.FATAL_INT) return; > if(Priority.FATAL.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, Priority.FATAL, message, null); > + forcedLog(getFQCN(), Priority.FATAL, message, null); > } > > /** > @@ -434,7 +434,7 @@ > void fatal(Object message, Throwable t) { > if(hierarchy.disable >= Priority.FATAL_INT) return; > if(Priority.FATAL.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, Priority.FATAL, message, t); > + forcedLog(getFQCN(), Priority.FATAL, message, t); > } > > > @@ -526,6 +526,20 @@ > return defaultHierarchy; > } > > + > + /** > + The value returned by this method is used as a hint to determine > + the correct caller localization information. > + > + <p>Subclasses should override this method to return their own > + fully qualified class name. > + > + @since 1.2 */ > + protected > + String getFQCN() { > + return Category.FQCN; > + } > + > > /** > Return the the {@link Hierarchy} where this <code>Category</code> >instance is > @@ -702,7 +716,7 @@ > void info(Object message) { > if(hierarchy.disable >= Priority.INFO_INT) return; > if(Priority.INFO.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, Priority.INFO, message, null); > + forcedLog(getFQCN(), Priority.INFO, message, null); > } > > /** > @@ -718,7 +732,7 @@ > void info(Object message, Throwable t) { > if(hierarchy.disable >= Priority.INFO_INT) return; > if(Priority.INFO.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, Priority.INFO, message, t); > + forcedLog(getFQCN(), Priority.INFO, message, t); > } > > /** > @@ -813,7 +827,7 @@ > if(msg == null) { > msg = key; > } > - forcedLog(FQCN, priority, msg, t); > + forcedLog(getFQCN(), priority, msg, t); > } > } > /** > @@ -837,7 +851,7 @@ > msg = key; > else > msg = java.text.MessageFormat.format(pattern, params); > - forcedLog(FQCN, priority, msg, t); > + forcedLog(getFQCN(), priority, msg, t); > } > } > > @@ -850,7 +864,7 @@ > return; > } > if(priority.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, priority, message, t); > + forcedLog(getFQCN(), priority, message, t); > } > > /** > @@ -862,7 +876,7 @@ > return; > } > if(priority.isGreaterOrEqual(this.getChainedPriority())) > - forcedLog(FQCN, priority, message, null); > + forcedLog(getFQCN(), priority, message, null); > } > > /** > @@ -1010,7 +1024,7 @@ > public > void warn(Object message) { > if(this.isEnabledFor(Priority.WARN)) > - forcedLog(FQCN, Priority.WARN, message, null); > + forcedLog(getFQCN(), Priority.WARN, message, null); > } > > /** > @@ -1025,6 +1039,6 @@ > public > void warn(Object message, Throwable t) { > if(this.isEnabledFor(Priority.WARN)) > - forcedLog(FQCN, Priority.WARN, message, t); > + forcedLog(getFQCN(), Priority.WARN, message, t); > } > } > > > > 1.5 +1 -0 >jakarta-log4j/src/java/org/apache/log4j/examples/Makefile > > Index: Makefile > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/examples/Makefile,v > retrieving revision 1.4 > retrieving revision 1.5 > diff -u -r1.4 -r1.5 > --- Makefile 2001/03/21 21:33:57 1.4 > +++ Makefile 2001/06/26 10:51:54 1.5 > @@ -7,6 +7,7 @@ > MyPatternParser.java\ > MyPatternLayout.java\ > MyCategory.java\ > + MyCategoryTest.java\ > MyCategoryFactory.java\ > > > > > > 1.9 +17 -58 >jakarta-log4j/src/java/org/apache/log4j/examples/MyCategory.java > > Index: MyCategory.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/examples/MyCategory.java,v > > retrieving revision 1.8 > retrieving revision 1.9 > diff -u -r1.8 -r1.9 > --- MyCategory.java 2001/06/06 16:07:16 1.8 > +++ MyCategory.java 2001/06/26 10:51:56 1.9 > @@ -17,71 +17,24 @@ > /** > A simple example showing category subclassing. > > - <p>The example should make it clear that subclasses follow the > - hierarchy. You should also try running this example with a <a > - href="doc-files/mycat.bad">bad</a> and <a > - href="doc-files/mycat.good">good</a> configuration file samples. > + <p>See <b><a href="doc-files/MyCategory.java">source code</a></b> > + for more details. > > - <p>See <b><a > - href="doc-files/MyCategory.java">source code</a></b> for more >details. > + <p>See {@link MyCategoryTest} for a usage example. > > */ > public class MyCategory extends Category { > > - private static String FQCN = MyCategory.class.getName(); > + // It's usually a good idea to add a dot suffix to the fully > + // qualified class name. This makes caller localization to work > + // properly even from classes that match MyCategory such as > + // MyCategoryTest. > + static String FQCN = MyCategory.class.getName() + "."; > > // It's enough to instantiate a factory once and for all. > private static MyCategoryFactory myFactory = new MyCategoryFactory(); > > /** > - When called wihtout arguments, this program will just print > - <pre> > - DEBUG [main] some.cat - Hello world. > - </pre> > - and exit. > - > - <b>However, it can be called with a configuration file in XML or > - properties format. > - > - */ > - static public void main(String[] args) { > - > - if(args.length == 0) { > - // Note that the appender is added to root but that the log > - // request is made to an instance of MyCategory. The output still > - // goes to System.out. > - Category root = Category.getRoot(); > - Layout layout = new PatternLayout("%p [%t] %c - %m%n"); > - root.addAppender(new ConsoleAppender(layout, >ConsoleAppender.SYSTEM_OUT)); > - } > - else if(args.length == 1) { > - if(args[0].endsWith("xml")) { > - DOMConfigurator.configure(args[0]); > - } else { > - PropertyConfigurator.configure(args[0]); > - } > - } else { > - usage("Incorrect number of parameters."); > - } > - try { > - MyCategory c = (MyCategory) MyCategory.getInstance("some.cat"); > - c.trace("Hello"); > - c.debug("Hello"); > - } catch(ClassCastException e) { > - LogLog.error("Did you forget to set the factory in the config >file?", e); > - } > - } > - > - static > - void usage(String errMsg) { > - System.err.println(errMsg); > - System.err.println("\nUsage: "+MyCategory.class.getName() + >"[configFile]\n" > - + " where *configFile* is an optional configuration >file, "+ > - "either in properties or XML format."); > - System.exit(1); > - } > - > - /** > Just calls the parent constuctor. > */ > public MyCategory(String name) { > @@ -92,9 +45,15 @@ > Overrides the standard debug method by appending " world" at the > end of each message. */ > public > - void debug(String message) { > + void debug(Object message) { > super.debug(message + " world."); > } > + > + protected > + String getFQCN() { > + return MyCategory.FQCN; > + } > + > > /** > This method overrides {@link Category#getInstance} by supplying > @@ -107,8 +66,8 @@ > } > > public > - void trace(String message) { > - super.log(XPriority.TRACE, message); > + void trace(Object message) { > + super.log(XPriority.TRACE, message); > } > } > > > > > 1.2 +55 -49 >jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper.java > > Index: VersionHelper.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper.java,v > > retrieving revision 1.1 > retrieving revision 1.2 > diff -u -r1.1 -r1.2 > --- VersionHelper.java 2001/06/20 07:59:47 1.1 > +++ VersionHelper.java 2001/06/26 10:52:09 1.2 > @@ -11,61 +11,67 @@ > import java.util.StringTokenizer; > > /** > - VersionHelper fixes the classloading trouble when using Log4J in a >multi-classloader > - environment like Jakarta Tomcat > + VersionHelper fixes the classloading trouble when using Log4J in a > + multi-classloader environment like Jakarta Tomcat > > @since 1.2 > - @author Christopher Taylor > -*/ > + @author Christopher Taylor */ > abstract public class VersionHelper { > > - public static final String VERSION_PROPERTY = "java.version"; > - private static VersionHelper helper; > + public static final String VERSION_PROPERTY = "java.version"; > + private static VersionHelper helper; > > > - /** VersionHelpers for specific JVM versions override this method, >For example, VersionHelper11 just calls > - * into <code>Class.forName()</code>, while VersionHelper20 calls >into > - * <code>Thread.currentThread().getContextClassLoader().loadClass >()</code> > - * @see java.lang.Thread#getContextClassLoader > - */ > - abstract public Class loadClass (String klass_name) throws >ClassNotFoundException; > + /** VersionHelpers for specific JVM versions override this method, > + * For example, VersionHelper11 just calls into > + * <code>Class.forName()</code>, while VersionHelper20 calls into > + * <code>Thread.currentThread().getContextClassLoader().loadClass >()</code> > + * @see java.lang.Thread#getContextClassLoader */ > + > + > + abstract public Class loadClass (String klass_name) throws >ClassNotFoundException; > > - /** All classes in Log4J that need to dynamically load other classes >must use > - * <code>org.apache.log4j.helpers.VersionHelper.getInstance >().loadClass(<i>class name</i>)</code> > - * and <b>not</b> use <code>Class.forName</code>. In a Java 2 >environment, classes from a parent > - * classloader will ignore any classes available in child class >loaders. Consequently, any appenders, > - * layout managers, or other supporting Log4J classes that are not >bundled with the main <code>log4j.jar</code> > - * file will be ignored in a multi-classloader environment like Tomcat >unless a call is made to > - * <code>Thread.currentThread().getContextClassLoader >().loadClass</code>. As this method is only in Java 2, > - * special version checking code must be inserted guaranteeing that it >won't be executed on Java 1 platforms. > - * The VersionHelper superclass handles the version checking within >this method by parsing the System property > - * <code>java.version</code>. > - * @see java.lang.Thread#getContextClassLoader > - */ > - public static VersionHelper getInstance () { > - if (helper == null) { > - /* If the helper is null, we'll inspect the System property >"java.version" and > - figure out which version of the VM we're running on. > - Version strings are: [major version].[minor version].[bug >fix revision] > - So JDK 1.2: 1.2.0 > - JDK 1.1: 1.1.0 > - */ > - String prop = System.getProperty(VERSION_PROPERTY); > - StringTokenizer st = new StringTokenizer(prop,"."); > - st.nextToken(); // Ignore the initial 1 > - String version = st.nextToken(); > - try { > - /* Here we'll parse the number and decide which version >helper to use */ > - switch (Integer.parseInt(version)) { > - case 0: > - case 1: helper = new VersionHelper11(); break; > - default: helper = new VersionHelper20(); break; > - } > - } > - catch (NumberFormatException oops) { > - helper = new VersionHelper11(); > - } > - } > - return helper; > + /** All classes in Log4J that need to dynamically load other classes > + * must use > + * <code>org.apache.log4j.helpers.VersionHelper.getInstance >().loadClass(<i>class > + * name</i>)</code> and <b>not</b> use <code>Class.forName</code>. > + * In a Java 2 environment, classes from a parent classloader will > + * ignore any classes available in child class loaders. > + * Consequently, any appenders, layout managers, or other supporting > + * Log4J classes that are not bundled with the main > + * <code>log4j.jar</code> file will be ignored in a > + * multi-classloader environment like Tomcat unless a call is made > + * to > + * <code>Thread.currentThread().getContextClassLoader >().loadClass</code>. > + * As this method is only in Java 2, special version checking code > + * must be inserted guaranteeing that it won't be executed on Java 1 > + * platforms. The VersionHelper superclass handles the version > + * checking within this method by parsing the System property > + * <code>java.version</code>. > + * @see java.lang.Thread#getContextClassLoader */ > + public static VersionHelper getInstance () { > + if (helper == null) { > + /* If the helper is null, we'll inspect the System property >"java.version" and > + figure out which version of the VM we're running on. > + Version strings are: [major version].[minor version].[bug fix >revision] > + So JDK 1.2: 1.2.0 > + JDK 1.1: 1.1.0 > + */ > + String prop = System.getProperty(VERSION_PROPERTY); > + StringTokenizer st = new StringTokenizer(prop,"."); > + st.nextToken(); // Ignore the initial 1 > + String version = st.nextToken(); > + try { > + /* Here we'll parse the number and decide which version helper to use >*/ > + switch (Integer.parseInt(version)) { > + case 0: > + case 1: helper = new VersionHelper11(); break; > + default: helper = new VersionHelper20(); break; > } > + } catch (NumberFormatException oops) { > + helper = new VersionHelper11(); > + } > + } > + return helper; > + } > } > > > > 1.2 +7 -7 >jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper11.java > > Index: VersionHelper11.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper11.java,v > > retrieving revision 1.1 > retrieving revision 1.2 > diff -u -r1.1 -r1.2 > --- VersionHelper11.java 2001/06/20 07:59:47 1.1 > +++ VersionHelper11.java 2001/06/26 10:52:12 1.2 > @@ -9,12 +9,12 @@ > package org.apache.log4j.helpers; > > /** VersionHelper11 is the Java 1 compatible VersionHelper for >classloading > - * @since 1.2 > - * @see org.apache.log4j.helpers.VersionHelper > - * @author Christopher Taylor > - */ > + * @since 1.2 > + * @see org.apache.log4j.helpers.VersionHelper > + * @author Christopher Taylor > + */ > public class VersionHelper11 extends VersionHelper { > - public Class loadClass (String klass_name) throws >ClassNotFoundException { > - return Class.forName(klass_name); > - } > + public Class loadClass (String klass_name) throws >ClassNotFoundException { > + return Class.forName(klass_name); > + } > } > > > > 1.2 +8 -8 >jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper20.java > > Index: VersionHelper20.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/VersionHelper20.java,v > > retrieving revision 1.1 > retrieving revision 1.2 > diff -u -r1.1 -r1.2 > --- VersionHelper20.java 2001/06/20 07:59:47 1.1 > +++ VersionHelper20.java 2001/06/26 10:52:15 1.2 > @@ -7,14 +7,14 @@ > */ > package org.apache.log4j.helpers; > > - /** VersionHelper20 is the Java 2 compatible VersionHelper for >classloading > - * @since 1.2 > - * @see org.apache.log4j.helpers.VersionHelper > - * @author Christopher Taylor > - */ > +/** VersionHelper20 is the Java 2 compatible VersionHelper for >classloading > + * @since 1.2 > + * @see org.apache.log4j.helpers.VersionHelper > + * @author Christopher Taylor > + */ > public class VersionHelper20 extends VersionHelper { > - public Class loadClass (String klass_name) throws >ClassNotFoundException { > - return Thread.currentThread().getContextClassLoader >().loadClass(klass_name); > - } > + public Class loadClass (String klass_name) throws >ClassNotFoundException { > + return Thread.currentThread().getContextClassLoader >().loadClass(klass_name); > + } > } > > > > > 1.8 +4 -1 >jakarta-log4j/src/java/org/apache/log4j/net/SocketNode.java > > Index: SocketNode.java > =================================================================== > RCS file: >/home/cvs/jakarta-log4j/src/java/org/apache/log4j/net/SocketNode.java,v > retrieving revision 1.7 > retrieving revision 1.8 > diff -u -r1.7 -r1.8 > --- SocketNode.java 2001/06/21 17:51:44 1.7 > +++ SocketNode.java 2001/06/26 10:52:30 1.8 > @@ -80,8 +80,11 @@ > cat.info("Caught java.io.EOFException closing conneciton."); > } catch(java.net.SocketException e) { > cat.info("Caught java.net.SocketException closing conneciton."); > + } catch(IOException e) { > + cat.info("Caught java.io.IOException: "+e); > + cat.info("Closing connection."); > } catch(Exception e) { > - cat.warn("Unexpected exception. Closing conneciton.", e); > + cat.error("Unexpected exception. Closing conneciton.", e); > } > > try { > > > > >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] > > > > >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] -- Ceki Gülcü --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]