- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
以下代码触发连接泄漏警告。我正在使用 OpenJDK 1.7.0_80 和 HikariCP 2.2.5(也可以使用最新的 HikariCP 2.3.9 重现)。我错过了什么吗?
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.Test;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class HikaryAutoCloseTest {
private static HikariDataSource configureDataSource() {
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://127.0.0.1/DATABASE");
config.setUsername("USERNAME");
config.setPassword("PASSWORD");
config.setLeakDetectionThreshold(10000);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("useServerPrepStmts", "true");
return new HikariDataSource(config);
}
@Test
public void testHikaryAutoClose() {
HikariDataSource dataSource = configureDataSource();
boolean ret = shouldNotLeakConnection(dataSource);
if (ret) {
System.out.println("UPDATE okey");
}
/* Wait for LeakTask to complain */
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("Exiting");
}
private boolean shouldNotLeakConnection(HikariDataSource dataSource) {
String sql = "INSERT INTO error_logs (description) values (?)";
try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql);) {
stmt.setString(1, "description");
return stmt.executeUpdate() != 0; // minor changes to this line remove the leak
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
更新:稍微更改返回语句可消除泄漏:
private boolean shouldNotLeakConnection(HikariDataSource dataSource) {
String sql = "INSERT INTO error_logs (description) values (?)";
try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql);) {
stmt.setString(1, "description");
boolean ret = stmt.executeUpdate() != 0;
return ret;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
最佳答案
问题似乎是由 AspectJ 1.7.2 中的错误引起的。它正在生成以下字节码:
private boolean shouldNotLeakConnection(com.zaxxer.hikari.HikariDataSource);
Code:
0: ldc #115 // String INSERT INTO error_logs (description) values (?)
2: astore_2
3: aconst_null
4: astore_3
5: aconst_null
6: astore 4
8: aload_1
9: invokevirtual #117 // Method com/zaxxer/hikari/HikariDataSource.getConnection:()Ljava/sql/Connection;
12: astore 5
14: aload 5
16: aload_2
17: invokeinterface #121, 2 // InterfaceMethod java/sql/Connection.prepareStatement:(Ljava/lang/String;)Ljava/sql/PreparedStatement;
22: astore 6
24: aload 6
26: iconst_1
27: ldc #127 // String description
29: invokeinterface #129, 3 // InterfaceMethod java/sql/PreparedStatement.setString:(ILjava/lang/String;)V
34: aload 6
36: invokeinterface #135, 1 // InterfaceMethod java/sql/PreparedStatement.executeUpdate:()I
41: ifeq 46
44: iconst_1
45: ireturn
46: iconst_0
47: aload 6
49: ifnull 59
52: aload 6
54: invokeinterface #139, 1 // InterfaceMethod java/sql/PreparedStatement.close:()V
59: aload 5
61: ifnull 71
64: aload 5
66: invokeinterface #142, 1 // InterfaceMethod java/sql/Connection.close:()V
71: ireturn
72: astore_3
73: aload 6
75: ifnull 85
78: aload 6
80: invokeinterface #139, 1 // InterfaceMethod java/sql/PreparedStatement.close:()V
85: aload_3
86: athrow
87: astore 4
89: aload_3
90: ifnonnull 99
93: aload 4
95: astore_3
96: goto 111
99: aload_3
100: aload 4
102: if_acmpeq 111
105: aload_3
106: aload 4
108: invokevirtual #143 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
111: aload 5
113: ifnull 123
116: aload 5
118: invokeinterface #142, 1 // InterfaceMethod java/sql/Connection.close:()V
123: aload_3
124: athrow
125: astore 4
127: aload_3
128: ifnonnull 137
131: aload 4
133: astore_3
134: goto 149
137: aload_3
138: aload 4
140: if_acmpeq 149
143: aload_3
144: aload 4
146: invokevirtual #143 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
149: aload_3
150: athrow
151: astore_3
152: new #25 // class java/lang/RuntimeException
155: dup
156: aload_3
157: invokespecial #27 // Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V
160: athrow
Exception table:
from to target type
24 47 72 any
71 72 72 any
14 59 87 any
71 87 87 any
8 125 125 any
3 71 151 Class java/sql/SQLException
72 151 151 Class java/sql/SQLException
注意第 45 行,ireturn
跳过了两个 close()
方法。
使用 AspectJ 1.8.6,生成了正确的字节码:
private boolean shouldNotLeakConnection(com.zaxxer.hikari.HikariDataSource);
Code:
0: ldc #115 // String INSERT INTO error_logs (description) values (?)
2: astore_2
3: aconst_null
4: astore_3
5: aconst_null
6: astore 4
8: aload_1
9: invokevirtual #117 // Method com/zaxxer/hikari/HikariDataSource.getConnection:()Ljava/sql/Connection;
12: astore 5
14: aload 5
16: aload_2
17: invokeinterface #121, 2 // InterfaceMethod java/sql/Connection.prepareStatement:(Ljava/lang/String;)Ljava/sql/PreparedStatement;
22: astore 6
24: aload 6
26: iconst_1
27: ldc #127 // String description
29: invokeinterface #129, 3 // InterfaceMethod java/sql/PreparedStatement.setString:(ILjava/lang/String;)V
34: aload 6
36: invokeinterface #135, 1 // InterfaceMethod java/sql/PreparedStatement.executeUpdate:()I
41: ifeq 48
44: iconst_1
45: goto 49
48: iconst_0
49: aload 6
51: ifnull 61
54: aload 6
56: invokeinterface #139, 1 // InterfaceMethod java/sql/PreparedStatement.close:()V
61: aload 5
63: ifnull 73
66: aload 5
68: invokeinterface #142, 1 // InterfaceMethod java/sql/Connection.close:()V
73: ireturn
74: astore_3
75: aload 6
77: ifnull 87
80: aload 6
82: invokeinterface #139, 1 // InterfaceMethod java/sql/PreparedStatement.close:()V
87: aload_3
88: athrow
89: astore 4
91: aload_3
92: ifnonnull 101
95: aload 4
97: astore_3
98: goto 113
101: aload_3
102: aload 4
104: if_acmpeq 113
107: aload_3
108: aload 4
110: invokevirtual #143 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
113: aload 5
115: ifnull 125
118: aload 5
120: invokeinterface #142, 1 // InterfaceMethod java/sql/Connection.close:()V
125: aload_3
126: athrow
127: astore 4
129: aload_3
130: ifnonnull 139
133: aload 4
135: astore_3
136: goto 151
139: aload_3
140: aload 4
142: if_acmpeq 151
145: aload_3
146: aload 4
148: invokevirtual #143 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
151: aload_3
152: athrow
153: astore_3
154: new #25 // class java/lang/RuntimeException
157: dup
158: aload_3
159: invokespecial #27 // Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V
162: athrow
Exception table:
from to target type
24 49 74 any
73 74 74 any
14 61 89 any
73 89 89 any
8 127 127 any
3 73 153 Class java/sql/SQLException
74 153 153 Class java/sql/SQLException
请注意,在第 45 行,ireturn
被替换为 goto
,它不会跳过两个 close()
方法。
感谢@brettw 帮助我缩小问题范围。
关于java - try-with-resources 和 HikariCP 的连接泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31562581/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!