Humm... How about this instead (not that I am lazy)?
$ cvs diff -u catalina/build.xml
Index: catalina/build.xml
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/build.xml,v
retrieving revision 1.124
diff -u -r1.124 build.xml
--- catalina/build.xml 29 Jun 2002 01:00:04 -0000 1.124
+++ catalina/build.xml 22 Jul 2002 16:31:07 -0000
@@ -801,6 +801,8 @@
unless="jdk.1.3.present"/>
<exclude name="org/apache/catalina/servlets/CGIServlet.java"
unless="jdk.1.3.present"/>
+ <exclude name="org/apache/catalina/logger/JdkLogger.java"
+ unless="jdk.1.4.present"/>
<exclude name="org/apache/naming/NamingService.java"
unless="compile.jmx"/>
<exclude
name="org/apache/naming/factory/DbcpDataSourceFactory.java"
On Mon, 2002-07-22 at 12:28, Patrick Luby wrote:
> Bob,
>
> This is a useful piece of code. However, your patch can't go into Tomcat
> as it will only compile with JDK 1.4. The standard builds of Tomcat that
> are downloadable from the jakarta.apache.org are built using JDK 1.3 and
> should be run without crashing Tomcat on JDK 1.2.
>
> So, if you would like this in Tomcat (and I think it would be a nice
> optional logger implementation), I think that you need to do the following:
>
> 1. Remove all of the following import statements and replace them with
> reflection calls so that the JDK 1.3 compiler can compile this class:
>
> import java.util.logging.Logger;
> import java.util.logging.Level;
> import java.util.logging.Formatter;
> import java.util.logging.Handler;
> import java.util.logging.LogRecord;
>
> 2. Catch any ClassNotFound and MethodNotFound exceptions that will occur
> when the code is run on JDK 1.2 or 1.3.
>
> Patrick
>
>
>
>
> Bob Herrmann wrote:
> > Hi. I am trying to get Tomcat to log to JDK1.4's logging.
> >
> > I tried implementing a "o.a.c.logging.Logger" subclass that forwarded
> > calls to commons-logging Log. This was unsatisfying because the
> > commons-logger unrolls the stack and logs the "class.method" of my
> > logger, not my logger's caller.
> >
> > I was tempted to change the commons-logger to allow for specifying
> > a class and method on all its methods, but that would be a large
> > change the commons-logger (involving changes and decisions about
> > how this new information should be pushed down and handled with
> > the other loggers it supports.) There is also some issues mapping
> > tomcat verbosity levels, to common-logger log levels and then to JDK
> > Logger levels.
> >
> > So I punted and implemented the code below. It is a
> > "o.a.c.logging.Logger" which writes directly to JDK 1.4 Logging.
> > It allowed me to unroll the stack in a way that fits well with
> > tomcat (ignoring stack frames calling with method log() or method
> > internalLog() which are uninteresting.) And allowed me to map
> > verbosity to JDK Levels.
> >
> > Cheers,
> > -bob
> >
> >
> >
> >
> > ------------------------------------------------------------------------
> >
> > /*
> > * $Header: $
> > * $Revision: $
> > * $Date: $
> > *
> > * ====================================================================
> > *
> > * The Apache Software License, Version 1.1
> > *
> > * Copyright (c) 1999 The Apache Software Foundation. All rights
> > * reserved.
> > *
> > * Redistribution and use in source and binary forms, with or without
> > * modification, are permitted provided that the following conditions
> > * are met:
> > *
> > * 1. Redistributions of source code must retain the above copyright
> > * notice, this list of conditions and the following disclaimer.
> > *
> > * 2. Redistributions in binary form must reproduce the above copyright
> > * notice, this list of conditions and the following disclaimer in
> > * the documentation and/or other materials provided with the
> > * distribution.
> > *
> > * 3. The end-user documentation included with the redistribution, if
> > * any, must include the following acknowlegement:
> > * "This product includes software developed by the
> > * Apache Software Foundation (http://www.apache.org/)."
> > * Alternately, this acknowlegement may appear in the software itself,
> > * if and wherever such third-party acknowlegements normally appear.
> > *
> > * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
> > * Foundation" must not be used to endorse or promote products derived
> > * from this software without prior written permission. For written
> > * permission, please contact [EMAIL PROTECTED]
> > *
> > * 5. Products derived from this software may not be called "Apache"
> > * nor may "Apache" appear in their names without prior written
> > * permission of the Apache Group.
> > *
> > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> > * SUCH DAMAGE.
> > * ====================================================================
> > *
> > * This software consists of voluntary contributions made by many
> > * individuals on behalf of the Apache Software Foundation. For more
> > * information on the Apache Software Foundation, please see
> > * <http://www.apache.org/>.
> > *
> > * [Additional notices, if required by prior licensing conditions]
> > *
> > */
> >
> >
> > package org.apache.catalina.logger;
> >
> > import java.sql.Timestamp;
> >
> > import org.apache.catalina.Lifecycle;
> > import org.apache.catalina.LifecycleEvent;
> > import org.apache.catalina.LifecycleException;
> > import org.apache.catalina.LifecycleListener;
> > import org.apache.catalina.util.LifecycleSupport;
> > import org.apache.catalina.util.StringManager;
> >
> > import java.util.logging.Logger;
> > import java.util.logging.Level;
> > import java.util.logging.Formatter;
> > import java.util.logging.Handler;
> > import java.util.logging.LogRecord;
> >
> >
> > /**
> > * Implementation of <b>Logger</b> that sends log messages to the
> > * Jdk logger
> > *
> > * @version $Revision: $ $Date: $
> > */
> >
> > public class JdkLogger
> > extends LoggerBase
> > implements Lifecycle {
> >
> >
> > // ----------------------------------------------------- Instance Variables
> >
> >
> > /**
> > * The descriptive information about this implementation.
> > */
> > protected static final String info =
> > "org.apache.catalina.logger.JdkLogger/1.0";
> >
> > /**
> > * The lifecycle event support for this component.
> > */
> > protected LifecycleSupport lifecycle = new LifecycleSupport(this);
> >
> > /**
> > * The string manager for this package.
> > */
> > private StringManager sm =
> > StringManager.getManager(Constants.Package);
> >
> > /**
> > * Has this component been started?
> > */
> > private boolean started = false;
> >
> >
> > /**
> > * The default JDK logging domain that these messages are logged to
> > */
> > private String domain = "tomcat";
> >
> >
> > /**
> > * The we are using. We set it immediately incase we get calls
> > */
> > private Logger jlog = Logger.getLogger(domain);
> >
> >
> > // ------------------------------------------------------------- Properties
> >
> >
> >
> > /**
> > * Return the logging domain in which we create log files.
> > */
> > public String getDomain() {
> >
> > return (domain);
> >
> > }
> >
> >
> > /**
> > * Set the domain in which we send our log files
> > *
> > * @param domain The new domain
> > */
> > public void setDomain(String domain) {
> >
> > String oldDomain = this.domain;
> > this.domain = domain;
> > support.firePropertyChange("domain", oldDomain, this.domain);
> >
> > // there doesnt seem to be any semantics for changing a Logger's name, so
> > // we just replace it.
> > jlog = Logger.getLogger(domain);
> > }
> >
> >
> > // --------------------------------------------------------- Public Methods
> >
> > /**
> > * Writes an explanatory message and a stack trace for a given
> > * <code>Throwable</code> exception to the logger.
> > * This message will be logged unconditionally.
> > *
> > * @param message A <code>String</code> that describes the error or
> > * exception
> > * @param exception The <code>Exception</code> error or exception
> > */
> > public void log(Exception exception, String message){
> > logCallerStack( Level.INFO, message, exception );
> > }
> >
> > /**
> > * Writes an explanatory message and a stack trace for a given
> > * <code>Throwable</code> exception to the logger
> > * This message will be logged unconditionally.
> > *
> > * @param message A <code>String</code> that describes the error or
> > * exception
> > * @param throwable The <code>Throwable</code> error or exception
> > */
> > public void log(String message, Throwable throwable){
> > logCallerStack( Level.INFO, message, throwable );
> > }
> >
> > /**
> > * Writes the specified message and exception to the logger,
> > * if the logger is set to a verbosity level equal
> > * to or higher than the specified value for this message.
> > *
> > * @param message A <code>String</code> the message to log
> > * @param verbosity Verbosity level of this message
> > */
> > public void log(String message, int verbosity){
> > if (this.verbosity < verbosity)
> > return;
> >
> > // Translate tomcat verbosity into JDK Levels
> > Level jlevel = Level.INFO;
> > if ( verbosity == FATAL ) jlevel = Level.SEVERE;
> > else if ( verbosity == ERROR ) jlevel = Level.SEVERE;
> > else if ( verbosity == WARNING ) jlevel = Level.WARNING;
> > else if ( verbosity == DEBUG ) jlevel = Level.FINE;
> >
> > logCallerStack( jlevel, message, null );
> > }
> >
> > /**
> > * Writes the specified message and exception to the logger,
> > * if the logger is set to a verbosity level equal
> > * to or higher than the specified value for this message.
> > *
> > * @param message A <code>String</code> that describes the error or
> > * exception
> > * @param throwable The <code>Throwable</code> error or exception
> > * @param verbosity Verbosity level of this message
> > */
> > public void log(String message, Throwable throwable, int verbosity){
> > if (this.verbosity < verbosity)
> > return;
> >
> > // Translate tomcat verbosity into JDK Levels
> > Level jlevel = Level.INFO;
> > if ( verbosity == FATAL ) jlevel = Level.SEVERE;
> > else if ( verbosity == ERROR ) jlevel = Level.SEVERE;
> > else if ( verbosity == WARNING ) jlevel = Level.WARNING;
> > else if ( verbosity == DEBUG ) jlevel = Level.FINE;
> >
> > logCallerStack( jlevel, message, throwable );
> > }
> >
> >
> > /**
> > * Writes the specified message to a the logger
> > *
> > * @param message A <code>String</code> specifying the message to be logged
> > */
> > public void log(String message) {
> > logCallerStack( Level.INFO, message, null );
> > }
> >
> >
> > // -------------------------------------------------------- Private Methods
> >
> > /**
> > * Writes the specified message to a the logger and attempts to unroll
> > * the stack to include the Class and method of the caller. Trys to be
> > * clever by detecting other wrappers around logging (ie. frames with
> > * methods name log() and internalLog() are skipped in determing the
> > * messages stack of origin)
> > *
> > * @param jLevel A <code>java.util.logging.Level</code> instance to indicate
>the desired logging level
> > * @param message A <code>String</code> specifying the message to be logged
> > * @param throwable The <code>Throwable</code> error or exception
> > */
> > private void logCallerStack( Level jlevel, String message, Throwable throwable
>){
> > // Hack (?) to get the stack trace.
> > Throwable dummyException=new Throwable();
> > StackTraceElement locations[]=dummyException.getStackTrace();
> > // Caller will be the third element
> > String cname="unknown";
> > String method="unknown";
> >
> > // tomcat has methods named log() and internalLog() that are sometimes on the
>stack
> > if( locations!=null && locations.length >2 ) {
> > StackTraceElement caller=null;
> > for (int stackLevel=2;stackLevel<locations.length;stackLevel++){
> > caller = locations[stackLevel];
> > method=caller.getMethodName();
> > if ( !method.equals("log") && !method.equals("internalLog") ){
> > cname=caller.getClassName();
> > // method += " [DEPTH "+stackLevel+"]"; uncomment this to see how
>much stack walking is going on.
> > break;
> > }
> > }
> > }
> > if( throwable==null ) {
> > jlog.logp( jlevel, cname, method, message );
> > } else {
> > jlog.logp( jlevel, cname, method, message, throwable );
> > }
> >
> > }
> >
> >
> > // ------------------------------------------------------ Lifecycle Methods
> >
> >
> > /**
> > * Add a lifecycle event listener to this component.
> > *
> > * @param listener The listener to add
> > */
> > public void addLifecycleListener(LifecycleListener listener) {
> >
> > lifecycle.addLifecycleListener(listener);
> >
> > }
> >
> >
> > /**
> > * Get the lifecycle listeners associated with this lifecycle. If this
> > * Lifecycle has no listeners registered, a zero-length array is returned.
> > */
> > public LifecycleListener[] findLifecycleListeners() {
> >
> > return lifecycle.findLifecycleListeners();
> >
> > }
> >
> >
> > /**
> > * Remove a lifecycle event listener from this component.
> > *
> > * @param listener The listener to add
> > */
> > public void removeLifecycleListener(LifecycleListener listener) {
> >
> > lifecycle.removeLifecycleListener(listener);
> >
> > }
> >
> >
> > /**
> > * Prepare for the beginning of active use of the public methods of this
> > * component. This method should be called after <code>configure()</code>,
> > * and before any of the public methods of the component are utilized.
> > *
> > * @exception LifecycleException if this component detects a fatal error
> > * that prevents this component from being used
> > */
> > public void start() throws LifecycleException {
> >
> > // Validate and update our current component state
> > if (started)
> > throw new LifecycleException( "alreadyStarted");
> > lifecycle.fireLifecycleEvent(START_EVENT, null);
> > started = true;
> >
> > }
> >
> >
> > /**
> > * Gracefully terminate the active use of the public methods of this
> > * component. This method should be the last one called on a given
> > * instance of this component.
> > *
> > * @exception LifecycleException if this component detects a fatal error
> > * that needs to be reported
> > */
> > public void stop() throws LifecycleException {
> >
> > // Validate and update our current component state
> > if (!started)
> > throw new LifecycleException("notStarted");
> > lifecycle.fireLifecycleEvent(STOP_EVENT, null);
> > started = false;
> >
> > }
> >
> >
> > }
> >
> >
> >
> >
> >
> > ------------------------------------------------------------------------
> >
> > --
> > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
>
> --
> ________________________________________________________________
> Patrick Luby Email: [EMAIL PROTECTED]
> Sun Microsystems Phone: 408-276-7471
> 901 San Antonio Road, USCA14-303
> Palo Alto, CA 94303-4900
> ________________________________________________________________
>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>