jooq 3.13资源泄漏

jooq 3.13 resource leak

我检查了我的 java 代码和覆盖率分析发现了这个资源泄漏错误。

@Before
public void init() {

(1) Event alloc_fn: A new resource is returned from allocation method "deleteFrom". (The virtual call resolves to "org.jooq.impl.DefaultDSLContext.deleteFrom".)
(2) Event leaked_resource:  Failing to save or close resource created by "dslContext.deleteFrom(com.nurego.bizops.metering.common.jooq.nongen.tables.MyTable.MYTABLE)" leaks it.

            dslContext.deleteFrom(MyTable.MYTABLE).execute();
}

dslContext.close() 已在预销毁方法中使用。

我应该这样做吗?

DeleteUsingStep<MyTableRecord> step = dslContext.deleteFrom(MyTable.MYTABLE);
step.execute();
step.close();

或者有更好的解决方案吗?

直到 jOOQ 3.13

There was a subtle change in contract between Java 7 and 8 regarding AutoCloseable,请参阅 Javadoc:

Java 7 version

A resource that must be closed when it is no longer needed.

注意“必须”这个词。

Java 8 version

An object that may hold resources (such as file or socket handles) until it is closed. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header. This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.

API Note:

It is possible, and in fact common, for a base class to implement AutoCloseable even though not all of its subclasses or instances will hold releasable resources. For code that must operate in complete generality, or when it is known that the AutoCloseable instance requires resource release, it is recommended to use try-with-resources constructions. However, when using facilities such as Stream that support both I/O-based and non-I/O-based forms, try-with-resources blocks are in general unnecessary when using non-I/O-based forms.

这样做(可能)是为了允许 Stream 扩展 AutoCloseable,以便于使用带有 try-with-resources 的流,尽管事实上几乎所有流都不是足智多谋的。

不幸的是,这使得大多数静态分析工具在自动关闭检测方面变得毫无用处。他们可能有 hard-coded 流的例外,但 DSLContext.

没有

使用 jOOQ 时,您可以安全地忽略这些错误 DSLContext

从 jOOQ 3.14 开始

对于新的 jOOQ 用户来说,这是一个常见的问题,可以被认为是一个 API 设计缺陷。 jOOQ 3.14 将从 DSLContext 超类型中删除 AutoCloseable 类型,并提供专用的 CloseableDSLContext 代替,它仅从相关方法返回: https://github.com/jOOQ/jOOQ/issues/10512

你可以试试这个:

try( DeleteUsingStep<MyTableRecord> step = dslContext.deleteFrom(MyTable.MYTABLE)) {
    step.execute();
} 

原因可能是 step 继承了 org.jooq.QueryAutoCloseable