gpt4 book ai didi

java - 无法删除嵌入式数据库的 Derby 系统目录

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:48:35 25 4
gpt4 key购买 nike

我无法删除 system directory在为 Windows 计算机上的 Derby Embedded 数据库调用 shutdown=true 时。

这是我的挑战的一个最小示例:

package derbytest;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author aelder
*/
public class DerbyTest {

private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
private static final String CONN_URL = "jdbc:derby:EmbeddedDBAudit";

private static File derbySystemFolder;
private static final String USER_HOME_DIR = System.getProperty("user.home", ".");

public static Connection getConnection(boolean createDatabase) throws SQLException {
return DriverManager.getConnection(CONN_URL + (createDatabase ? ";create=true" : ""));
}

public static void shutdownConnectionAndCleanup() {
try {
DriverManager.getConnection(CONN_URL + ";shutdown=true");
} catch (SQLException ex) {
if (!ex.getSQLState().equals("08006")) {
ex.printStackTrace();
}
}

deleteFolder(derbySystemFolder);
}

public static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) { //some JVMs return null for empty dirs
for (File f : files) {
if (f.isDirectory()) {
deleteFolder(f);
} else {
f.delete();
}
}
}
folder.delete();
}

public static void setDerbyHome() {
setDatabaseFile("");

int index = 1;
while (derbySystemFolder.exists()) {
setDatabaseFile(String.valueOf(index++));
}

// Set the db system directory.
System.setProperty("derby.system.home", derbySystemFolder.getAbsolutePath());
}

private static void setDatabaseFile(String auditFolderCount) {
String databaseFilePATH = USER_HOME_DIR + File.separator + ".EmbeddedDBAudit" + auditFolderCount;

derbySystemFolder = new File(databaseFilePATH);
derbySystemFolder.deleteOnExit();
}

public static void initDerbyHomeAndDriver() {
setDerbyHome();

initDerbyDriverInstance();
}

public static void initDerbyDriverInstance() {
try {
Class.forName(DRIVER).newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
Logger.getLogger(DerbyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}

public static boolean tableAlreadyExists(SQLException e) {
return e.getSQLState().equals("X0Y32");
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
initDerbyHomeAndDriver();
getConnection(true);
shutdownConnectionAndCleanup();
} catch (SQLException ex) {
Logger.getLogger(DerbyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

我也尝试过使用外部库来删除文件夹,例如 apache 的 org.apache.commons.io.FileDeleteStrategy.FORCE.delete(file);import org. apache.commons.io.FileUtils.deleteDirectory(文件);。即使在数据库关闭后,derby 系统似乎仍然卡在文件上。

期望的行为:删除 system directory退出时。

编辑:

Windows 进程资源管理器显示 derby.log 在数据库连接关闭后仍然打开:

enter image description here

最佳答案

假设是 Derby 代码本身未能关闭此文件,这对我来说似乎是一个错误。

关闭引擎后,Derby 显然应该关闭其日志并释放对它的所有引用。

如果您有权访问 https://www.eclipse.org/mat/ 等工具您可能能够找到哪个线程(甚至哪个堆栈帧?)已将此引用分配给 derby.log 并且未能释放它。

如果您可以将此行为封装在一个演示它的小测试程序中,我鼓励您记录一个针对 Derby 的错误 (http://db.apache.org/derby/DerbyBugGuidelines.html),以便开发人员可以自己重现它并弄清楚如何修复它。

与此同时,您可以通过禁用 derby.log 文件或将 derby.log 文件重新定位到另一个目录来解决该问题。

这显然不是修复,但它可能是行为的改进,这样这个缺陷就不会再阻碍您的工作了?这里有一些关于如何控制 derby.log 文件的文档:https://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/devguide/cdevdvlp25889.html

关于java - 无法删除嵌入式数据库的 Derby 系统目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47582819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com