JDK-6524460 : EntityResolver2 no longer used in Java6
  • Type: Bug
  • Component: xml
  • Sub-Component: org.xml.sax
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-02-13
  • Updated: 2012-04-25
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
I am using JDOM to parse an XML document. By default, JDOM will instantiate

com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser

as SAXParser. I am explicitly setting an EntityResolver2 to the parser in order to handle entities in a XML document, even if no DTD is included.

This works in Java 5 but fails in Java 6:

org.xml.sax.SAXParseException: The entity "auml" was referenced, but not declared.

I noticed that Java 6 would use a different parser from Xerces. This will break all users of EntityResolver2 that rely on the JDK recognizing and using it.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.) Set an EntityResolver2 to the SAXParser that returns the DTD containing common entities from the getExternalSubset() method

2.) Parse a XML that contains undeclared entities:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title>entities_title#&auml;&ouml;&uuml;&amp;&lt;&gt;</title>
	  	<link>entities_link</link>
	  	<description>entities_description#&auml;&ouml;&uuml;&amp;&lt;&gt;</description>

		<item>
			<title>entities_item1.title#&auml;&ouml;&uuml;&amp;&lt;&gt;</title>
	        <link>entities_item1.link</link>
	        <description>entities_item1.description#&auml;&ouml;&uuml;&amp;&lt;&gt;</description>
		</item>
	</channel>
</rss>

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The SAXParser asks the EntityResolver2 for the external DTD and uses it.
ACTUAL -
See exception below.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Caused by: org.xml.sax.SAXParseException: The entity "auml" was referenced, but not declared.
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1411)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(XMLDocumentFragmentScannerImpl.java:1885)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3017)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:645)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:453)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:851)
	at org.rssowl.core.interpreter.internal.DefaultSaxParserImpl.parse(DefaultSaxParserImpl.java:116)
	at org.rssowl.core.interpreter.Interpreter.interpret(Interpreter.java:114)
	at org.rssowl.core.tests.interpreter.InterpreterTest.testUndeclaredEntities(InterpreterTest.java:431)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
	at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
	at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
	at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
	at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
	at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
	at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethod(EclipseAppContainer.java:529)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:148)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:169)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:476)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:416)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1124)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1099)


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Add a DTD to the XML that declares all entities used in the XML.