2017-11-30 3 views
2

Windows 컴퓨터에서 Derby Embedded 데이터베이스에 대해 shutdown = true를 호출하면 system directory을 삭제할 수 없습니다. 같은내장 데이터베이스 용 Derby 시스템 디렉토리를 삭제할 수 없습니다.

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

나뿐만 아니라 폴더를 삭제하는 외부 라이브러리를 사용하여 시도 아파치의 org.apache.commons.io.FileDeleteStrategy.FORCE.delete(file); 또는 import org.apache.commons.io.FileUtils.deleteDirectory(file); :

은 여기 내 도전의 최소한의 예입니다. 데이터베이스가 종료 된 후에도 더비 시스템이 여전히 파일에 정지 된 것처럼 보입니다.

원하는 동작 : 종료시 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 도구를 사용하여 실행중인 프로그램을 검사하고 열려있는 파일과 디렉터리를 확인하십시오. 이 파일 중 적어도 하나는 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

관련 문제