The version of Apache log4j used by SoundHelix.

[[ 🗃 ^aEp6o apache-log4j ]] :: [📥 Inbox] [📤 Outbox] [🐤 Followers] [🤝 Collaborators] [🛠 Commits]

Clone

HTTPS: git clone https://vervis.peers.community/repos/aEp6o

SSH: git clone USERNAME@vervis.peers.community:aEp6o

Branches

Tags

v_1_1b5 :: docs /

TROUBLESHOOT.html

<html>
<head>
<title>Troubleshooting log4j</title>
</head> 
<body bgcolor=#FFFFFF>
 
<h1 align=center>Log4j troubleshooting</h1>

<h2 align=center>Ceki G&uuml;lc&uuml;
<br>November 2000</h2>

<hr>

<p>Here is a list of commonly encoutered problems when using log4j:

<ul> 

<li><p><a href=#noAppenders>log4j tells me to initialize
properly.</a>

<li><p><a href=#duplicates>Duplicates in log4j output.</a>

<li><p><a href=#space>Options are not parsed correctly.</a>

<li><p><a href=#jit>Location information is printed as a "?" character.</a>

<li><p><a href=#cce>ClassCastException when instantiating a Category subclasses.</a>

<li><p><a href=#notfound>My EJB/Servlet/JSP says log4j class not found/defined.</a>

</ul>

<hr>

<p><a name=noAppenders><h4>log4j tells me to initialize properly.</h4>

Logging output is written to a target by using an appender. If no
appenders are attached to a category nor to any of its ancestors, you
will get the following message when trying to log:

<pre>
log4j: No appenders could be found for category (some.category.name).
log4j: Please initialize the log4j system properly.
</pre>

<em>Log4j does not have a default logging target.</em> It is the
user's responsability to ensure that all categories can inherit an
appender.  This can be easily achieved by attaching an appender to the
root category.


<p><a name=duplicates><h4>Duplicates in log4j output.</h4>

<p>The reason for observing duplicates in log4j output is either due
to having added the same appender multiple times to the same category
(typically root) or having added the same appender to different
categories ignoring the fact that appenders are inherited
cumulatively.

<p>log4j does not eliminate appender duplicates. In other words, if
you add the same appender to a category <i>n</i> times, that appender
will be invoked <i>n</i> times to append to its target. 

<p>A slightly different cause is adding different appenders all
sharing the same underlying output target to some category. In the
most common occurance of this phenomenon, the
BasicConfigurator.configure() method is invoked multiple times. Each
time it is invoked, this method adds an appender with a
<code>System.out</code> target to the root category. 

<p>One other common mistake is to forget that appenders are inherited
cumulatively from the hierarchy. For example, if you add an appender,
say <code>A</code>, to the root category, all other categories will
inherit <code>A</code> as an appender. Thus, if you add <code>A</code>
to a categoy, say <code>C</code>, then an enabled statement of
category <code>C</code>, will print to <code>A</code> twice, once
because <code>A</code> is in root and once because it is in
<code>C</code>. 

<p><a name=space><h4>Options are not parsed correctly.</h4>

The PropertyConfigurator relies on <code>java.util.Properties</code>
class to read in the configuration file. This class preserves spaces
in options. For example,

<pre>
fruit=orange  
</pre>
is returned as an option having the key <code>"fruit"</code> and the
value <code>"orange "</code>.

<p>The spaces in the value, i.e. <code>"orange "</code>, are due to
invisible spaces at the end of the example shown above. Thus, some of
the options might not be interpreted correctly due to trailing
spaces. 

<p>In log4j version 0.9.0, all spaces are removed from <em>both</em>
ends of option values. In version 0.9.1 log4j reverted to the old
behaviour where option values are not all automatically trimmed. 


<p><a name=jit><h4>Location information is printed as a "?" character.</h4>

Location information is extracted automatically by the PatternLayout
conversion patterns %C, %F, %M and %L. However, some just-in-time
(JIT) compilers make it impossible to extract location information. It
is also possible that the complier that generated the byte code may
have ommitted the LineNumber table as is done by -O option of javac
and jikes.  

<p>You can remedy this problem by disabling the JIT compiler and by
compiling the code without the -O option.

<p><a name=cce><h4><code>ClassCastException</code> when instantiating
a <code>Category</code> subclasses.</a></h4>

<p>This exception is thrown because log4j does not support
homonyms. For example, the following will systematically throw a
<code>ClassCastException</code>

<pre>
  Category c1 = Category.getInstance("bad");
  MyCategory c2 = (MyCategory) MyCategory.getInstance("bad");
</pre>

where <code>MyCategory</code> is a sub-class of
<code>Category</code>. The problem occurs because the second
<code>getInstance</code> invocation will retrieve the category created
in the fist invocation. This instance is a <code>Category</code>
object and cannot be cast to <code>MyCategory</code>.

<p>By default, the <code>PropertyConfigurator</code> will create and
configure <code>org.apache.log4j.Category</code> objects. Thus, if you try to
instantiate a category sub-class for an already existing category, and
try to cast it to the sub-class type, you will systematically get a
<code>ClassCastException</code>.

<p>To address this problem, the <code>PropertyConfigurator</code> admits
the <code>log4j.categoryFactory</code> key. The value of this key will
be used as the factory to invoke when instantiating Category objects.

<p>The <code>DOMConfigurator</code> has a finer grain method for
setting the class of the category object to instantiate.

<p><a name=notfound><h4>Log4j class not found/defined</h4>

<p>Naturally you should check the classpath.  But you should also 
be aware of the presence of multiple classloaders in the JVM:
<p> <ol>
<li>the bootstrap classloader
<li>the extension classloader
<li>the application classloader
</ol>
<p>If you place log4j.jar in the <code>jre/lib/ext</code> directory
but place user-defined extensions to log4j in the application 
classloader classpath, log4j configurators will not find them.

<p>Servlet, JSP and EJB containers inside of application servers
usually have their own special classloaders in addition to the 
three mentioned above.  While this provides for a greater
degree of separation for different webapps, EJB containers and the
application server runtime itself, it can provide headaches to the
uninitiated.

<p>Classloaders are usually hierarchically related.  The bootstrap
loader forms the root with the extension loader as its child.  The
application loader is the child of the extension loader and it's
this "app loader" that we use by default when we write standalone
Java programs.

<p>Upon receiving a class load request, the classloader usually 
delegates it to the parent before attempting to service the request.
This allows the bootstrap and extension loaders to deliver any classes
that are part of the JDK or its extensions.  Only after this delegation
fails will the classloader attempt to find the class itself.  Note that
classloaders do not delegate requests to children.

<p>Application servers often use the application loader for its runtime
classes and create separate classloaders for its webapp and EJB
containers.  These additional classloaders may decend directly
from the app server's runtime classloader.  If log4j is placed in the
classpath of a webapp classloader, another webapp classloader will not
necessarily see it.  EJBs wouldn't see it either.  If log4j is intended
to be made availble to all objects participating in the app server, it
should be included in the classpath of a classloader high enough in the
classloader hierarchy to be seen by all classloaders.

<p>A good article on classloaders with examples using IBM's WebSphere
application server can be found 
<a href="http://www7.software.ibm.com/vadd-bin/ftpdl?1/vadc/wsdd/pdf/gisell/UnderstandingWebSphereClassLoaders.pdf">here</a> 
in PDF format.



</body>
</html>

[See repo JSON]