SonarLint: Resources should be closed bei Stream<T>?

KonradN

Super-Moderator
Mitarbeiter
Da Sonarcube in einem anderen Thread aufgetaucht ist, habe ich jetzt einfach einmal paar Tests damit gemacht und u.a. SonarLint in IntelliJ als PlugIn hinzu gefügt.

Nun werden aber einfache Streams angemeckert. Hintergrund ist, dass Stream<T> Autoclosable implementiert und ich da kein try-with-resource habe ...

Also z.B. einfach etwas wie:
Java:
            Files.lines(Paths.get(...))
                    .map(...)
                    .filter(...)
                    .forEach(...);

Mal paar Details mit ... vereinfacht - denn das tut ja nichts zur Sache. Ist halt ein typischer Stream - er wird geöffnet, es wird damit etwas gemacht (filter, map, ...) um dann am Ende damit etwas zu machen (forEach, collect, ...)

Da ist - ganz klar - kein try with resource drin. Und das macht doch auch wenig Sinn.

Und interessant ist: Diese Regel nimmt einige Klassen aus, wenn man https://rules.sonarsource.com/java/RSPEC-2095/ anschaut.... Aber diese funktionalen Aufrufe sind doch ok.

Erwarte ich hier einfach zu viel? Bei anderen statischen codeanalysetools musste ich ja auch "Law of demeter" oder so deaktivieren, weil das sonst diese Dinge anmeckerte....
 

httpdigest

Top Contributor
Ich denke, dass das hier an dem Files.lines() liegt, was laut Dokumentation einen File Handle offen hält, bis man den Stream explizit/manuell close()d.
The returned stream contains a reference to an open file. The file is closed by closing the stream.
Also mit anderen Worten: den Files.lines() Stream muss man schließen, ansonsten hat man vermutlich einen File Handle Leak (bis evtl. der Garbage Collector den Stream irgendwann schließt).
 

KonradN

Super-Moderator
Mitarbeiter
Oh, da in dem Link zu der Doku steht es sogar ganz explizit:
API Note:This method must be used within a try-with-resources statement or similar control structure to ensure that the stream's open file is closed promptly after the stream's operations have completed.
Das war mir so die ganze Zeit irgendwie total entgangen.

Vielen Dank für den schnellen und guten Hinweis.
 

httpdigest

Top Contributor
Meine Momenten mit SonarQube waren immer:
"Was?! Das soll ein Fehler/Problem sein? No way... da ist bestimmt was in SonarQube nicht richtig eingestellt oder die erkennen das nicht richtig."
Am Ende war das Erkannte immer richtig und ich zu dumm. :D

Also: SonarQube kann ich auch nur zu 100% empfehlen.
 

KonradN

Super-Moderator
Mitarbeiter
Evtl. an der Stelle noch der kurze Hinweis:
Ich habe jetzt direkt andere Stream<T> Stellen geprüft und die wurden alle nicht angemeckert.

Das nur, falls sich das sonst noch Jemand fragen sollte. Bei meinen ersten Tests (jetzt so ca. 3 Stunden mal geprüft) waren die Regeln sehr akkurat und gut. Da war fast nichts, das ein manuelles Eingreifen notwendig machte. Ich war hier an einem kleinen Tool, das auf der Konsole lief und da habe ich lediglich eine Regel, die Ausgaben auf der Konsole anmeckerte, deaktiviert.

Aber ich muss da noch deutlich mehr Zeit investieren um das auch mit den Meldungen von PMD und SpotBugs vergleichen um zu sehen, was es da ggf. für Unterschiede gibt. Ebenso die Unterschiede bei den Reports (Bisher habe ich nur SonarLint getestet, SonarCube hatte ich noch keine Zeit für) wobei SonarCube da nicht schlechter sein kann wie unformatierte XML Dateien, die ich mir in IntelliJ ansehe (nach einer Formatierung).

Und ggf. für die etwas unerfahrenen Java Entwickler, die try-with-resources noch nicht kennen. Das würde dann einfach auf so einen Code hinaus laufen:
Java:
try (Stream<String> stream = Files.lines(Paths.get(...)) ) {
    stream.map(...)
        .filter(...)
        .forEach(...);
} catch (IOException ex) {
    ...
}
Ich habe jetzt auch das catch dazu genommen - das einfach nur um zu verdeutlichen: Die IOException muss man ja behandeln und wenn man das direkt macht, dann wird das nicht wirklich sehr viel mehr Code. Also Anzahl Zeilen bleibt sogar gleich nur die Variable kommt dazu und es wandert halt das Files.lines in die Zeile vom try.

Und etwas refactoring - die try Zeile kann man etwas leserlicher machen z.B. durch eine Methode ... Ich mag diese verschachtelung in einer Zeile nicht wirklich ...
 

KonradN

Super-Moderator
Mitarbeiter
Also: SonarQube kann ich auch nur zu 100% empfehlen.
Ja, darauf läuft es im Augenblick bei mir auch hinaus. Aber es fehlen noch etwas mehr Ergebnisse.

Wenn ich daran denke, wie gut es sich in der IDE integriert und so. Das ist schon überzeugend. Wenn ich da an die Erfahrungen mit PMD und SpotBugs denke, dann ist das ein Unterschied wie Tag und Nacht.
 

Ähnliche Java Themen


Oben