英文:
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 "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()
is already used in predestroy method.
Should I do smth like this?
DeleteUsingStep<MyTableRecord> 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:
> 在不再需要时必须关闭的资源。
注意其中的 "必须" 一词。
> 一个对象可以持有资源(如文件或套接字句柄),直到被关闭。当退出 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:
> A resource that must be closed when it is no longer needed.
Note the word "must".
> 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<MyTableRecord> step = dslContext.deleteFrom(MyTable.MYTABLE)) {
step.execute();
}
The reason might be the step
inherits org.jooq.Query
which is AutoCloseable
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论