XMLDecoder.readObject()上的ArrayIndexOutOfBoundException

时间:2018-07-11 05:23:20

标签: java arrays java-8 xml-serialization indexoutofboundsexception

程序中有一些情况,如下所示,我将从属性文件中获取空对象

<?xml version="1.0" encoding="UTF-8"?> 
 <java version="1.4.1" class="java.beans.XMLDecoder"> 
 <object class="java.util.Map">
</object>
</java>

在下面的代码中读取空对象

public Object translateObj(
        String data,
        PropertyDefinition propDef) {
        try {
            XMLDecoder decoder =
                new XMLDecoder(new BufferedInputStream(new ByteArrayInputStream(data.getBytes("UTF-8"))));

            Object object = decoder.readObject();

            decoder.close();

            return object;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("XmlNativeTranslator.translateFromStorage: " +
                " Unable to UTF-8 encode inputData " + data.toString());
        } catch (ArrayIndexOutOfBoundsException e) {
            StringBuffer s = new StringBuffer();
            s.append("Failed to translate property definition key [");
            s.append(propDef.getKey());
            s.append("] XML contents [");
            s.append(data.toString());
            s.append("]");
            throw new RuntimeException(s.toString(), e);
        }
    }

在尝试读取上面的代码中的行解码器中的空对象时,readObject()我遇到以下错误

  

java.lang.RuntimeException:XmlNativeTranslator.translateFromStorage:   无法转换属性定义键[FORMS_KEY] XML   内容[]造成原因:   java.lang.ArrayIndexOutOfBoundsException:0

需要一种解决这种情况的方法

1 个答案:

答案 0 :(得分:0)

java.util.Map是一个接口,您永远不要以序列化的形式遇到它,因为不可能有接口的直接实例。

例如,空地图的有效表达式为

<object class="java.util.HashMap"/>

<object class="java.util.Collections" method="emptyMap"/>

<object class="java.util.Properties"/>

XMLDecoder具有在特殊情况下继续进行操作的可疑功能,这会导致ArrayIndexOutOfBoundsException作为后续错误。

您可以强制其引发实际异常:

XMLDecoder dec = new XMLDecoder(new InputSource(new StringReader(data)));
dec.setExceptionListener(ex -> {
    throw ex instanceof RuntimeException? (RuntimeException)ex:
        new RuntimeException("Failed to translate property definition key"+
            " ["+propDef.getKey()+"] XML contents ["+data+"]", ex);
});
Object object = dec.readObject();
return object;

请注意,使用StringReader不会处理任何编码错误。我还删除了close()步骤,因为StringReader没有附加资源,在特殊情况下,当我们使用try-with-resource时,XMLDecoder.close()会导致更多后续错误。

此处手动使用StringBuffer不能比字符串串联更好。在Java 5之前,编译器将生成几乎相同的代码,因为Java 5使用StringBuilder生成了相似的代码,效率更高,更不用说Java 9和更高版本了。

在示例输入中运行此代码会产生

Exception in thread "main" java.lang.RuntimeException: Failed to translate property definition key [] XML contents [<?xml version="1.0" encoding="UTF-8"?> 
 <java version="1.4.1" class="java.beans.XMLDecoder"> 
 <object class="java.util.Map">
</object>
</java>]
    at ListFiltersToGetMatchingRecords.lambda$main$0(ListFiltersToGetMatchingRecords.java:35)
    at com.sun.beans.decoder.DocumentHandler.handleException(DocumentHandler.java:359)
    at com.sun.beans.decoder.NewElementHandler.getValueObject(NewElementHandler.java:126)
    at com.sun.beans.decoder.ElementHandler.endElement(ElementHandler.java:169)
    at com.sun.beans.decoder.DocumentHandler.endElement(DocumentHandler.java:318)
… shortened …
    at com.sun.beans.decoder.DocumentHandler.parse(DocumentHandler.java:372)
    at java.beans.XMLDecoder$1.run(XMLDecoder.java:201)
    at java.beans.XMLDecoder$1.run(XMLDecoder.java:199)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.beans.XMLDecoder.parsingComplete(XMLDecoder.java:199)
    at java.beans.XMLDecoder.readObject(XMLDecoder.java:250)
    at ListFiltersToGetMatchingRecords.main(ListFiltersToGetMatchingRecords.java:38)
Caused by: java.lang.InstantiationException: java.util.Map
    at java.lang.Class.newInstance(Class.java:427)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
… shortened …
    at java.beans.Statement.invoke(Statement.java:182)
    at java.beans.Expression.getValue(Expression.java:155)
    at com.sun.beans.decoder.ObjectElementHandler.getValueObject(ObjectElementHandler.java:166)
    at com.sun.beans.decoder.NewElementHandler.getValueObject(NewElementHandler.java:123)
    ... 24 more
Caused by: java.lang.NoSuchMethodException: java.util.Map.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 42 more