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_1_3 :: docs /

critique.html

<HTML>
<document>

<HEAD>
<title>JSR47 vs. log4j</title>
</HEAD>

<body>

<CENTER>
<H1>JSR47 vs. log4j</H1>
<font size="+1">by Ceki G&uuml;lc&uuml;</font>
</CENTER>
 
<hr>
<p>I consider it quite distasteful to criticize other people's work,
especially in public. However, since the logging API included in JDK
1.4 will be potentially considered as the "standard", I feel compelled
to react. I am not alone in my criticism of JSR47, Greg Davis has his
own set of <a
href="http://www.swzoo.org/documents/miscellaneous/jsr047/">comments</a>.

<p>The JDK 1.4 logging API is a result of the <a
href="http://jcp.org/aboutJava/communityprocess/review/jsr047/index.html">JSR47
effort</a>, led by Graham Hamilton. 

<p>Before delving into the details, some historical perspective is in
order. I am the founder of the log4j project. I participated in the
specification of the JSR47 API, although not as an expert. In 1999, I
was still working for IBM and big blue had already Chris Barlock as a
member in the JSR47 experts group. Chris is the author of <a
href="http://www.alphaworks.ibm.com/tech/loggingtoolkit4j">IBM's
logging toolkit for Java</a>.

<p>On the surface, his toolkit has heavily influenced the JSR47
API. In particular, the two share the same basic components, namely
loggers, levels, handlers and formatters. In log4j, these components
are called categories, priorities, appenders and layouts
respectively. Pairwise, they are identical in purpose. As such, the
terms logger and category, level and priority, handler and appender,
formatter and layout will be used interchangeably in the remainder of
this document.


<p>Even after a casual review it should be apparent that the log4j and
JSR47 APIs are <em>very</em> similar. For one, they are the only
logging APIs which are based on a named hierarchy. If you understand
one API, then understanding the concepts of the other should be a
breeze. There are differences however.

<h2>On Parents and  Children</h2>

<p>In JSR47, a parent logger knows about its children but not the
other way around. Children do not have links to their parent. For
example, the logger named <code>"foo"</code> knows about
<code>"foo.bar1"</code> and <code>"foo.bar2"</code>. However,
<code>"foo.bar1"</code> has no links to its parent <code>"foo"</code>.

<p>In log4j, it is exactly the other way around. A log4j category
contains a link to its parent but a parent does not have links to its
children.

<p>At first glance, this might look like a mundane implementation
detail but it is actually quite fundamental.

<ol>
<p><b><li>Configuration order matters</b>

<p>In JSR47, when you set the level of a logger, say
<code>wombat</code>, JSR47 traverses the tree below
<code>wombat</code>. In other words, the levels for all the loggers
descending from <code>wombat</code> are overwritten. This can be a
very expensive operation for large trees. In particular, for the most
common case where one sets the level of the root logger. However,
performance is not the point I am trying to make.

<p>In log4j, changing the priority of a category involves the change
of a single field. Children categories dynamically inherit the
priority of their parent by traversing the hierarchy tree upwards.

<p>It follows that with JSR47 if you configure the level for logger
"foo.bar1" before configuring the level for "foo", then the latter
instruction will overwrite the first exactly as if the first
instruction for configuring "foo.bar1" had never
existed. <em>Configuration order dependence is not a show stopper but
it is something that will bite you time and again.</em>

<p>In contrast, in log4j categories can be configured in any
order. You never have to worry about configuration order.

<p><b><li>Limited inheritance</b>

<p>In JSR47, a logger does not walk the hierarchy to inherit its level
but possesses a copy of it. 

<p>Unfortunately, in the JSR47 API, handlers cannot be inherited
because it would be prohibitively expensive to let each logger to
contain a distinct Vector of all inherited handlers, especially in
large trees.

<p>To circumvent this problem by JSR47 defines global handlers. A
logger logs to global handlers and to the handlers attached to itself
directly. <em>It does not inherit any handlers from the
hierarchy.</em>

<p>In log4j, appenders are inherited additively from the hierarchy. A
category will log to the appenders attached to itself as well as the
appenders attached to its ancestors. This might not seem like much
until the day you need handler inheritance; probably a week after you
decide to adopt a logging API.

<p>Similarly, in log4j resource bundles are inherited from the
hierarchy. In JSR47, a resource bundle <em>must</em> be attached to
each logger individually. There is no resource bundle inheritance in
JSR47. In practice, this means that you have to choose between
internationalization and the benefits of the named logger
hierarchy. It's one or the other. This limitation is particularly
surprising because support for internationalization is advocated as
one of the primary advantages of the JSR47 API.

</ol>

<h2>Bogus Levels</h2>

<p>JSR 47 defines the levels <code>ALL</code>, <code>SEVERE</code>,
<code>WARNING</code>, <code>INFO</code>, <code>CONFIG</code>,
<code>FINE</code>, <code>FINER</code>, <code>FINEST</code> and
<code>OFF</code>. Experience shows that the levels <code>ALL</code>
and <code>OFF</code> are never needed. The <code>SEVERE</code> and
<code>CONFIG</code> levels are unique to JSR47.

<p>Having three debugging levels <code>FINE</code>,
<code>FINER</code>, <code>FINEST</code> could seem like a good
idea. However, you will soon discover that even when by yourself, it
is hard to decide when to use which level. It is plain impossible in
groups.

<p>Log4j in contrast has a limited but self-evident set of priorities:
<code>FATAL</code>, <code>ERROR</code>, <code>WARN</code>,
<code>INFO</code> and <code>DEBUG</code>.

<p>Both JSR47 and log4j allow the user to extend the set of
priorities. Log4j supports subclasses of priorities in configuration
files as well as across the wire. JSR47 does not.

<h2>Limited functionality</h2>

<p>Log4j has appenders capable of logging to the console, to files, to
Unix Syslog daemons, to Microsoft NT EventLoggers, remote servers, to
JMS channels, automatically generate email etc. It can roll log files
by size or date and log asynchronously.

<p>JSR47 can log to the console, to files, to sockets and to a memory
buffer.

<p>Log4j has an extensible and powerful layout called the
<code>PatternLayout</code>.  JSR47 offers the much weaker
<code>SimpleFormatter</code> as an alternative.

<p>Log4j supports configuration through property files as well as XML
documents. JSR47 currently admits only property files. Moreover, the
language of JSR47 configuration files is very weak. In particular, you
can only configure one instance of a given handler class. <em>This
means that you can log to just one file at a time.</em>

<h2>Other differences</h2>

<p>There are many other details in which log4j differs from
JSR47. Even if the log4j core is small, the project contains a total
of over 30'000 lines of well-tested code. JSR47 contains about 5'000
lines of code. 

<p>Log4j has been around for a number of years, enjoys the support of
five active developers (committers) and is being used in thousands of
projects. Our site gets over 500 downloads each and every day, and the
numbers are on the rise.  Log4j has been ported to C++ and
Python. Companies are also offering commercial products extending
log4j.

<p>Here is a short list of opensource projects or sites that are known
to use log4j.

<ul>
<li><a href="http://www.jcorporate.com/html/products/expresso/logging.html">Espresso Framework</a>
<li><a href="http://www.free-project.org/">Free E-Democracy Project</a>
<li><a href="http://java.freehep.org">FreeHEP</a>
<li><a href="http://www.jboss.org">JBoss</a>

<li><a href="http://www.opensymphony.com/guidelines/logging.jsp">OpenSymphony</a>
<li><a href="http://theserverside.com">TheServerSide</a>
<li><a href="http://jakarta.apache.org/turbine/index.html">Turbine</a>
<li><a href="http://jakarta.apache.org/velocity/index.html">Velocity</a>
<li><a href="http://wired2.web.cern.ch/wired2/">WIRED</a>
 
</ul>


<p>By the way, log4j runs fine under JDK 1.1 and above. JSR 47 will
run under JDK 1.4 and only under JDK 1.4. Interestingly enough, no
package shipped with JDK 1.4 is using the JSR47 API.  

<p>Brian R. Gilstrap has <A
href="http://javalogging.sourceforge.net/">re-written</a> JSR47 API to
run under JDK 1.2 and 1.3. He has also published an <a
href="http://www.ociweb.com/jnb/archive/jnbJun2001.html">article</a>
in JavaWorld. This is all very promising but since
<code>java.util.logging</code> is under the <code>java.*</code>
namespace, when running under JDK 1.3, you will systematically
encounter:
<pre>
Exception in thread "main" java.lang.ExceptionInInitializerError: java.lang.SecurityException: Prohibited package name: java.util.logging
        at java.lang.ClassLoader.defineClass(ClassLoader.java:477)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:248)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
</pre>


<p>Jochen Hiller had observed this problem in early 2001 when he
implemented the JSR47 API by wrapping log4j.

<h2>Error Handling</h2>

In JSR 47 when an error occurs then either a
<code>RunTimeException</code> is thrown to the user or (in handlers
only) an internal field is set. In the first case, the
<code>RunTimeException</code> will cause your application to crash. In
the latter case, you can retrieve the last caught exception in the
handler by querying the <code>getException</code> method of that
handler. <em>The former is totally unacceptable while the latter is
impractical.</em>

<p>In log4j, under no circumstances are exceptions thrown at the
user. However, all appenders have an associated
<code>ErrorHandler</code>.  This <code>ErrorHandler</code> is invoked
by the appender whenever a handler-specific error occurs.  By default,
log4j appenders are associated with an
<code>OnlyOnceErrorHandler</code> which emits a message on the console
for the first error in an appender and ignoring all following errors.

<p>An <code>ErrorHandler</code> can implement an arbitrary error
handling policy. For example, after a failure to write to a database a
<code>JDBCAppender</code> can be redirected to fall back on a
<code>FileAppender</code>. This functionality is supported in XML
configuration files. You do not need to change a single line of client
code.

<p>But again who cares about errors, right?

<h2>Performance</h2>

<p>Logging performance must be studied in three distinct cases: when
logging is turned off, when turned on but due to priority comparison
logic not enabled, and when actually logging.  Please refer to the <a
href="manual.html#performance">log4j manual</a> for a more detailed
discussion of logging performance.

<p>When logging is turned on, log4j will be about three times slower
to decide whether a log statement is enabled or not. This is due to
the dynamic nature of log4j which requires it to walk the
hierarchy. To give you an idea about the figures involved, we are
talking about 90 <em>nanoseconds</em> instead of 30
<em>nanoseconds</em> on a 800Mhz Intel processor. In other words, one
million disabled logging requests will cost under a second in both
environments.

<p>In a shipped binary, you can turn off logging entirely and both
APIs will perform identically.  Note that if one is not careful, the
cost of parameter construction before invoking a disabled log
statement will overwhelm any other performance consideration.
Regardless of the API you decide to use, logging statements should
never be placed in tight loops, for example, before or after an
element swap instruction in a sort algorithm.

<p>In log4j, caller localization information is optional whereas in
JSR47 it is always extracted. Since the extraction of caller
localization is a very slow operation, in the common case where caller
information is not needed, log4j will log the same information 4 to
100 times faster. 


<h2>Lobby Sun</h2>

<p>If you feel that these differences are important, then this the
time to lobby Sun to adopt log4j as the logging API shipped with JDK
1.4. Since the JSR47 has not been yet reached final specification
stage nor formally approved, assuming enough demand, it should be
still possible to modify the JSR47 API. This will be much harder once
JDK 1.4 ships. Apparently, even the JSR47 experts group is divided on
the issue.

<p><b>Please direct your polite and personalized request to <a
href="mailto:java-logging-input@eng.sun.com">java-logging-input@eng.sun.com</a>
with Bcc: to <a href="mailto:cgu@qos.ch">cgu@qos.ch</a>.</b>

<p>By the way, e-mail to <code>java-logging-input@eng.sun.com</code>
does not go to the JSR47 experts group but is internal to Sun
Microsystems. <em>The address of the JSR47 experts group mailing list
is considered confidential information.</em> I do not know it myself.

<p>Over one hundred individuals, including some from very large
accounts, have written to Sun to express their concern, in their vast
majority pushing for the adoption of log4j. Their names and the
content of their request are listed below. I am very grateful for
their support. Some of these requests are quite detailed and
insightful.

<p><UL>
<li><p><a href="pub-support/ChristopherTaylor.html">Christopher Taylor</a> <!-- -->
<li><p>Jon Stevens
<li><p><a href="pub-support/PaulGrinchenko.html">Paul Grinchenko</a> <!-- -->
<li><p><a href="pub-support/CourtDemas.html">Court Demas</a> and his <a href="pub-support/CourtDemas2.html">follow up</a> <!-- -->
<li><p><a href="pub-support/NelsonMinar.html">Nelson Minar</a> <!-- -->
<li><p><a href="pub-support/RobertMahoney.html">Robert Mahoney</a> <!-- -->
<li><p><a href="pub-support/EllisTeer.html">Ellis Teer</a> 
<li><p><a href="pub-support/GuyLichtman.html">Guy Lichtman</a> <!-- -->
<li><p><a href="pub-support/MichaelMoser.html">Michael Moser</a> <!-- -->
<li><p><a href="pub-support/HenrikLundahl.html">Henrik Lundahl</a> 
<li><p><a href="pub-support/ThomasFenner.html">Thomas Fenner</a> <!-- -->
<li><p><a href="pub-support/EndreStolsvik.html">Endre St&oslash;lsvik</a> <!-- -->
<li><p><a href="pub-support/KnutErikBallestad.html">Knut Erik Ballestad</a> 
<li><p><a href="pub-support/HenrikFredholm.html">Henrik Fredholm</a> and his <a href="pub-support/HenrikFredholm2.html">follow up</a> to Graham.
<li><p><a href="pub-support/JohnVolkar.html">John Volkar</a> <!-- -->
<li><p><a href="pub-support/WilliamJaynes.html">William Jaynes</a> <!-- -->
<li><p><a href="pub-support/MichaelStacey.html">Michael Stacey</a> <!-- -->
<li><p><a href="pub-support/StacyCurl.html">Stacy Curl</a> <!-- -->
<li><p><a href="pub-support/DavidOwens.html">David Owens</a> <!-- -->
<li><p><a href="pub-support/EoinFlood.html">Eoin Flood </a> <!-- -->
<li><p><a href="pub-support/TonyDean.html">Tony Dean </a> <!-- -->
<li><p><a href="pub-support/AlexBlewitt.html">AlexBlewitt</a> 
<li><p><a href="pub-support/JamesProkash.html">James Prokash</a> <!-- -->
<li><p><a href="pub-support/RalfHaug.html">Ralf Haug</a> <!-- -->
<li><p><a href="pub-support/CarlBacher.html">Carl Bacher</a> <!-- -->
<li><p><a href="pub-support/DanTanner.html">Dan Tanner</a> <!-- -->
<li><p><a href="pub-support/BrentSprecher.html">Brent Sprecher</a> <!-- -->
<li><p><a href="pub-support/SteveWingfield.html">Steve Wingfield</a> <!-- -->
<li><p><a href="pub-support/AndersKristensen.html">Anders Kristensen</a> <!--  -->
<li><p><a href="pub-support/AbeMirrashidi.html">Abe Mirrashidi</a> <!-- -->
<li><p><a href="pub-support/JasonKitcat.html">Jason Kitcat</a> <!-- -->
<li><p><a href="pub-support/RonJacobs.html">Ron Jacobs</a> <!-- -->
<li><p><a href="pub-support/AndyDePue.html">Andy DePue</a>  and his <a href="pub-support/AndyDePue2.html">follow up</a> <!-- -->
<li><p><a href="pub-support/JoeLoda.html">Joe Loda</a> <!-- -->
<li><p><a href="pub-support/DavidMaharaj.html">David Maharaj</a> <!-- -->
<li><p><a href="pub-support/FrankBaxter.html">Frank Baxter</a> <!-- -->
<li><p><a href="pub-support/HenryLi.html">Henry Li</a> <!-- -->
<li><p><a href="pub-support/RichardWilliams.html">Richard Williams </a> <!-- -->
<li><p><a href="pub-support/JasonHeirtzler.html">Jason Heirtzler</a> <!-- -->
<li><p><a href="pub-support/ScottMiller.html">Scott Miller</a> 
<li><p><a href="pub-support/ChandraPatni.html">Chandra Patni</a> <!-- -->
<li><p><a href="pub-support/DanielHoppe.html">Daniel Hoppe </a> <!-- -->
<li><p><a href="pub-support/SebastienGuimont.html">Sebastien Guimont</a> <!-- -->
<li><p><a href="pub-support/ThomasQuas.html">Thomas Quas</a> <!-- -->
<li><p><a href="pub-support/JeffTurner.html">Jeff Turner</a> 
<li><p><a href="pub-support/JohnMunsch.html">John Munsch</a> <!-- -->
<li><p><a href="pub-support/DelEdwards.html">Del Edwards</a> <!-- -->
<li><p><a href="pub-support/Piper.html">Piper</a> <!-- -->
<li><p><a href="pub-support/TimColson.html">Tim Colson</a> <!-- -->
<li><p><a href="pub-support/HowardShip.html">Howard Ship</a> <!-- -->
<li><p><a href="pub-support/LewisGardner.html">Lewis Gardner</a> <!-- -->
<li><p><a href="pub-support/DanielSavarese.html">Daniel F. Savarese</a> <!-- -->
<li><p><a href="pub-support/PayamMirrashidi.html">Payam Mirrashidi</a> <!-- -->
<li><p><a href="pub-support/BruceDeen.html">Bruce W. Deen</a> 
<li><p><a href="pub-support/EmilyBache.html">Emily Bache</a> and her <a href="pub-support/EmilyBache2.html">follow up</a> <!-- -->
<li><p><a href="pub-support/JulienDubois.html">Julien Dubois</a> <!-- -->
<li><p><a href="pub-support/AlefArendsen.html">Alef Arendsen</a> <!-- -->
<li><p><a href="pub-support/SorenHilmer.html">S&oslash;ren Hilmer</a> 
<li><p><a href="pub-support/MaheshBhat.html">Mahesh Bhat</a> <!-- -->
<li><p><a href="pub-support/JeffLinwood.html">Jeff Linwood</a> 
<li><p><a href="pub-support/PeterMeulmeester.html">Peter Meulmeester</a> <!-- -->
<li><p><a href="pub-support/MichaelDuffy.html">Michael Duffy</a> <!-- -->
<li><p><a href="pub-support/BillGriffith.html">Bill Griffith</a> 
<li><p><a href="pub-support/DanielBram.html">Daniel Bram</a> <!-- -->
<li><p><a href="pub-support/RichardDallaway.html">Richard Dallaway</a> <!-- -->
<li><p><a href="pub-support/ChrisMein.html">Chris Mein</a> <!-- -->
<li><p><a href="pub-support/BenjaminRussellStocum.html">Benjamin Russell Stocum</a> <!-- -->
<li><p><a href="pub-support/GuyNirpaz.html">Guy Nirpaz</a> <!-- -->
<li><p><a href="pub-support/GrayJones.html">Gray Jones</a> <!-- -->
<li><p><a href="pub-support/CarlosPerez.html">Carlos Perez</a> <!-- -->
<li><p><a href="pub-support/PaulMichaelReilly.html">Paul Michael Reilly</a> <!-- -->
<li><p><a href="pub-support/MarcusAhnve.html">Marcus Ahnve</a> <!-- -->
<li><p><a href="pub-support/DavidDuddleston.html">David Duddleston</a> <!-- -->
<li><p><a href="pub-support/BrianPaulsen.html">Brian Paulsen</a> 
<li><p><a href="pub-support/AlexFernandez.html">Alex Fern�ndez</a> <!-- -->
<li><p><a href="pub-support/DanielStephan.html">Daniel Stephan</a> <!-- -->
<li><p><a href="pub-support/AlexanderEvsukov.html">Alexander Evsukov</a> <!-- -->
<li><p><a href="pub-support/StevenSagaert.html">Steven Sagaert</a> <!-- -->
<li><p><a href="pub-support/DougErickson.html">Doug Erickson</a> <!-- -->
<li><p><a href="pub-support/ScottGilpin.html">Scott Gilpin </a> <!-- -->
<li><p><a href="pub-support/NateSammons.html">Nate Sammons</a> author of <a href="http://protomatter.sourceforge.net">Protomatter Syslog</a> <!-- -->
<li><p><a href="pub-support/StephanSchmidt.html">Stephan J. Schmidt</a> <!-- -->
<li><p><a href="pub-support/JochenBedersdorfer.html">Jochen Bedersdorfer</a> <!-- -->
<li><p><a href="pub-support/BalajiKithiganahalli.html">Balaji Kithiganahalli</a> and his <a href="pub-support/BalajiKithiganahalli2.html">follow up</a> <!-- -->
<li><p><a href="pub-support/ChrisYearsley.html">Chris Yearsley</a> 
<li><p><a href="pub-support/ScottFleming.html">Scott Fleming</a> <!-- -->
<li><p><a href="pub-support/PaulCraven.html">Paul Craven</a> <!-- -->
<li><p><a href="pub-support/BruceKroeze.html">Bruce Kroeze</a> <!-- -->
<li><p><a href="pub-support/AndrewHarris.html">Andrew Harris</a> <!-- -->
<li><p><a href="pub-support/BernshtamPavel.html">Bernshtam Pavel</a> <!-- -->
<li><p><a href="pub-support/TomJanofsky.html">Tom Janofsky</a> 
<li><p><a href="pub-support/StephenAshcroft.html">Stephen Ashcroft</a> <!-- -->
<li><p><a href="pub-support/BradleySchatz.html">Bradley Schatz</a> <!-- -->
<li><p><a href="pub-support/ErikBergersjo.html">Erik Bergersj&ouml;</a> <!-- -->
<li><p><a href="pub-support/KevinHuber.html">Kevin Huber</a>  <!-- -->
<li><p><a href="pub-support/LeeTHall.html">Lee T Hall</a> <!-- -->
<li><p><a href="pub-support/JoelSchneider.html">Joel Schneider</a> <!-- -->
<li><p><a href="pub-support/IvanRosero.html">Ivan Rosero</a> <!-- -->
<li><p><a href="pub-support/ArndtSchoenewald.html">Arndt Schoenewald</a> <!-- -->
<li><p><a href="pub-support/ScottEllsworth.html">Scott Ellsworth</a> <!-- -->
<li><p><a href="pub-support/BrettMorgan.html">Brett Morgan </a> <!-- -->
<li><p><a href="pub-support/HorstScheruga.html">Horst Scheruga</a> <!-- -->
<li><p><a href="pub-support/AxelBoness.html">Axel Boness</a> <!-- -->
<li><p><a href="pub-support/EdHowland.html">Ed Howland</a> <!-- -->
<li><p><a href="pub-support/FredericSoulier.html">Frederic Soulier</a> <!-- -->

<!--


<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 
<li><p><a href="pub-support/ .html"></a> 

-->



</UL>

<p>Most of the e-mail notes are reproduced with permission. However,
do not hesitate to contact <a href="cgu@qos.ch">cgu@qos.ch</a> in case
you are uncomfortable seeing your name or the contents of your request
reproduced publicly.

<h2>Sun's response</h2>

The gist of Graham Hamilton's <a
href="pub-support/GrahamHamilton.html">response</a> consists of declaring: "too
late in the Merlin cycle". This is of course a valid concern. He also
explains:

<pre>
  In designing the APIs we've tried to draw from numerous
  sources and we've tried to support a wide set of requirements.
</pre>

<p>Unfortunately, given the uproar that this API is causing, it is
becoming increasingly clear that the resulting API is unlikely to meet
a wide set of requirements. The apparent failure of JSR47 API is also
casting a shadow on the nature of the Java Community Process. <a
href="http://www.zdnet.com/eweek/stories/general/0,11011,2666270,00.html">Michael
C. Daconta</a> has some interesting comments on the JCP.  All said and
done, Java remains a wonderful computing platform.  Sun deserves
credit for their ongoing investment. They have also introduced a
number of amazingly innovative APIs. However, no one gets it right
<em>all</em> the time.

<p>Given the volume and the quality of support we are receiving from
the community, I would not be surprised to see the JSR47 API retracted
or replaced wholesale by log4j.

</body> </HTML>

[See repo JSON]