2013-02-13 2 views
14

In Eclipse erhielt ich eine Warnung Resource leak: 'ps' is not closed at this location, die ich nicht verstehe.Ressource Leckwarnung in der Sonnenfinsternis

In meinem Java Code erkläre ich die "ps" als eine vorbereitete Anweisung und ich benutze (und schließe) es oft. Dann habe ich die folgende Sequenz:

try { 
    if(condition) { 
     ps = c.prepareStatement("UPDATE 1 ..."); 
    } else { 
     ps = c.prepareStatement("UPDATE 2 ..."); 
    } 
    ps.executeUpdate(); 
} catch (SQLException e) { 
    // exception handling 
} finally { 
    if (null != ps) 
     try { 
      ps.close(); 
     } catch (SQLException e) { 
      // exception handling 
     }; 
} 

Das „Ressource Leck“ -Warnung kommt auf dem „Update“ -Statement im anderen Abschnitt. Wenn ich ps = null setze, bevor ich den try Block starte, gibt es keine Warnung.

Wenn die zweite UPDATE-Anweisung auskommentiert ist, wird keine Warnung angezeigt.

Ist das ein Verständnis oder ein Java/Eclipse-Problem?

+1

Meine Vermutung ist, dass Eclipse erkennt, dass Sie das vorbereitete Anweisungsobjekt zuvor verwenden und aufgrund des Potenzials für die SQLException es möglicherweise nicht ordnungsgemäß schließen. Wenn Sie 'ps = null;' im finally-Block machen, wird es wahrscheinlich repariert und dies wäre ein vernünftigerer Ort, um es zu bereinigen. –

Antwort

3

Ich denke, es ist ein Problem mit dem Checker, den Sie verwenden.

Brechen Sie Ihren Code in initialization und use Blöcke. Werfen Sie außerdem eine Ausnahme aus dem Initialisierungsblock aus (oder führen Sie eine vorzeitige Rückkehr durch). Auf diese Weise gibt es keine Notwendigkeit für null zu überprüfen, wenn Sie die Ressource nach use Block Release

// initialization 
// Note that ps is declared final. 
// I think it will help to silence your checker 
final PreparedStatement ps; 

try { 
    if(bedingungen ...) { 
     ps = c.prepareStatement("UPDATE 1 ..."); 
    } else { 
     ps = c.prepareStatement("UPDATE 2 ..."); 
    } 
} 
catch (SQLException e) { 
    log.error("Problem creating prepared statement, e); 
    throw e; 
} 

// use 
try { 
    ps.executeUpdate(); 
} catch (SQLException e) { 
    log.error("Problem decrementing palets on " + srcElement.getName() + 
     ": " + e.getMessage()); 
} 
finally { 
    try { 
     ps.close(); 
    } catch (SQLException e) { 
     log.warn("Error closing PreparedStatement: " + e.getMessage()); 
    }; 
} 
+0

Ich werde es versuchen ... –

10

Wenn Sie diese Warnung haben Sie verwenden Java 7. In diesem Fall sollten Sie die Ressource nicht schließen, die AutoClosable selbst implementiert.

// decide which update statement you need: 
// (your if should be here) 
String update = ....; 
try (
    ps = c.prepareStatement(update); 
) { 
    // use prepared statement here. 
} catch (SQLException) { 
    // log your exception 
    throw new RuntimeException(e); 
} 
// no finally block is needed. The resource will be closed automatically. 

ich in der Tat weiß nicht, warum Anwesenheit von if/else Anweisung bewirkt, dass die Warnung zu erscheinen oder verschwinden: Sie sollten diese Ressourcen in speziellen Initialisierungsabschnitt von try statementcommented initialisieren. Aber Java 7 empfiehlt die Arbeit mit automatisch schließbaren Ressourcen, die ich oben beschrieben habe, also versuchen Sie es.

+0

Danke, das hat mir geholfen. Da ich noch nicht bereit bin, Java 7 vollständig zu übernehmen, habe ich Eclipse gerade gesagt, dass Ressourcenlecks ignoriert werden sollen. Wahrscheinlich gefährlich, aber wird jetzt funktionieren. – rjcarr

-4

Ändern Sie den Variablennamen von c in mC. Ich denke, es ist ein seltsamer Fehler bei der Verwendung von c als Variablenname. Danke Charlie