【发布时间】:2018-05-14 22:26:25
【问题描述】:
在为 Windows 计算机上的 Derby Embedded 数据库调用 shutdown=true 时,我无法删除 system directory。
这是我的挑战的一个最小示例:
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(file);。即使在数据库关闭后,似乎 derby 系统仍会挂在文件上。
期望的行为:在退出时删除 system directory。
编辑:
Windows 进程资源管理器显示 derby.log 在数据库连接关闭后仍处于打开状态:
【问题讨论】:
-
Windows?哪些文件无法删除?
-
编辑了注释以指定这是在 Windows 计算机上。原始帖子指出我无法删除的文件是 Derby 的系统目录 (db.apache.org/derby/docs/10.3/tuning/rtunproper32066.html)。不过,退出程序后,我可以删除该文件夹。
-
尝试使用 Microsoft Process Explorer 工具检查您正在运行的程序,并查看它打开了哪些文件和目录。这些文件中至少有一个是 Derby 系统目录中的文件。但是哪一个?你能用你的发现更新你的问题吗? docs.microsoft.com/en-us/sysinternals/downloads/… 当然,请确保在执行“shutdown=true”之后检查您的程序。
-
@BryanPendleton 看起来 Derby 正在挂在 derby.log 上。见编辑。
标签: java derby embedded-database