Finalizer inconsistency¶
ID: java/missing-super-finalizeKind: problemSecurity severity: Severity: errorPrecision: mediumTags: - quality - reliability - correctness - external/cwe/cwe-568Query suites: - java-security-and-quality.qls
Click to see the query in the CodeQL repository
Afinalize method that overrides the finalizer of a superclass but does not callsuper.finalize may leave system resources undisposed of or cause other cleanup actions to be left undone.
Recommendation¶
Make sure that allfinalize methods callsuper.finalize to ensure that the finalizer of its superclass is executed. Finalizer chaining is not automatic in Java.
It is also possible to defend against subclasses that do not callsuper.finalize by putting the cleanup code into afinalizer guardian instead of thefinalize method. A finalizer guardian is an anonymous object instance that contains the cleanup code for the enclosing object in itsfinalize method. The only reference to the finalizer guardian is stored in a private field of the enclosing instance, which means that both the guardian and the enclosing instance can be finalized at the same time. This way, a subclass cannot block the execution of the cleanup code by not callingsuper.finalize.
Example¶
In the following example,WrongCache.finalize does not callsuper.finalize, which means that native resources are not disposed of. However,RightCache.finalizedoes callsuper.finalize, which means that native resourcesare disposed of.
classLocalCache{privateCollection<NativeResource>localResources;//...protectedvoidfinalize()throwsThrowable{for(NativeResourcer:localResources){r.dispose();}};}classWrongCacheextendsLocalCache{//...@Overrideprotectedvoidfinalize()throwsThrowable{// BAD: Empty 'finalize', which does not call 'super.finalize'.// Native resources in LocalCache are not disposed of.}}classRightCacheextendsLocalCache{//...@Overrideprotectedvoidfinalize()throwsThrowable{// GOOD: 'finalize' calls 'super.finalize'.// Native resources in LocalCache are disposed of.super.finalize();}}
The following example shows a finalizer guardian.
classGuardedLocalCache{privateCollection<NativeResource>localResources;// A finalizer guardian, which performs the finalize actions for 'GuardedLocalCache'// even if a subclass does not call 'super.finalize' in its 'finalize' methodprivateObjectfinalizerGuardian=newObject(){protectedvoidfinalize()throwsThrowable{for(NativeResourcer:localResources){r.dispose();}};};}
References¶
Java API Specification:Object.finalize().
J. Bloch,Effective Java (second edition), Item 7. Addison-Wesley, 2008.
Common Weakness Enumeration:CWE-568.