Given a test case [1], a XMLDecoder with the MockClassLoader and
ExceptionListener is created.
The MockClassLoader only throws ClassNotFoundException. The
ExceptionListener only records the exceptions.
Run this test case on Harmony and RI to use this XMLDecoder to readObject()
from a ByteArrayInputStream.
RI will record ClassNotFoundException when the readObject() method is
called, but Harmony won't.
The content of ClassNotFoundException from RI is given as [2].
The Harmony XMLDecoder parses the ByteArrayInputStream and store all the
java objects into the readObjs stack.
Only if the class name of the object is not primitive (int, byte, short
...), classloader is called.
When the readObject method is called, then it will directly return the
corresponding object from readObjs stack.
It is possible that the RI XMLDecoder will always parse ByteArrayInputStream
and use classloader to load class and return the corresponding object once
the readObject is
Shall we follow the "RI's probable behavior"?
[1] public class TestXMLDecoder {
static byte xml123bytes[] = null;
static MockClassLoader mockClassLoader = null;
static ExceptionListener exceptionListener = null;
static Vector<Exception> exceptions = new Vector<Exception>();
static class MockClassLoader extends ClassLoader {
public Class<?> loadClass(String name) throws ClassNotFoundException
{
throw new ClassNotFoundException();
}
protected Class<?> findClass(String name) throws
ClassNotFoundException {
throw new ClassNotFoundException();
}
}
static {
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
XMLEncoder enc = new XMLEncoder(byteout);
enc.writeObject(Integer.valueOf("1"));
enc.writeObject(Boolean.valueOf("true"));
enc.writeObject(Double.valueOf("3.2"));
enc.close();
xml123bytes = byteout.toByteArray();
mockClassLoader = new MockClassLoader();
exceptionListener = new ExceptionListener() {
public void exceptionThrown(Exception e) {
exceptions.add(e);
}
};
}
public static void main(String[] args) {
TestXMLDecoder testXMLDecoder = new TestXMLDecoder();
XMLDecoder xmlDecoder = new XMLDecoder(new ByteArrayInputStream(
xml123bytes), testXMLDecoder, exceptionListener,
mockClassLoader);
System.out.println("before readObject, exceptions_size="
+ exceptions.size());
try {
xmlDecoder.readObject();
xmlDecoder.readObject();
xmlDecoder.readObject();
} catch (ArrayIndexOutOfBoundsException e) {
// ignored
}
System.out.println("after readObject, exceptions_size="
+ exceptions.size());
// print the exceptions info
for (int index = 0; index < exceptions.size(); index++) {
exceptions.get(index).printStackTrace();
}
}
}
[2] java.lang.ClassNotFoundException
at
org.apache.harmony.beans.tests.java.beans.TestXMLDecoder$MockClassLoader.loadClass(TestXMLDecoder.java:17)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.sun.beans.ObjectHandler.classForName(Unknown Source)
at com.sun.beans.ObjectHandler.classForName2(Unknown Source)
at com.sun.beans.ObjectHandler.startElement(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown
Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentScannerImpl$ContentDispatcher.scanRootElementHook(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
Source)
at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at java.beans.XMLDecoder.getHandler(Unknown Source)
at java.beans.XMLDecoder.readObject(Unknown Source)
at
org.apache.harmony.beans.tests.java.beans.TestXMLDecoder.main(TestXMLDecoder.java:46)