It's not very often that I get upset at a piece of code, but Javadoc is
getting me dangerously close to the cursing point.
EJBGen uses Javadoc to parse its
annotations. First of all, the fact that the Javadoc API doesn't use the
standard Java conventions (accessors should start with get and set, etc...) is
already a constant source of mistakes for me. But what has been irritating
me a lot over these past two years is its insistence at displaying warnings
disguised as errors. Here is a typical example:
C:\weblogic\dev\sandbox\cbeust\ejbgenlet\examples\bands>javadoc -doclet weblogic.tools.ejbgen.EJBGen -d gen src\*Bean.java
Loading source file src\ArtistBean.java...
Loading source file src\BandBean.java...
Loading source file src\FanClubBean.java...
Loading source file src\MusicLibraryBean.java...
Loading source file src\RecordingBean.java...
Constructing Javadoc information...
src\BandBean.java:134: cannot resolve symbol
symbol : class FanClubLocal
location: class examples.ejb20.bands.BandBean
The error in bold appears something like twenty times for this simple example
(resulting in eighty lines of useless information that convinces the user that
something is wrong with their files).
My first idea to get rid of this logorrhea was brute force: redirect
System.out and System.err so that I can filter out the noise. This turned
out to be impossible since this trace is printed before my doclet ever gets
Then I started exploring more civilized solutions, like examining how Javadoc reports these messages. It turns out this is
handled by a class called Messenger that implements the interface
DocErrorReporter. An instance of that class can be found on the RootDoc,
the object that represents the entirety of my document and that gets passed to
my doclet when it is ready to be run. Unfortunately, I didn't see any "setDocErrorReported()"
method on the RootDoc, so then again, it was a dead-end.
My only chance now is to be able to create my own RootDoc, where I would
implement my own DocErrorReporter methods, hence allowing me to squelch the
A breakpoint in my start() routine allowed me to see that the RootDoc I was
receiving was an instance of RootDocImpl. I set a breakpoint in the
constructor of RootDocImpl, relaunched my example and held my breath. The
debugger gladly stops, I step up the stack trace to finally see who is creating
the document. This is when I let out a loud curse:
return (new RootDocImpl(docenv , listClasses(listbuffer10.toList()) ,
listbuffer9.toList() , list5));
Have the Sun engineers never heard of the concept of a factory? Apparently
not, and the concept of extensibility is equally unknown to them.
Javadoc is a
distressingly poorly engineered piece of code and I can't wait to finally be
able to get rid of it, because right now, short of patching the boot class path
of my application (which is a violation of the Java license), I am completely