Nullzeigerausnahme in JAXB RI ClassFactory

8

Einführung

Mein Freund und ich arbeiten an einer JavaFX-Anwendung, die als Planer für unsere Schule dient. Wir haben Aufgaben (Hausaufgaben für Klassen), Veranstaltungen, Kurse und Studenteninformationen. In einem Versuch, Daten dauerhaft auf der Festplatte des Benutzers zu speichern, verwenden wir JAXB.

Wir haben unsere Klassen kommentiert und können die Task-Klasse in einem Wrapper erfolgreich marshallen. Das Problem wird aus der tasks.xml -Datei entfernt.

Hier sind die relevanten Codezeilen:

Task.java

%Vor%

TaskListWrapper.java:

%Vor%

Methode in AppData.java

Es handelt sich um das Speichern und Entpacken von Dateien.

%Vor%

saveObject () -Methode in derselben Klasse:

%Vor%

InitFiles () in App.java

Beachten Sie den Kommentar, der auf die Nullzeigerausnahme

hinweist %Vor%

Gut formatiertes XML-Dokument aus dem Marshalling:

%Vor%

Die Ausnahme:

%Vor%

Der Nullzeiger ist in der //TODO in der Methode initFiles() angegeben:

%Vor%

Dinge, die wir versucht haben:

  • Mit den Namen und Anmerkungen. Es scheint nicht, als wäre die Benennung das Problem.
  • Sysuting des Dateiverzeichnisses, um sicherzustellen, dass es korrekt ist.
  • Sysuting der Klassen, die der JAXBContext kennt. Es erkennt die Klassen Task und TaskListWrapper .
  • Sysuting um.toString() . Es zeigt eine gültige Adresse im Speicher an, so dass das um -Objekt selbst nicht die nullpointer-Ausnahme auslöst.
  • Ändern der Position von TaskListWrapper.java auf dasselbe Paket wie Task.java .
  • Versuchen Sie, eine einzelne Aufgabe zu entpacken, indem Sie die XML-Datei so ändern, dass nur ein <task> als Wurzelelement verwendet wird, wenn ich

    ändere %Vor%

    bis

    %Vor%

Orte, an denen wir nach Antworten gesucht haben:

  • Ссылка
  • Eine Vielzahl von Stackoverflow-Fragen, die mit dem Bug mit der @XMLAttribute Annotation zu tun hatten. Da wir diese nicht verwenden, ist dieser Bug nicht relevant
  • Java lernen: 4. Ausgabe von Patrick Niemeyer und Daniel Leuck. Wir haben ihre genaue Art der Einrichtung des Unmarshallers kopiert. Sie haben einen einfachen Ansatz:

    %Vor%

Frage

Warum wirft TaskListWrapper taskList = (TaskListWrapper) um.unmarshal(tasks); eine Nullzeiger-Ausnahme?

    
Tom Magnusson 08.03.2015, 17:26
quelle

1 Antwort

3

JAXB ist nicht mit FXCollections wie der ObservableList in Ihrem Wrapper kompatibel. Sie müssen ein XmlAdapter schreiben, um es zu einer normalen Liste zu entwirren. Das Marshalling wird also funktionieren, aber das Unmarshalling nicht, wie Sie in der Zeile des Stacktrace sehen können:

%Vor%

Es gibt den Lister $ CollectionLister , der nicht weiß, was er mit der Unbekannten Quelle machen soll. Ein Adpater sollte einen ListWrapper wie folgt verwenden:

%Vor%

Der entsprechende Adapter sieht folgendermaßen aus:

%Vor%

Damit Ihr TaskListWrapper endlich so aussehen sollte:

%Vor%

Und übrigens, es gibt eine Menge von FX-Eigenschaften, die du verwendest, also solltest du deine Klasse Task mit @XmlAccessorType(XmlAccessType.PROPERTY) besser kommentieren und sicherstellen, dass für jedes Feld ein Getter / Setter existiert. Wie die FXProperties Konvention sagt:

%Vor%

Die Annotation @XmlAccessType(XmlAccessorType.PROPERTY) wird hier detailliert beschrieben: JAXB JavaDoc . Wenn in einem Paket oder einer Klasse nichts mit Anmerkungen versehen ist, lautet der Standardwert @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) , wobei JavaDoc Folgendes sagt:

  

Jedes öffentliche Getter / Setter-Paar und jedes öffentliche Feld wird es sein   wird automatisch an XML gebunden, sofern es nicht mit XmlTransient annotiert wird.

In einer FX-Klasse (einem speziellen Modell) versuchen Sie also, die verwendeten Eigenschaften in privaten Feldern auszublenden. Aber was, wenn Sie ein öffentliches Feld brauchen, das nicht gemarshallt werden sollte? Dann empfehle ich die Annotation @XmlAccessorType(XmlAccessType.PROPERTY) . Der JavaDoc davon sagt:

  

Jedes Getter / Setter-Paar in einer JAXB-gebundenen Klasse wird automatisch erstellt   gebunden an XML, sofern nicht mit XmlTransient annotiert.

Beobachten Sie den kleinen Unterschied in einem Wort public , wenn also mit @XmlAccessorType(XmlAccessType.PROPERTY) kommentiert wird, wird sogar der private Getter / Setter berücksichtigt.

Aber ich denke, die meisten Leute benutzen @XmlAccessorType(XmlAccessType.FIELD) , wo der JavaDoc sagt:

  

Jedes nicht statische, nicht transiente Feld in einer JAXB-gebundenen Klasse wird sein   wird automatisch an XML gebunden, sofern es nicht mit XmlTransient annotiert wird.

Dies kann in einer FX-Klasse mit FX-Eigenschaften etwas knifflig sein. Ich würde es dir nicht empfehlen.

    
NwDev 10.03.2015, 11:31
quelle