无法删除嵌入式数据库的Derby系统目录 [英] Unable to delete Derby System Directory for Embedded Database

查看:154
本文介绍了无法删除嵌入式数据库的Derby系统目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法删除

解决方案

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



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



如果您可以使用> ://www.eclipse.org/mat/ ,您也许可以找到哪个线程(甚至哪个堆栈帧?)已将该引用分配给derby.log,但未能释放该引用。



如果您可以将此行为封装在一个演示该行为的小型测试程序中,建议您记录一个针对Derby的错误( http://db.apache.org/derby/DerbyBugGuidelines.html ),以便开发人员可以自己复制并找出解决方法。 / p>

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



这显然不是解决办法,但这可能是行为上的一种改进,以致该缺陷不再阻碍您的工作了?以下是有关如何控制derby.log文件的一些文档: https://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/devguide/cdevdvlp25889.html


I am unable to delete the system directory upon calling shutdown=true for a Derby Embedded database on a Windows computer.

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); or 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.

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:

解决方案

Assuming that it's Derby code itself which has failed to close this file, this seems like a bug to me.

After you shut down the Engine, Derby clearly should close its log and release all its references to it.

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.

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.

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.

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系统目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆