NullPointerException-Handling bei API-Nutzung

Tarnschaf86

Grünschnabel
Hallo!

Ich dachte, dass ich mein Problem mit der Durchsuchung des Forums oder wenigstens Google lösen könnte, aber leider hatte ich dabei keinen Erfolg, weswegen ich jetzt so mein Glück versuche.

Meine Aufgabe ist folgende:

Ich benutze eine Server-API, um von diesem per Java-Programm IP-Adressen auszulesen. Dabei wird sich erst mit dem Server verbunden, dessen Objektstruktur dann von oben über IP-CIDR-Blöcke über IP-Netzwerke bis nach unten zu den IP Adressen durchlaufen wird. Dazu werden jeweils die Kinder der jeweiligen Objekte abgefragt und darauf die Methoden erneut aufgerufen.

Mein Problem ist nun:

Wenn ein Objekt keine Kinder hat, liefert die vordefinierte API-Methode, die ich benutze (benutzen muss) eine NullPointerException. Diese fange ich momentan mit try / catch ab, wobei der catch Block gar nichts tut. Mir ist "egal" wenn ein einzelnes Objekt keine Kinder hat (was per Design einfach sein kann) und möchte mit dem nächsten Objekt einfach weiter machen.
Das funktioniert auch - die Prüfung jedes einzelnes meiner sehr vielen Objekte per try / catch ruft allerdings natürlich eine äußerst schlechte Performance hervor.

Daher meine Frage:

Kann ich das irgendwie "eleganter" und damit mit besserer Performance meines Programms lösen?

Gruß Julian
 
Hallo und erst mal Herzlich Willkommen hier bei tutorials.de :)

Wenn eine Exception geworfen wird, dann musst du diese auch behandeln, da führt kein Weg daran vorbei. Ich würde es allerdings eleganter finden (und auch Performance-mäßig wäre es beeser) wenn an statt der NullPointerException einfach ein "null" zurückgegeben wird. Da aber die API vorgegeben ist, kann man so etwas ja nicht ändern.

Ich würde eher nach Möglichkeiten suchen, die Exception zu vermeiden. Das heißt, du versuchst irgendwie rauszufinden, ob der Knoten überhaupt Kinder hat. Entweder die API hat so eine Methode, oder du schaust wie du es sonst rausfinden kannst.

Ausserdem könntest du die Daten vom Server auch cachen und mit den lokal gecachten Daten arbeiten. Einfach vom Server holen und im Hintergrund schonmal durchlaufen lassen, ohne dass der Benutzer was mitkriegt. Hier kannst du dir dann selbst merken welcher Knoten wieviele Kinder hat und bei dem vom Benutzer angestoßenen Durchlauf dann auf diese Daten zurückgreifen. Dies sollte einen enormen Performancegewinn bringen.

Gruß
BK
 
Ich glaube, ich muss das Procedere während des Programms noch ein bisschen ausführlicher erklären, da die Antwort von Bratkartoffel (vielen Dank dafür!) leider nicht besonders hilfreich ist.

Ich fange mit einer übergeordneten Struktur, die ich angebe an, lasse mir dessen Kinder (IPBlöcke) mit einer API-Methode ("1" genannt), die die interne Datenbank des Servers aufruft, auslesen: diese Einträge werden in einem Array gespeichert. Mit einer weiteren API-Methode ("2"), die auch die Datenbank des Servers ausliest, kann ich mir über diese Einträge deren eindeutigen (long) Objekt-ID's ausgeben lassen, auf die ich wiederum 1 aufrufen kann. Wenn ein bestimmtes Objekt weitere Kinder hat, werden dann diese ausgelesen, darauf kann ich dann wieder 2, dann 1, dann 2 usw. aufrufen, bis ich irgendwann in der Hierarchie ganz unten bei den IPAdressen angelangt bin. So weit, so gut!
Wenn ein Objekt keine Kinder hat, kommt bei Aufruf von 1 auf die eindeutige ID die NullPointerException.

Probleme:
Ich bin ziemlich sicher, dass ich die API-Methoden nicht ändern kann.
Es gibt keine Methode, die prüft, ob ein Objekt überhaupt Kinder hat.
Ich weiß vor dem Aufruf von 1 also nicht, welche Objekte das betrifft.
Auch mit Ansatz des Cachens kann ich leider nicht so viel anfangen, da ich, auch wenn es irgendwo zwischengespeichert wird, irgendwann 1 aufrufen muss. Dadurch gewinne ich nichts, oder?

...Wie kann ich mein Exception-Handling trotzdem etwas optimieren?

Gruß Julian
 
Hallo,

also eine NullPointerException ist eine Unchecked Exception, die man eigentlich nicht zur Laufzeit abfangen sollte. Die Behandlung erfolgt vor dem Kompilieren, also durch eine Code-Korrektur des Programmierers.

Ich würde eine NullPointerException bzw. alle anderen Exceptions die von RuntimeException ableiten eher als Unterstützung für Tests und Debugging betrachten, es sind aber keine Fehler, die im Code zur Laufzeit behandelt werden können.

Kannst du denn prüfen, ob ein Objekt keine Kinder hat bzw. Kinder hat, die null sind. Falls die prüfung auf null positiv ist, könntest du das entsprechende Objekt ignorieren.

Gruß

Tikonteroga
 
Hallo, guten Morgen! :)

Interessanter Artikel, vielen Dank dafür! Da ich aber bei jedem Durchlauf (momentan), Tendenz steigend, ca. 3k Objekte abrufe, ist die Performance meiner Einschätzung nach doch relevant. Die Serververbindung wird nur einmalig aufgebaut und besteht dann für die ganze Session und das bisschen String-Manipulation und später die Ausgabe fallen da nicht mehr so sehr ins Gewicht. Und jetzt braucht die Applikation schon rund 25 Minuten....

Leider bleibt mir vorab eigentlich keine Möglichkeit auf null zu testen, da bloß diese eine Methode zu diesem Zweck zur Verfügung steht, die sich dazu zwangsläufig in der Server-DB austobt. Ich habe anfangs gedacht, man könnte vielleicht auch aus der DB-ID's der Objekte irgendwas ablesen, aber meine Versuche dazu (mit HEX-Editor) haben auch nichts ergeben. Das sind offenbar wirklich nur eindeutige Positionsbestimmungen.

Sonst keine Vorschläge? :(
Ich dachte an sowas wie, dass ich ne Klasse habe, die bewirkt, dass die NPE nicht für jedes einzelne Objekt abgefangen wird (bzw. daraufhin gesprüft wird), sondern das der Methode bloß "simuliert" und der Code ohne Error-Handling fortgesetzt wird. Geht so was? Die Exception einfach zu ignorieren? Oder kann ich vielleicht wenigstens irgendwas halbwegs sinnvolles in den catch Block schreiben...?
So finde ich meinen Code gerade einfach nicht "schön", obwohl er einwandfrei funktioniert! ;)
 
Hallo,

wenn du nicht über öffentliche API checken kannst ob der Aufruf ohne NPE durchgeführt werden kann könnte man sich noch im Debugger die interne Objektstruktur analysiseren. Vielleicht findet man ja da ne möglichkeit per Reflection den inneren Zustand auf Konsistenz zu prüfen... auf jeden Fall ist das ein Hack und ein riesen Bug / Flaw in der API die du verwendest.

Gruß Tom
 
Keine schlechte Idee, das probier ich gleich mal, ob ch da dran komme! Vielleicht findet sich so ja eine Ansatzstelle!

Dass diese API nicht ideal programmiert ist und eigentlich zu gar nichts effektiv zu gebrauchen ist, ist mir auch schon aufgefallen. Da ich auch noch nen "richtigen" Bug gefunden habe, der mich tagelang zur Verzweiflung gebracht hat, bevor ich ihn indentifizieren konnte, stehe ich schon seit Wochen mit dem "Support" in Kanada in Kontakt.
 
Es gibt offenbar wirklich keine Möglichkeit das zu vermeiden!
Habe mich mit meinem Auftraggeber jetzt darauf verständigt, dass das Programm nur ein Mal pro Nacht ausgeführt wird, dann spielt die Performance keine so große Rolle mehr.
Und für alle, die die Suchfunktion nutzen: Ich arbeite am BlueCat "Proteus" IPAM Server.


Noch eine kleine Frage:
Ich habe eigentlich 2 von den Geräten, die ausgelesen werden sollen. Die eine ist das Backup für die andere. Wie kann ich erreichen, dass man Programm für diese ausgeführt wird, wenn die erste tatsächlich nicht erreicht werden kann? Ich muss dazu eigentlich nur manuell die in der Methode angegebene IP Adresse ändern. Aber wie kann ich diesen Vorgang automatisiert durchführen (und zwar nicht dauerhaft natürlich)? Ich merke, dass der jeweilige Server nicht erreichbar ist, indem die API-Connect-Methode, mal wieder, eine NPE liefert.
Vielleicht eine Art Verschachtelung meiner NPE-Handler? Geht sowas?
 
Hallo,

ich würde eine Liste mit den IP-Adressen der Server anlegen und diese dann durchlaufen. Sobald eine erfolgreich verarbeitet wurde kannst du ja mit einem break aus der Schleife springen.

Gruß
BK
 
Zurück