2017-11-30 44 views
2

Windowsコンピュータ上のDerby組み込みデータベースに対して、shutdown = trueを呼び出すとsystem directoryを削除できません。など組み込みデータベース用のDerby 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を削除してください。

編集:

それは、これを閉じるために失敗したダービーコード自体だと仮定すると、

enter image description here

+0

Windows?どのファイルを削除できませんか? – Bill

+0

コメントが編集され、これがWindowsコンピュータ上にあることを指定します。元の投稿には、削除できないファイルがDerbyのシステムディレクトリ(https://db.apache.org/derby/docs/10.3/tuning/rtunproper32066.html)であることが記載されています。プログラムを終了すると、私はそのフォルダを削除することができます。 –

+0

Microsoft Process Explorerツールを使用して実行中のプログラムを調べ、開いているファイルとディレクトリを確認してください。これらのファイルの少なくとも1つは、Derbyシステム・ディレクトリー内のファイルになります。しかし、どちら?あなたの発見であなたの質問を更新できますか? https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorerそして、当然のことながら、あなたが** shutdown = trueを実行した後にあなたのプログラムをチェックしてください**。 –

答えて

1

Windowsプロセスエクスプローラは、データベース接続がシャットダウンされた後derby.logがまだ開いていることを私に示してファイル、これは私のバグのようです。

エンジンをシャットダウンした後、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

関連する問題