jooq 3.13 资源泄漏

huangapple go评论74阅读模式
英文:

jooq 3.13 resource leak

问题

我检查了我的Java代码,Coverity分析发现了这个资源泄漏错误。

@Before
public void init() {

(1) Event alloc_fn: 从分配方法deleteFrom返回新资源(虚拟调用解析为org.jooq.impl.DefaultDSLContext.deleteFrom”。)
(2) Event leaked_resource: 未能保存或关闭由dslContext.deleteFrom(com.nurego.bizops.metering.common.jooq.nongen.tables.MyTable.MYTABLE)创建的资源泄漏

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

`dslContext.close()` 已经在 predestroy 方法中使用

我应该像这样做吗

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

还是有更好的解决方案?

英文:

I checked my java code and coverity analysis found this resource leak error.

@Before
public void init() {

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

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

dslContext.close() is already used in predestroy method.

Should I do smth like this?

DeleteUsingStep&lt;MyTableRecord&gt; step = dslContext.deleteFrom(MyTable.MYTABLE);
step.execute();
step.close();

Or is there a better solution?

答案1

得分: 1

直到 jOOQ 3.13

在 Java 7 和 8 之间,关于 AutoCloseable 的契约发生了微小的变化,请参阅 Javadoc:

Java 7 版本

> 在不再需要时必须关闭的资源。

注意其中的 "必须" 一词。

Java 8 版本

> 一个对象可以持有资源(如文件或套接字句柄),直到被关闭。当退出 try-with-resources 块时,会自动调用 AutoCloseable 对象的 close() 方法,前提是该对象已在资源规范头中声明。这种结构确保及时释放,避免资源耗尽异常和可能会发生的错误。
>
> API 注释:
>
> 尽管并非其所有子类或实例都将持有可释放资源,但基类可能实现 AutoCloseable,这在实际情况中是可能且实际情况是常见的。对于必须在完全通用情况下操作的代码,或者当知道 AutoCloseable 实例需要资源释放时,建议使用 try-with-resources 结构。然而,在使用诸如 Stream 等既支持基于 I/O 和非基于 I/O 形式的功能时,在使用非 I/O 形式时,通常不需要使用 try-with-resources 块。

这可能是为了允许 Stream 在方便使用 try-with-resources 的情况下扩展 AutoCloseable,尽管几乎所有流都不是资源密集型的。

不幸的是,这使得大多数静态分析工具在自动可关闭性检测方面变得无用。它们可能已经为流硬编码了一个异常,但对于 DSLContext 则没有。

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

从 jOOQ 3.14 开始

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

英文:

Until jOOQ 3.13

There was a subtle change in contract between Java 7 and 8 regarding AutoCloseable, see the Javadoc:

Java 7 version

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

Note the word "must".

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.

This was done (probably) to allow for Stream to extend AutoCloseable for convenience of using streams with try-with-resources, despite the fact that almost all streams are not resourceful.

Unfortunately, this makes most static analysis tools useless when it comes to auto closeable detection. They might have hard-coded an exception for streams, but not for DSLContext.

You can safely ignore these errors when using jOOQ's DSLContext.

Starting with jOOQ 3.14

This has been a frequent issue for new jOOQ users, and could be considered an API design flaw. jOOQ 3.14 will remove the AutoCloseable type from the DSLContext super types and provide a dedicated CloseableDSLContext instead, which is returned only from relevant methods:
https://github.com/jOOQ/jOOQ/issues/10512

答案2

得分: 0

你可以尝试这样做:

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

可能的原因是 step 继承了 org.jooq.Query,而它是 AutoCloseable 的。

英文:

You might try this:

try( DeleteUsingStep&lt;MyTableRecord&gt; step = dslContext.deleteFrom(MyTable.MYTABLE)) {
    step.execute();
} 

The reason might be the step inherits org.jooq.Query which is AutoCloseable.

huangapple
  • 本文由 发表于 2020年8月20日 18:14:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63502922.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定