You found a bug (two, in fact) in the JDK. Congratulations! (Or condolences, I suppose).
The first error is that it is a "fatal" error, but it will raise ErrorListener.error() instead of ErrorListener.fatalError() . If you put the println operator in error() in your example, you will see that it is being called.
The second mistake is that ignoring the first one above what you do should work.
But this is not so.
Throwing your example into the debugger and delving into the JDK, I found that the error listener does not propagate down to the underlying XMLScanner and XMLErrorReporter .
What happens is that XMLErrorReporter creates an instance of com.sun.org.apache.xerces.internal.util.DefaultErrorHandler and calls its method fatalError() , which is what splashes the [fatal error] message to stderr .
In particular, this happens on line 422 com.sun.org.apache.xerces.internal.impl.XMLErrorReporter
After that, it jumps the exception onto the stack, and TransformerImpl fires it for your listener.
What should happen is that these base classes must either have a proxy server for the higher level listener you were in, or create a local no-op listener to disable output at lower levels. I suspect this is the last one, because otherwise you will receive a notification twice.
I need to take a closer look at the abstraction tree and debug the build chain to find out why this is not happening, but unfortunately this is a bug in the JDK and there is no way to control / prevent this. (This is testing in Java 1.7.0_25-b15).
source share