Skip to content

Commit de09122

Browse files
authored
Merge pull request #19175 from jcogs33/jcogs33/java/call-to-thread-run
Java: update `java/call-to-thread-run`
2 parents 15aa0bb + 4290411 commit de09122

File tree

5 files changed

+111
-19
lines changed

5 files changed

+111
-19
lines changed

java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.qhelp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ continue while the child thread is waiting, so that "Main thread activity" is pr
4949
<li>
5050
The Java Tutorials: <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html">Defining and Starting a Thread</a>.
5151
</li>
52+
<li>
53+
SEI CERT Oracle Coding Standard for Java: <a href="https://wiki.sei.cmu.edu/confluence/display/java/THI00-J.+Do+not+invoke+Thread.run()">THI00-J. Do not invoke Thread.run()</a>.
54+
</li>
55+
<li>
56+
Java API Specification: <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Thread.html">Thread</a>.
57+
</li>
58+
<li>
59+
Java API Specification: <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Runnable.html">Runnable</a>.
60+
</li>
5261

5362

5463
</references>

java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* @problem.severity recommendation
77
* @precision high
88
* @id java/call-to-thread-run
9+
* @previous-id java/run-method-called-on-java-lang-thread-directly
910
* @tags quality
1011
* reliability
1112
* concurrency
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
| CallsToRunnableRun.java:15:3:15:15 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
1+
| CallsToRunnableRun.java:67:5:67:16 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
2+
| CallsToRunnableRun.java:71:5:71:24 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
3+
| CallsToRunnableRun.java:75:5:75:24 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
4+
| CallsToRunnableRun.java:79:5:79:27 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
5+
| CallsToRunnableRun.java:83:5:83:27 | run(...) | Calling 'Thread.run()' rather than 'Thread.start()' will not spawn a new thread. |
Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,95 @@
1-
import java.lang.Runnable;
2-
3-
public class CallsToRunnableRun extends Thread implements Runnable{
4-
5-
private Thread wrapped;
6-
private Runnable callback;
7-
8-
@Override
9-
public void run() {
10-
wrapped.run();
11-
callback.run();
12-
}
13-
14-
public void bad() {
15-
wrapped.run();
16-
callback.run();
17-
}
1+
class Job implements Runnable {
2+
public void run() {
3+
/* ... */
4+
}
5+
}
6+
7+
/**
8+
* A class that subclasses `java.lang.Thread` and inherits its `.run()` method.
9+
*/
10+
class AnotherThread1 extends Thread {
11+
AnotherThread1(Runnable runnable) {
12+
super(runnable);
13+
}
14+
}
15+
16+
/**
17+
* A class that directly subclasses `java.lang.Thread` and overrides its
18+
* `.run()` method.
19+
*/
20+
class AnotherThread2 extends Thread {
21+
AnotherThread2(Runnable runnable) {
22+
super(runnable);
23+
}
24+
25+
/**
26+
* An overriding definition of `Thread.run`.
27+
*/
28+
@Override
29+
public void run() {
30+
super.run(); // COMPLIANT: called within a `run` method
31+
}
32+
}
33+
34+
/**
35+
* A class that indirectly subclasses `java.lang.Thread` by subclassing
36+
* `AnotherThread1` and inherits its `.run()`
37+
* method.
38+
*/
39+
class YetAnotherThread1 extends AnotherThread1 {
40+
YetAnotherThread1(Runnable runnable) {
41+
super(runnable);
42+
}
43+
}
44+
45+
/**
46+
* A class that indirectly subclasses `java.lang.Thread` by subclassing
47+
* `AnotherThread2` and overrides its `.run()`
48+
* method.
49+
*/
50+
class YetAnotherThread2 extends AnotherThread2 {
51+
YetAnotherThread2(Runnable runnable) {
52+
super(runnable);
53+
}
54+
55+
/**
56+
* An overriding definition of `AnotherThread.run`.
57+
*/
58+
@Override
59+
public void run() {
60+
super.run(); // COMPLIANT: called within a `run` method
61+
}
62+
}
63+
64+
class ThreadExample {
65+
public void f() {
66+
Thread thread = new Thread(new Job());
67+
thread.run(); // $ Alert - `Thread.run()` called directly.
68+
thread.start(); // COMPLIANT: Thread started with `.start()`.
69+
70+
AnotherThread1 anotherThread1 = new AnotherThread1(new Job());
71+
anotherThread1.run(); // $ Alert - Inherited `Thread.run()` called on its instance.
72+
anotherThread1.start(); // COMPLIANT: Inherited `Thread.start()` used to start the thread.
73+
74+
AnotherThread2 anotherThread2 = new AnotherThread2(new Job());
75+
anotherThread2.run(); // $ Alert - Overriden `Thread.run()` called on its instance.
76+
anotherThread2.start(); // COMPLIANT: Overriden `Thread.start()` used to start the thread.
77+
78+
YetAnotherThread1 yetAnotherThread1 = new YetAnotherThread1(new Job());
79+
yetAnotherThread1.run(); // $ Alert - Inherited `AnotherThread1.run()` called on its instance.
80+
yetAnotherThread1.start(); // COMPLIANT: Inherited `AnotherThread.start()` used to start the thread.
81+
82+
YetAnotherThread2 yetAnotherThread2 = new YetAnotherThread2(new Job());
83+
yetAnotherThread2.run(); // $ Alert - Overriden `AnotherThread2.run()` called on its instance.
84+
yetAnotherThread2.start(); // COMPLIANT: Overriden `AnotherThread2.start()` used to start the thread.
85+
86+
Runnable runnable = new Runnable() {
87+
public void run() {
88+
/* ... */ }
89+
};
90+
runnable.run(); // COMPLIANT: called on `Runnable` object.
91+
92+
Job job = new Job();
93+
job.run(); // COMPLIANT: called on `Runnable` object.
94+
}
1895
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Likely Bugs/Concurrency/CallsToRunnableRun.ql
1+
query: Likely Bugs/Concurrency/CallsToRunnableRun.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql

0 commit comments

Comments
 (0)