NullPointerException

Hallo zusammen,

ich wollte ein paar Buchung einpflegen (manuell) und erhalte plötzlich immer nachfolgende oder vergleichbare Exceptions:

Cannot invoke “java.time.LocalDateTime.compareTo(java.time.chrono.ChronoLocalDateTime)” because the return value of “name.abuchen.portfolio.model.Transaction.getDateTime()” is null

java.lang.NullPointerException: Cannot invoke “java.time.LocalDateTime.compareTo(java.time.chrono.ChronoLocalDateTime)” because the return value of “name.abuchen.portfolio.model.Transaction.getDateTime()” is null
at name.abuchen.portfolio.model.Transaction$ByDate.compare(Transaction.java:201)
at name.abuchen.portfolio.model.Transaction$ByDate.compare(Transaction.java:1)
at name.abuchen.portfolio.model.TransactionPair$ByDate.compare(TransactionPair.java:27)
at name.abuchen.portfolio.model.TransactionPair$ByDate.compare(TransactionPair.java:1)
at name.abuchen.portfolio.ui.util.viewers.ColumnViewerSorter$ViewerSorter.compare(ColumnViewerSorter.java:365)
at org.eclipse.jface.viewers.ViewerComparator.lambda$0(ViewerComparator.java:202)
at java.base/java.util.TimSort.binarySort(Unknown Source)
at java.base/java.util.TimSort.sort(Unknown Source)
at java.base/java.util.Arrays.sort(Unknown Source)
at org.eclipse.jface.viewers.ViewerComparator.sort(ViewerComparator.java:202)
at org.eclipse.jface.viewers.StructuredViewer.getSortedChildren(StructuredViewer.java:1031)
at org.eclipse.jface.viewers.ColumnViewer.getSortedChildren(ColumnViewer.java:821)
at org.eclipse.jface.viewers.AbstractTableViewer.internalVirtualRefreshAll(AbstractTableViewer.java:647)
at org.eclipse.jface.viewers.AbstractTableViewer.internalRefresh(AbstractTableViewer.java:622)
at org.eclipse.jface.viewers.AbstractTableViewer.internalRefresh(AbstractTableViewer.java:612)
at org.eclipse.jface.viewers.AbstractTableViewer.lambda$0(AbstractTableViewer.java:565)
at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1395)
at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1356)
at org.eclipse.jface.viewers.AbstractTableViewer.inputChanged(AbstractTableViewer.java:565)
at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:279)
at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1639)
at name.abuchen.portfolio.ui.views.TransactionsViewer.setInput(TransactionsViewer.java:218)
at name.abuchen.portfolio.ui.views.AllTransactionsView.notifyModelUpdated(AllTransactionsView.java:132)
at name.abuchen.portfolio.ui.views.AllTransactionsView.createBody(AllTransactionsView.java:223)
at name.abuchen.portfolio.ui.editor.AbstractFinanceView.createViewControl(AbstractFinanceView.java:178)
at name.abuchen.portfolio.ui.editor.PortfolioPart.createView(PortfolioPart.java:596)
at name.abuchen.portfolio.ui.editor.PortfolioPart.activateView(PortfolioPart.java:552)
at name.abuchen.portfolio.ui.editor.PortfolioPart.activateView(PortfolioPart.java:540)
at name.abuchen.portfolio.ui.editor.ClientEditorSidebar$1.select(ClientEditorSidebar.java:69)
at name.abuchen.portfolio.ui.editor.ClientEditorSidebar$1.select(ClientEditorSidebar.java:1)
at name.abuchen.portfolio.ui.editor.Sidebar$Entry.handleMouseDown(Sidebar.java:423)
at org.eclipse.swt.events.MouseListener$2.mouseDown(MouseListener.java:95)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4660)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1657)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1680)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1665)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1394)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4427)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4003)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1147)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1038)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:166)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
at org.eclipse.equinox.launcher.Main.run(Main.java:1415)

Ich habe es schon einmal mit der 0.82.0 probiert und selbst bei den Backupdateien kann ich jetzt das Problem ebenfalls sehen.

Gibt es eine Möglichkeit die Datei zu reparieren oder handelt es sich um einen Fehler der auf Programmseite korrigiert werden kann?
Sind weitere Informationen erforderlich?

Ich habe noch 2 weitere Dateien die problemlos funktionieren.

Vielen Dank und viele Grüße

Exceptions habe ich im Prinzip bei jeder Funktion, daher vermute ich das ein korrupter Satz die Ursache des Problems ist, kann man hier etwas machen und die Depotdatei (ZIP-File) irgendwie bearbeiten?

Die xml ja, die Binary nur in der Entwicklungsumgebung.

So lange die Datei aufgeht, kann man versuchen neu als xml zu speichern.

Der Export hat leider nichts gebracht, gibt es eine Option den Export nur bis zu einem bestimmten Datum zu erstellen oder Elemente auszublenden?
Ich vermute das nur ein paar Sätze defekt sind, die ich vermutlich heute im Laufe des Tages editiert habe, den bei ein/zwei Änderungen hatte ich bei der Erfassung auch schon eine Exception.

Wie meinst Du das? Der “Export” war ja nur ein Speichern unter einem anderen lesbaren Format. Von der xml eine Kopie machen und darin mittels eines Editors oder grep nach Fehlern suchen.

Ein korrekter Wert würde wohl so aussehen

<datetime>2023-10-27T15:34</datetime>

Ein Fehler wäre z.B.

<datetime></datetime>
1 Like

Wie sollte bzw. würde ein grep-Befehl für Fehler aussehen?
Stören bereits Elemente ohne Werte?

Ich frage weil die Datei ziemlich groß ist und beim einfachen durchscrollen ist mir nichts aufgefallen. Ich hatte versucht die exportierte Datei zu reparieren, nur wird mir nichts sinnvolles angezeigt, also kein Hinweis auf Wert, Zeile, etc.

Du wirst es an der Stelle schwer haben, den schuldigen Eintrag zu finden. Die beste Lösung wäre, die Stelle, die momentan “unkontrolliert” auf die Nase fällt, die Transaktion auf das Vorhandensein eines Datums prüfen zu lassen und wenn das fehlt, eine vernünftige Exception mit den Details zur fraglichen Transaktion zu werfen.

Ich habe das seinerzeit mal an vielen Stellen so eingebaut, aber das war nur an Stellen, an denen ich wegen etwas anderem unterwegs war. Alle möglichen Stellen ausfindig machen und anpassen wäre ein Job für jemanden, der Vater und Mutter ermordet hat.

Problem ist das speziell die Seiten mit der Vermögensübersicht, die Wertpapiere, etc. sofort eine Exception werden und ich dort nichts mehr machen kann. Ich hatte auch gedacht ich exportiere einfach alles bis vor einigen Tagen, nur kann ich das leider nicht auswählen.
Ich vermute das es ein Kurs ist, wie püfe ich nach einem Datum, denn die Datei ist einige MB aks NML-Datei groß.

Ohne da jetzt so tief einzusteigen, deutet die Meldung because the return value of “name.abuchen.portfolio.model.Transaction.getDateTime()” is null at name.abuchen.portfolio.model.Transaction$ByDate.compare(Transaction.java:201) darauf hin, dass hier bei einer Transaktion was nicht stimmt.

Ob die Ursache da jetzt wirklich ein fehlerhafter Wert in der Datei ist, oder noch ein Bug vorliegt durch den der Wert innerhalt der Logik einfach noch nicht gesetzt ist (=null), wäre wohl nur durch debugging und Nachstellen zu ermitteln.

Ganz konkret kommt es hier zu einer exception, weil diese Funktion null zurück gibt.

Wenn du auf die Suche in deiner Datei gehen möchtest:
Du könntest nach transaction suchen. Dann stößt du auf Einträge wie account-transaction und portfolio-transaction. Beide Typen müssten ein Feld <date>, besitzen (ähnlich, wie das schon @ProgFriese geschrieben hat). Wenn du kein Vorkommen von

<date></date>

in deiner Datei findest, kann es sein, dass die Ursache darin liegt, dass eine Transaktion gar kein <date>-Feld hat.
Also müsstest du quasi nach Einträgen suchen, die es nicht gibt.

Ich könnte mir vorstellen, dass eine KI dir möglicherweise ein Powershellscript erstellen kann, welches genau danach sucht.

1 Like

Wenn Du über die Dialog so eine Buchung erstellen konntest, dann ist das sicherlich ein Bug. Jede Buchung braucht ein Datum. Es wird nicht an allen Stellen noch mal geprüft, ob die Buchung wirklich ein Datum hat. Und dann kommt es zu solchen Fehlern.

Ich werde mal einen Check einbauen, der beim Start solchen Buchungen einfach das aktuelle Datum zuweist. Dann kann man die ggf. korrigieren.

I like @OnkelDok idea. I am no expert in powershelgl, but ChatGPT says something like this would look for these kind of transactions:

[xml]$xml = Get-Content "file.xml"

$nodes = $xml.SelectNodes("//account-transaction | //portfolio-transaction")

$result = foreach ($n in $nodes) {
    $dateNode = $n.SelectSingleNode("date")

    if (-not $dateNode -or [string]::IsNullOrWhiteSpace($dateNode.InnerText)) {
        $n
    }
}

$result
1 Like

Erstmal könnte man zählen, um zu prüfen ob jede Transaction ein Date hat.

grep -c "<account-transaction>" example.xml

sollte die Anzahl der account-transactions ausgeben, bzw.

grep -c "<portfolio-transaction>" example.xml

die Anzahl der portfolio-transactions.

Um zu prüfen, ob jede Transaction ein Date hat, kann man versuchen:

grep -A 2 "<account-transaction>" example.xml | grep -c "<date>"

Das “-A 2” bedeutet: Gib zwei auf den Match folgende Zeilen mit aus. Da sollte normalerweise ein Date dabei sein. Wenn hierbei die Anzahl der dates gleich der Anzahl der vorher gezählten account-transactions ist, müsste man noch auf den String zwischen "<date>" und "</date>" prüfen, ob der in eine time umzurechnen ist, z.B. mit awk, genaue Zeile weiß ich jetzt nicht.

2 Likes

Ich habe nochmal kurz in meine Datei geschaut:
Beim Zählen muss man aufpassen, denn es gibt auch reguläre Einträge, die kein <date>-Feld als Kind besitzen (aber auch keine anderen):

 <account-transaction reference="../account-transaction[15]/crossEntry/portfolio/transactions/portfolio-transaction[114]/crossEntry/accountTransaction"/>

Stimmt, die würden bei der Suche nach "<account-transaction>" aber auch nicht gezählt.

1 Like

Stimmt auch wieder. :+1:

Damit man das kann, sollte das Datum nicht mit gespeichert werden und der Vorgang in Form einer Fehlermeldung mit den Details zur Transaktion angezeigt werde. Nicht speichern deswegen, weil man so eine Meldung schon mal wegklicken kann und dann das falsche Datum dauerhaft im Datenbestand wäre, was vermutlich Berechnungen verfälscht.

3 Likes