2016-11-23 67 views
1

我有兩個javafx應用程序一個應用程序和更新程序。 App使用Firebird數據庫來存儲一些脆弱的用戶數據。數據庫以嵌入模式運行(我認爲它是相關的),這意味着同時只能有一個數據庫連接(數據庫創建一個鎖文件)。 更新程序更新程序。Java不會釋放應用程序中的所有資源close

整個架構是這樣的:

  1. 用戶運行APP->應用被檢查,如果如果然後開始更新程序(用java的ProcessBuilder),並關閉本身需要更新(Platform.exit( ))。
  2. 更新程序檢查App是否已正確終止。
  3. 更新器在開始更新之前運行命令「App --export-user-data」(也使用ProcessBuilder)導出最重要的內容(必須按照這種方式進行 - 我無法將此功能移至更新器)。
  4. 應用程序凍結在第一session.beginTransaction() - 沒有一個單一的錯誤或異常

我觀察到現在什麼:

  • 當我啓動應用程序,並按下關閉[X ]然後所有 來自「C:\ ProgramData \ firebird」的鎖定文件被刪除,但是當App 啓動Updater並關閉自身時,鎖定文件保持不動。我認爲這就是爲什麼Hibernate無法開始交易。
  • 更新的過程是不是應用程序的子(我查這個過程使用監視器)
  • 當我開始直接更新它就像一個魅力 - 這樣的問題顯示出來,只有當應用程序開始更新。

事情我不能做:

  • 開關數據庫別的 - 它必須是火鳥嵌入式
  • 移動導出功能更新

我將不勝感激甚至是最奇怪的想法,因爲我花了四天時間來解決這個問題。

編輯: 火鳥版本:2.1 Jaybird版本:2.1.6

的方式更新開始(僅在必要的東西)

public void startUpdater(){ 
    ProcessBuilder pb = new ProcessBuilder(updaterPath, argument) 
    pb.start(); 
    Platform.exit(); 
} 
+0

請顯示重現此操作所必需的最低代碼。還包括Firebird嵌入式版本和您正在使用的Jaybird版本。 –

+2

沒有看到任何代碼,我想你應該做一個適度的關閉你的應用程序,而不是隻調用exit()。 – Henry

+0

我無法發佈源代碼,因爲它不屬於我,但我會嘗試提供一些sinippets。我還會提供更多關於firebird的信息。 – straw

回答

0

久戰之後我finaly有一個解決辦法。當java創建一個新進程時,子進程繼承它父進程的所有句柄。這就是爲什麼firebird鎖定文件沒有被刪除。我通過在cpp中創建小應用程序並在運行更新程序時將其用作代理來解決此問題。

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

int _tmain(int argc, TCHAR *argv[]) 
{ 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 

    if(argc != 2) 
    { 
     printf("Usage: %s [cmdline]\n", argv[0]); 
     return 0; 
    } 

    // Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
     argv[1],  // Command line 
     NULL,   // Process handle not inheritable 
     NULL,   // Thread handle not inheritable 
     FALSE,   // Set handle inheritance to FALSE 
     0,    // No creation flags 
     NULL,   // Use parent's environment block 
     NULL,   // Use parent's starting directory 
     &si,   // Pointer to STARTUPINFO structure 
     &pi)   // Pointer to PROCESS_INFORMATION structure 
    ) 
    { 
     printf("CreateProcess failed (%d).\n", GetLastError()); 
     return 0; 
    } 

}