...
Code Block | ||
---|---|---|
| ||
public final class Client { public void doSomething(File file) { private final Lock lock = new ReentrantLock(); public void doSomething(File file) { InputStream in = null; try { lock.lock( in = new FileInputStream(file); in = new FileInputStream(filelock.lock(); // Perform operations on the open file lock.unlock(); } catch (FileNotFoundException x) { // Handle exception } finally { if (in != null) { try { in.close(); } catch (IOException x) { // Handle exception } } } } } |
...
Code Block | ||
---|---|---|
| ||
public final class Client { public void doSomething(File file) { private final Lock lock = new ReentrantLock(); public void doSomething(File file) { InputStream in = null; try { in = new FileInputStream(file); lock.lock(); // Perform operations on the open file } catch (FileNotFoundException fnf) { // Forward to handler } finally { lock.unlock(); if (in != null) { try { in.close(); } catch (IOException e) { // Forward to handler } } } } } |
...
Code Block | ||
---|---|---|
| ||
public final class Client { public void doSomething(File file) { private final Lock lock = new ReentrantLock(); public void doSomething(File file) { InputStream in = null; lock.lock(); try { in = new FileInputStream(file); // Perform operations on the open file } catch (FileNotFoundException fnf) { // Forward to handler } finally { lock.unlock(); if (in != null) { try { in.close(); } catch (IOException e) { // Forward to handler } } } } } |
...
Code Block | ||
---|---|---|
| ||
public interface LockAction { void doSomethingWithFile(InputStream in); } public final class ReentrantLockAction { private static final Lock lock = new ReentrantLock(); public static void doSomething(File file, LockAction action) { Lock lock = new ReentrantLock(); InputStream in = null; lock.lock(); try { in = new FileInputStream(file); action.doSomethingWithFile(in); } catch (FileNotFoundException fnf) { // Forward to handler } finally { lock.unlock(); if (in != null) { try { in.close(); } catch (IOException e) { // Forward to handler } } } } } public final class Client { public void doSomething(File file) { ReentrantLockAction.doSomething(file, new LockAction() { public void doSomethingWithFile(InputStream in) { // Perform operations on the open file } }); } } |
...
Code Block | ||
---|---|---|
| ||
final class DateHandler {
private final Date date = new Date();
private final Lock lock = new ReentrantLock();
// str could be null
public void doSomething(String str) {
lock.lock();
String dateString = date.toString();
if (str.equals(dateString)) {
// ...
}
// ...
lock.unlock();
}
}
|
...
Code Block | ||
---|---|---|
| ||
final class DateHandler {
private final Date date = new Date();
private final Lock lock = new ReentrantLock();
// str could be null
public void doSomething(String str) {
lock.lock();
try {
String dateString = date.toString();
if (str != null && str.equals(dateString)) {
// ...
}
// ...
} finally {
lock.unlock();
}
}
}
|
...
Failure to release locks on exceptional conditions could lead to thread starvation and deadlock.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
LCK08-J | Low | Likely | Low | P9 | L2 |
Automated Detection
Some static analysis tools are capable of detecting violations of this rule.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.LCK08.RLF CERT.LCK08.LOCK | Release Locks in a "finally" block Do not abandon unreleased locks | ||||||
ThreadSafe |
| CCE_LK_UNRELEASED_ON_EXN | Implemented |
Related Vulnerabilities
The GERONIMO-2234 issue report describes a vulnerability in the Geronimo application server. If the user single-clicks the keystore portlet, the user will lock the default keystore without warning. This causes a crash and stack trace to be produced. Furthermore, the server cannot be restarted because the lock is never cleared.
Related Guidelines
Bibliography
...
...