2016-12-23 2 views
0

У меня есть кусок JAXB немаршалинг код, который выглядит следующим образом:JAXB демаршаллинга не удалось на одной машине, но не другие/Также работал в тестовом модуле

Foo foo = null; 
try { 
    logger.debug(methodNamePrefix + "xmlString is \n" + xmlString); 
    JAXBContext jaxbContext = JAXBContext 
           .newInstance(Foo.class); 
    Unmarshaller u = jaxbContext.createUnmarshaller(); 
    u.setEventHandler(new DefaultValidationEventHandler()); 
    StreamSource streamsource = new StreamSource(new StringReader(xmlString)); 
    foo = (Foo) u.unmarshal(streamsource); 
    sanityCheckDbpAfterUnmarshalling(xmlString, foo); 

}catch(Exception e){ 
    throw new AnalysisNotPossibleException(); 
} 
if (foo==null){ 
    throw new AnalysisNotPossibleException(); 
} 

Этот код не работает в течение нескольких месяцев, до недавнего времени, по одна машина, она начала сбой. Когда он потерпел неудачу, он выплюнул, казалось бы, законную жалобу, за исключением того, что один и тот же фрагмент кода с одним и тем же вводом xmlString при запуске на другом компьютере или даже на том же компьютере, но в модульном тесте, не стал бы жаловаться:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"entry"). Expected elements are (none) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:101) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:243) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:478) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459) 
     at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:148) 

Я вполне уверен, что это связано с некоторой локальной средой этой машины, но я не мог понять, что это такое. Я пробовал очистить все свои двоичные файлы в своем Eclipse.

Я знаю, что это требует отладки, и я не ожидаю полного ответа. Но я был бы признателен за любые идеи для некоторых вещей, которые я могу проверить. Благодаря!

Обновлено

Класс Foo выглядит следующим образом:

@XmlRootElement 
public class Foo implements Serializable{ 
    private static final long serialVersionUID = -4550266352252980254L; 

    @XmlElement 
    private HashMap<String, SomeProperty> mapAllPortletProperty = 
      new HashMap<String, SomeProperty>(); 
    ... 

И строка XML выглядит следующим образом

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<foo> 
    <mapAllPortletProperty> 
     <entry> 
      <key>Portlet 6262</key> 
      <value> 
       <apIdStrAtBirth>4536</apIdStrAtBirth>    
       ... 

2 Update

Спасибо за всю помощь до сих пор. Это помогло мне подумать об этих двух аспектах:

  1. Ресурс утечки? StreamSource и StringReader держат на некоторые ресурсы после того, как они сделаны с помощью unmarshalling?
  2. Безопасность резьбы? c.f. Это сообщение о "JAXB creating context and marshallers cost"

Для # 1 я проверил, что утечки ресурсов отсутствуют. У меня также есть программа стресс-теста, и она делает много неузнаваемости. Я не заметил, что в программе постоянно растет объем памяти.

Для # 2, я переписал свой код так, что для каждого класса, который нуждается в , чтобы быть unmarshalling, мой код создает экземпляр JAXBContext только один раз.

К сожалению, с приведенным выше новым пониманием я до сих пор не смог найти , чтобы найти причину проблемы. Более глубокое понимание приветствуется!

+0

Класс Foo и .xml могут помочь –

+0

Спасибо! Добавлена ​​информация – leeyuiwah

+0

Все ли машины, работающие с * той же * версией Java? – Andreas

ответ

0

После большой отладки, я нашел причину проблемы.

В одном из моих папок было две связанными JAXB JAR-файлов сидят:

$ find . -name "jaxb*" -exec ls -l {} \; 
-rwx------+ 1 leecy None 89967 Mar 19 2014 ./war/WEB-INF/lib/jaxb-api-2.1.jar 
-rwx------+ 1 leecy None 876610 Mar 19 2014 ./war/WEB-INF/lib/jaxb-impl-2.1.13.jar 

Я думаю, что уже есть ссылки реализация JAXB, который поставляется с виртуальной машиной Java (я использую Oracle/Sun в JDK 1.7 .0_51), и нам НЕ нужны эти дополнительные файлы JAR, не так ли? И их присутствие на самом деле может запутать мою программу и привести к загрузке другого JAXBContextImpl. По какой-то причине такая реализация не смогла бы размонтировать XML-файл.

Вдохновленный этим blog post, у меня есть моя программа распечатывает имя точного класса реализации после конкретизации, и я получил следующие результаты:

Если я удалил лишние файлы JAR, моя программа печататься эту строку, и демаршаллинга будет работать:

getJcMap(): Just instantiated an JAXBContext: class com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl 

Если бы я оставил их в свою программу, отпечатанное это вместо того, чтобы, и демаршаллинга потерпит неудачу:

getJcMap(): Just instantiated an JAXBContext: class com.sun.xml.bind.v2.runtime.JAXBContextImpl 

Это объясняет, почему проблема возникла только с этой конкретной машиной с этой конкретной папкой проекта, но не с другой средой.

Так что я удалил эти дополнительные файлы JAR, и проблема была решена!

Спасибо всем! Счастливых праздников!

Смежные вопросы