Помогите устранить неполадки JAXB демаршал NPE - PullRequest
7 голосов
/ 15 июня 2011

Я работаю с API, который не имеет контроля, который возвращает XML. По сути, у меня есть directory объект, который может содержать несколько directory и file объектов, которые не обернуты ни одним тегом, кроме нескольких других примитивных полей. file объект содержит несколько примитивных полей и 2 списка, которые обернуты тегами tPathList и oPathList.

Ниже приведен пример такого XML:

<hwreply>
  <result>1</result>
  <directory>
    <file>
      <created>DATE</created>
      <modified>DATE</modified>
      <name>STRING</name>
      <size>INT</size>
      <tPath>STRING</tPath>
      <oPath>STRING</oPath>
      <aPath>STRING</aPath>
      <tPathList> 
        <tPath>STRING</tPath>
        ...
      </tPathList>
      <oPathList> 
        <oPath>STRING</oPath>
        ...
      </oPathList>    
    </file>
    <file>...</file>
    ...
    <directory>...</directory>
    <directory>...</directory>
    ...
    <nEntries>5</nEntries>
    <created>DATE</created>
    <modified>DATE</modified>
  </directory>
</hwreply>

Я создал объекты Directory и File, а также OpenDirectory, который является корневым. Когда я звоню

OpenDirectory od = response.getEntity(OpenDirectory.class);

Я получаю следующее исключение:

Exception in thread "main" java.lang.NullPointerException
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:290)
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:254)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106)
    at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:195)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:507)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:145)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2938)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
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:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
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:119)
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 com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:120)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:103)
at com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider.readFrom(XMLRootElementProvider.java:115)
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:111)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
at liveperson.lphosting.plugins.cdn.proxy.highwinds.HighwindsProxy.getDirectory(HighwindsProxy.java:49)
at liveperson.lphosting.plugins.cdn.proxy.highwinds.HighwindsProxy.main(HighwindsProxy.java:59)

Я подумал, что это относится к одному из моих списков, но я не мог понять, где я ошибся. Любая помощь будет оценена.

Заранее спасибо.

Ниже приведены классы (за исключением нескольких полей / методов):

@XmlRootElement(name = "hwreply")
public class OpenDirectory extends ResponseBase {

@XmlElement(name="session")
public Session getSession() {...}

public void setSession(Session session) {...}

@XmlElement(name="directory")
public Directory getDirectory() {...}

public void setDirectory(Directory directory) {...}
}



public class Directory {

...
private List<Directory> directories;
private List<File> files;

@XmlElement(name="nEntries")
public int getnEntries() {...}

public void setnEntries(int nEntries) {...}

@XmlElement(name="name")
public String getName() {... }

public void setName(String name) {...  }

@XmlElement(name="readonly")
public boolean isReadonly() {...  }

public void setReadonly(boolean readonly) { ... }

@XmlElement (name="created")
public String getCreated() { ... }

public void setCreated(String created) { ... }

@XmlElement(name="modified")
public String getModified() {... }

public void setModified(String modified) {...    }

@XmlElements(
        @XmlElement(name="directory", type=Directory.class)
)
public List<Directory> getDirectories() {
    return directories;
}

public void setDirectories(List directories) {
    this.directories = directories;
}

@XmlElements(
        @XmlElement(name="file", type=File.class)
)
public List<File> getFiles() {
    return files;
}

public void setFiles(List files) {
    this.files = files;
}
}



public class File {

private List<String> tPathList;
private List<String> oPathList;

@XmlElement(name="xferStatus")
public int getXferStatus() {...}

public void setXferStatus(int xferStatus) {...}

@XmlElement(name="size")
public int getSize() {...}

public void setSize(int size) {...}


@XmlElement(name="tPath")
public String gettPath() {...}

public void settPath(String tPath) {...}

@XmlElement(name="oPath")
public String getoPath() {...}

public void setoPath(String oPath) {...}

@XmlElementWrapper(name="tPathList")
@XmlElements(
        @XmlElement(name="tPath", type=String.class)
)
public List gettPathList() {
    return tPathList;
}

public void settPathList(List tPathList) {...}

@XmlElementWrapper(name="oPathList")
@XmlElements(
        @XmlElement(name="oPath", type=String.class)
)
public List getoPathList() {
    return oPathList;
}

public void setoPathList(List oPathList) {
    this.oPathList = oPathList;
}
}

Ответы [ 2 ]

6 голосов
/ 22 сентября 2011

Проблема решается самим ОП, добавляя его в качестве ответа.

Нашел проблему.Если это кому-нибудь поможет:

setFiles(List files) в классе File, должно быть setFiles(List<File> files).

1 голос
/ 16 октября 2013

У меня тоже было такое же исключение. но решение было другим. Я делюсь этим здесь, для будущих решателей проблем. Когда вы вызываете JAXBContext.newInstance(), посмотрите на возвращенный объект.

Обычно это должен быть тип com.sun.xml.bind.v2.runtime.JAXBContextImpl. Однако, если это происходит из какой-то библиотеки glassfish3, например:

jar:file.../glassfish3/glassfish/modules/jaxb-osgi.jar

, который бросил мне то же исключение A изменил порядок classpath, и, наконец, демаршаллинг работал нормально, если JAXBContext.newInstance() находит первый реализующий класс JAXBContext из этого jar:

jar:file:.../.m2/repository/com/sun/xml/bind/jaxb-impl/2.x.x/jaxb-impl-2.x.x.jar
...