简体   繁体   English

无法删除嵌入式数据库的Derby System Directory

[英]Unable to delete Derby System Directory for Embedded Database

I am unable to delete the system directory upon calling shutdown=true for a Derby Embedded database on a Windows computer. 在Windows计算机上为Derby Embedded数据库调用shutdown = true时,我无法删除系统目录

Here's a minimal example of my challenge: 这是我挑战的最小例子:

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);
        }
    }
}

I have tried using external libraries to delete the folder as well such as the apache's org.apache.commons.io.FileDeleteStrategy.FORCE.delete(file); 我已经尝试使用外部库来删除文件夹,例如apache的org.apache.commons.io.FileDeleteStrategy.FORCE.delete(file); or import org.apache.commons.io.FileUtils.deleteDirectory(file); 或者import org.apache.commons.io.FileUtils.deleteDirectory(file); . It seems like the derby system still hangs onto the file even after the database is shutdown. 即使在数据库关闭后,似乎derby系统仍然挂起到文件上。

Desired behavior: Delete the system directory on exit. 所需行为:退出时删除系统目录

Edit: 编辑:

Windows process explorer shows me that derby.log is still open after the database connection is shutdown: Windows进程资源管理器向我显示在数据库连接关闭后,derby.log仍处于打开状态:

在此输入图像描述

Assuming that it's Derby code itself which has failed to close this file, this seems like a bug to me. 假设它的Derby代码本身无法关闭此文件,这对我来说似乎是个错误。

After you shut down the Engine, Derby clearly should close its log and release all its references to it. 关闭Engine之后,Derby显然应该关闭它的日志并释放它的所有引用。

If you have access to a tool such as https://www.eclipse.org/mat/ you might be able to find which thread (and even which stack frame?) has allocated this reference to derby.log and failed to release it. 如果您可以访问https://www.eclipse.org/mat/这样的工具,您可能能够找到哪个线程(甚至是哪个堆栈框架?)已将此引用分配给derby.log并且无法释放它。

If you can encapsulate this behavior in a small test program which demonstrates it, I encourage you to log a bug against Derby ( http://db.apache.org/derby/DerbyBugGuidelines.html ) so that the developers can reproduce it themselves and figure out how to fix it. 如果您可以将此行为封装在一个演示它的小型测试程序中,我建议您记录针对Derby的错误( http://db.apache.org/derby/DerbyBugGuidelines.html ),以便开发人员可以自己重现它弄清楚如何解决它。

In the meantime, you may be able to work around the problem by disabling the derby.log file, or by relocating the derby.log file to another directory. 在此期间,您可以通过禁用derby.log文件或将derby.log文件重定位到另一个目录来解决此问题。

That's clearly not a fix, but it might be an improvement in the behavior such that this flaw isn't blocking your work anymore? 这显然不是一个解决方案,但它可能是一种行为的改善,以至于这个缺陷不再阻碍你的工作了? Here's some documentation about how to control the derby.log file: https://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/devguide/cdevdvlp25889.html 以下是有关如何控制derby.log文件的一些文档: https ://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/devguide/cdevdvlp25889.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM