2013-08-28 5 views
0

Я наблюдаю действительно странное поведение в библиотеке XStream при чтении созданного файла и использовании Patter.compile по результатам При запуске он дает исключение нулевого указателя , но он отлично работает, если я запускаю он шаг за шагом в режиме отладки.
I'v сузил его до Pattern.complie. Если я просто читаю значение для строковой переменной, он отлично работает, если я использую Pattern.complie («. *»), Используя метод unmarshal, он тоже отлично работает
Я использую Java 7 и XStream 1.4.4
Я думаю, что это связано с читателем.getAttribute («ключ»), возвращающим нуль, но не при отладке Любая идея, почему это происходит?
Вот что у меня есть:
Мой классPattern.complie breaks XStream

import java.util.regex.Pattern; 
public class A { 
private Pattern key; 
ArrayList<A> subTree; 
public A(HierarchicalStreamReader reader, UnmarshallingContext context){ 
    this.key=Pattern.compile(reader.getAttribute("key")); 
      // String a = reader.getAttribute("key") - Works fine 
      // this.key=Pattern.compile(a) - Breaks 
    subTree=new ArrayList<A>(); 
    reader.moveDown(); 
    while(reader.hasMoreChildren()) { 
     subTree.add(new A(reader,context)); 
    } 
    reader.moveUp(); 
} 
} 

XStream преобразователь класса

public class AConverter implements Converter { 
    public boolean canConvert(Class clazz) { 
     return A.class.isAssignableFrom(clazz); 
    } 

    public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { 

    } 

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 
     reader.moveDown(); 
     A n = new A(reader,context); 
     reader.moveUp(); 
     return n; 
    } 

}

Тестовый случай

public void testA() throws FileNotFoundException, IOException, ClassNotFoundException{ 
    XStream xstream = new XStream(); 
    xstream.alias("MessageFieldMappings", A.class); 
    xstream.registerConverter(new AConverter()); 
    ObjectInputStream in = xstream.createObjectInputStream(new FileInputStream("test1.xml")); 
    A rootNode = (A) in.readObject(); 
    in.close(); 

} 

Тестовый файл (test1.xml)

<object-stream> 
<MessageFieldMappings> 
<RootMapping> 
    <FieldMap key=".*"> 
    <FieldMap key="A.*"> 
     <FieldMap key="AB.*"/> 
     <FieldMap key="AC.*"/> 
    </FieldMap> 
    <FieldMap key="D.*"/> 
    </FieldMap> 
</RootMapping> 
</MessageFieldMappings> 
</object-stream> 

Я получаю ошибку

com.thoughtworks.xstream.converters.ConversionException: null : null 
---- Debugging information ---- 
cause-exception  : java.lang.NullPointerException 
cause-message  : null 
class    : nz.orion.monkPraser.praser.fieldConverter.A 
required-type  : nz.orion.monkPraser.praser.fieldConverter.A 
converter-type  : nz.orion.monkPraser.praser.fieldConverter.AConverter 
path    : /MessageFieldMappings/RootMapping 
line number   : 3 
version    : null 
------------------------------- 
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79) 
... 

ответ

1

Ключ находится в

path    : /MessageFieldMappings/RootMapping 
line number   : 3 

Вы псевдонимами MessageFieldMappings к классу A, поэтому, когда он видит MessageFieldMappings это будет вызывать преобразователь, который будет moveDown элементу RootMapping и попытаться извлечь атрибут key. Он не имеет одного, следовательно, NPE.

Вам нужен дополнительный уровень MoveDown/Up в конвертере:

reader.moveDown(); // RootMapping 
reader.moveDown(); // First FieldMap 
A n = new A(reader,context); 
reader.moveUp(); 
reader.moveUp(); 
return n; 
+0

Да его совершенно очевидно, на самом деле я не знаю, как я пропустил это. Большое спасибо за ваше время! Я думаю, мой отладчик может игнорировать NullPointer – iddqd