我真的很长一段时间都在为这个例外而苦苦挣扎。
我有一个 java 程序(TG-Toolkit),其中我有类来管理用于代理和后端插件的常用内容。主要用途之一是数据库。我将 HikariCP 与 MariaDB 组合使用。一切正常,但有时(比如 30% 的重启)我会遇到这个异常。在那之后一切仍然正常,正如我所说,我只是有时会遇到这个例外。
MariaDB 版本 3.1.4 HikariCP 版本 5.0.1
我使用 try-with-resource 来处理连接和结果集
[12:05:27] [Server thread/INFO]: [Core] [STDOUT] BEFORE CLOSE
[12:05:27] [Server thread/WARN]: Nag author(s): '[Wega]' of 'Core' about their usage of System.out/err.print. Please use your plugin's logger instead (JavaPlugin#getLogger).
[12:05:27] [Server thread/WARN]: [Toolkit] HikariCP activity connections: 0
[12:05:27] [Server thread/INFO]: [com.zaxxer.hikari.HikariDataSource] HikariPool-1 - Shutdown initiated...
[12:05:27] [HikariPool-1 connection closer/WARN]: Exception in thread "HikariPool-1 connection closer" Exception in thread "HikariPool-1 connection closer" java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: Exception in thread "HikariPool-1 connection closer" Exception in thread "HikariPool-1 connection closer" java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: Exception in thread "HikariPool-1 connection closer" java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: Exception in thread "HikariPool-1 connection closer" Exception in thread "HikariPool-1 connection closer" java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:177)
[12:05:27] [HikariPool-1 connection closer/WARN]: at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:124)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: Exception in thread "HikariPool-1 connection closer" java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [Server thread/INFO]: [com.zaxxer.hikari.HikariDataSource] HikariPool-1 - Shutdown completed.
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[12:05:27] [HikariPool-1 connection closer/WARN]: java.lang.NoClassDefFoundError: org/mariadb/jdbc/message/client/QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.client.impl.StandardClient.close(StandardClient.java:1003)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//org.mariadb.jdbc.Connection.close(Connection.java:235)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:137)
[12:05:27] [HikariPool-1 connection closer/WARN]: at core-0.2-SNAPSHOT.jar//com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:444)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[12:05:27] [HikariPool-1 connection closer/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[12:05:27] [HikariPool-1 connection closer/WARN]: Caused by: java.lang.ClassNotFoundException: org.mariadb.jdbc.message.client.QuitPacket
[12:05:27] [HikariPool-1 connection closer/WARN]: ... 7 more
[code][12:05:27] [Server thread/INFO]: [Core] [STDOUT] AFTER CLOSE
这是我使用的代码:
package net.trustgames.toolkit.managers;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import net.trustgames.toolkit.Toolkit;
import org.jetbrains.annotations.NotNull;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
/**
* This class handles the basic MariaDB and HikariCP methods such as getting connection,
* creating the database, table (if not exists) and closing the hikari connection. Note that the
* plugin#getLogger is used instead of Bukkit#getLogger, because async methods should not access Bukkit API
*/
public final class HikariManager {
private static final Logger logger = Toolkit.getLogger();
private static HikariDataSource dataSource;
/**
* Sets parameters and creates new pool.
* (is run async)
*/
public HikariManager(@NotNull String user,
@NotNull String password,
@NotNull String ip,
@NotNull String port,
@NotNull String database,
@NotNull Integer poolSize) {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("org.mariadb.jdbc.Driver");
hikariConfig.setJdbcUrl("jdbc:mariadb://" + ip + ":" + port + "/" + database);
hikariConfig.addDataSourceProperty("user", user);
hikariConfig.addDataSourceProperty("password", password);
hikariConfig.setMaximumPoolSize(poolSize);
dataSource = new HikariDataSource(hikariConfig);
}
/**
* gets a new connection from the hikaricp pool
*/
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
System.out.println("RUNTIME EXCEPTION 1");
throw new RuntimeException("Getting a new connection from HikariCP", e);
}
}
/**
* @param callback When datasource is initialized
*/
public void onDataSourceInitialized(Runnable callback) {
CompletableFuture.runAsync(() -> {
if (dataSource != null) {
callback.run();
} else {
// if dataSource is null, schedule the callback to be run when it is initialized
try {
Thread.sleep(500L);
onDataSourceInitialized(callback);
} catch (InterruptedException e) {
System.out.println("RUNTIME EXCEPTION 10");
throw new RuntimeException(e);
}
}
}).orTimeout(10L, TimeUnit.SECONDS)
.exceptionally(throwable -> {
Toolkit.getLogger().severe("HikariCP data source initialization timed out!");
return null;
});
}
/**
* @return
* true - if datasource is initialized<p>
* false - if datasource is not initialized
*/
public boolean isDataSourceInitialized() {
return dataSource != null;
}
/**
* checks if the table exists, if it doesn't, it creates one using the given SQL statement
* (is run async)
*
* @param tableName The name of the table
* @param stringStatement The SQL statement in String
*/
public void initializeTable(@NotNull String tableName, @NotNull String stringStatement) {
CompletableFuture.runAsync(() -> {
try (Connection connection = getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(stringStatement)) {
statement.executeUpdate();
}
} catch (SQLException e) {
System.out.println("RUNTIME EXCEPTION 11");
throw new RuntimeException("Unable to create missing " + tableName + " table in the database!", e);
}
});
}
public void close() {
Toolkit.getLogger().warning("HikariCP activity connections: " + dataSource.getHikariPoolMXBean().getActiveConnections());
dataSource.close();
}
}
这就是我在 spigot 插件的 onDisable 方法中关闭池的方式。
public void closeConnections() {
if (hikariManager.isDataSourceInitialized())
hikariManager.close();
}
这里还有 github 上完整代码的链接。不应该与此相关,但如果有人想更深入地了解,请成为我的客人。 https://github.com/ThomasWega/TG-Toolkit/ https://github.com/ThomasWega/TG-Core/
我想当我关闭池时我可能仍然有一些打开的连接,所以我将它打印到控制台,但它显示在 spigot 服务器关闭时有 0 个活动连接,所以这应该不是问题。我也尝试过在相关方法中添加一些打印,但也没有运气。看起来真的像是关闭游泳池的原因,虽然我不明白为什么会这样。