/** * @name Useless run() method in thread * @description Thread instances that neither get an argument of type 'Runnable' passed to their * constructor nor override the 'Thread.run' method are likely to have no effect. * @kind problem * @problem.severity warning * @precision low * @id java/empty-run-method-in-thread * @tags reliability * correctness * concurrency */ import java class ThreadClass extends Class { ThreadClass() { this.hasQualifiedName("java.lang", "Thread") } /** * Any constructor of `java.lang.Thread` _without_ a parameter of type `Runnable`; * these require overriding the `Thread.run()` method in order to do anything useful. */ Constructor getAConstructorWithoutRunnableParam() { result = this.getAConstructor() and ( result.getNumberOfParameters() = 0 or result.getNumberOfParameters() = 1 and result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "String") or result.getNumberOfParameters() = 2 and result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "ThreadGroup") and result.getParameter(1).getType().(RefType).hasQualifiedName("java.lang", "String") ) } /** * Any constructor of `java.lang.Thread` _with_ a parameter of type `Runnable`; * these ensure that the `Thread.run()` method calls the `Runnable.run()` method. */ Constructor getAConstructorWithRunnableParam() { result = this.getAConstructor() and not exists(Constructor c | c = result | result = this.getAConstructorWithoutRunnableParam()) } } from ClassInstanceExpr cie, ThreadClass thread, Class emptythread where emptythread.hasSupertype*(thread) and not exists(Class middle, Method run | run.hasName("run") and run.isPublic() and not run.isAbstract() and run.hasNoParameters() and middle.getAMethod() = run and middle.hasSupertype+(thread) and emptythread.hasSupertype*(middle) ) and not cie.getConstructor().callsConstructor*(thread.getAConstructorWithRunnableParam()) and cie.getType().(RefType).getSourceDeclaration() = emptythread select cie, "Thread " + emptythread.getName() + " has a useless empty run() inherited from java.lang.Thread."