Search code examples
javadatabase-connectionderbydelete-file

folder/file deletion not working when first connected to derby


UPDATE: it looks like system.exit(0) is unlocking the file and allows the second code example to work. How can I unlock the file without calling system.exit()?

I have two code examples. The first creates a database, closes the connection and then tries to delete the database. It fails when trying to delete the directory folder.

The second code example just deletes the folder. It works and is the same code used in the first code example.

I think there may be some type of timing issue. Even though the connection is closed before the delete occurs in the first example I'm wondering if the delete operation is not working because of some latent connection.

First code example:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.io.FileUtils;
import java.io.*;

public class DBtest{        
    public static void main(String[] args) {
        System.out.print('\u000C');
        String db = "test2";

        File file = new File(db);
        Connection conn = getDB(db);  

        try{ 
            if (conn != null) conn.close();
            System.out.println("connection closed " );
        }catch(SQLException e){
            System.out.println("connection NOT closed " + e);
            System.exit(0);
        }

        deleteDirectory(file);
        System.exit(0);

    }
    public static boolean deleteDirectory(File directoryToBeDeleted){
        File[] allContents = directoryToBeDeleted.listFiles();
        if (allContents != null) {
            for (File file : allContents) {           
               deleteDirectory(file);
            }
        }
        directoryToBeDeleted.setWritable(true);
        System.out.println(directoryToBeDeleted.toString());
        return directoryToBeDeleted.delete();
    }   

    public static Connection getDB(String database) {
        try{ 
            /* jdbc:derby specifies the driver to use to connect to the derby database
             * database is the name of the database we want to connect to.  A database can hold many tables
             * create=true is an option that creates and connects to the database if it does not exist, 
             * or just connect if it already exists.
             */ 

            File db =new File(database);            

            String URL = "jdbc:derby:" + database + ";create=true"; 

            System.out.println("db exists " + db.exists());

            Connection conn = DriverManager.getConnection(URL);            
            System.out.println("Succesfully connected to " + database);

            return conn;
        }catch(SQLException e){
            System.out.println("FATAL ERROR: from getDB " + e);

             return null;
        }   
    }    
}

Second code example:

import org.apache.commons.io.FileUtils;
import java.io.*;
public class DirectoryDelete
{
    public static void main(String[] args){
        System.out.println('\u000C');
        File file = new File("test2");
        deleteDirectory(file);

    }

    public static boolean deleteDirectory(File directoryToBeDeleted){
        File[] allContents = directoryToBeDeleted.listFiles();
        if (allContents != null) {
           for (File file : allContents) {           
            deleteDirectory(file);
            }
        }
        directoryToBeDeleted.setWritable(true);
        System.out.println(directoryToBeDeleted.toString());
        return directoryToBeDeleted.delete();
    }
}

Is there something I need to do in the first example to free the folder/files in order to be able to delete them?


Solution

  • Well this took a fair amount of digging. Turns out you have to shut down the database in order to delete the folder. Closing the connection is not actually needed as shutting down the database will close all connections. Simply invoke DriverManager.getConnection("jdbc:derby:;shutdown=true"); and you are off to the races.