Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java没有';t在应用程序关闭时释放所有资源_Java_Windows_Javafx_Firebird_Firebird Embedded - Fatal编程技术网

Java没有';t在应用程序关闭时释放所有资源

Java没有';t在应用程序关闭时释放所有资源,java,windows,javafx,firebird,firebird-embedded,Java,Windows,Javafx,Firebird,Firebird Embedded,我有两个javafx应用程序,一个是应用程序和更新程序。 应用程序使用Firebird数据库存储一些脆弱的用户数据。数据库以嵌入式模式运行(我认为这是相关的),所以这意味着同一时间只能有一个到数据库的连接(数据库创建一个锁文件)。 更新程序更新应用程序 整个架构如下所示: 用户运行App->App正在检查是否需要更新,如果需要,则启动更新程序(使用java ProcessBuilder)并关闭自身(Platform.exit()) 更新程序检查应用程序是否已正确终止 更新程序运行命令“App--

我有两个javafx应用程序,一个是应用程序和更新程序。 应用程序使用Firebird数据库存储一些脆弱的用户数据。数据库以嵌入式模式运行(我认为这是相关的),所以这意味着同一时间只能有一个到数据库的连接(数据库创建一个锁文件)。 更新程序更新应用程序

整个架构如下所示:

  • 用户运行App->App正在检查是否需要更新,如果需要,则启动更新程序(使用java ProcessBuilder)并关闭自身(Platform.exit())
  • 更新程序检查应用程序是否已正确终止
  • 更新程序运行命令“App--export user data”(也使用ProcessBuilder)在开始更新之前导出最重要的内容(必须这样做-我无法将此函数移动到更新程序)
  • 应用程序在第一次会话时冻结。beginTransaction()-没有单一错误或异常
  • 到目前为止,我观察到:

    • 当我启动应用程序并按[X]关闭它时,所有 “C:\ProgramData\firebird”中的锁定文件将被删除,但当应用程序 启动更新程序并关闭自身,然后锁定文件保持不变。我认为这就是为什么Hibernate不能开始事务
    • 更新程序的进程不是应用程序的子进程(我使用进程监视器对此进行了检查)
    • 当我直接启动Updater时,它就像一个符咒一样工作-所以问题只有在应用程序启动Updater时才会出现。
    我不能做的事情:

    • 将数据库切换到其他任何位置-必须嵌入firebird
    • 将导出函数移到更新程序
    即使是最奇怪的想法,我也会非常感激,因为我花了四天时间试图解决这个问题

    编辑: 火鸟版本:2.1 Jaybird版本:2.1.6

    更新程序的启动方式(仅限于必要的内容)


    经过长时间的战斗,我终于找到了解决办法。当java创建一个新进程时,子进程从其父进程继承所有句柄。这就是为什么firebird锁文件没有被删除。我在cpp中创建了一个小应用程序,并在运行updater时将其用作代理,从而解决了这个问题

    #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;
        }
    
    }
    
    #包括
    #包括
    #包括
    int_tmain(int argc,TCHAR*argv[])
    {
    STARTUPINFO si;
    处理信息;
    零内存(&si,sizeof(si));
    si.cb=sizeof(si);
    零内存(&pi,sizeof(pi));
    如果(argc!=2)
    {
    printf(“用法:%s[cmdline]\n”,argv[0]);
    返回0;
    }
    //启动子进程。
    如果(!CreateProcess(NULL,//没有模块名称(使用命令行)
    argv[1],//命令行
    NULL,//进程句柄不可继承
    NULL,//线程句柄不可继承
    FALSE,//将句柄继承设置为FALSE
    0,//没有创建标志
    NULL,//使用父级的环境块
    NULL,//使用父级的起始目录
    &si,//指向STARTUPINFO结构的指针
    &pi)//指向进程信息结构的指针
    ) 
    {
    printf(“CreateProcess失败(%d)。\n”,GetLastError());
    返回0;
    }
    }
    
    经过长时间的战斗,我终于找到了解决办法。当java创建一个新进程时,子进程从其父进程继承所有句柄。这就是为什么firebird锁文件没有被删除。我在cpp中创建了一个小应用程序,并在运行updater时将其用作代理,从而解决了这个问题

    #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;
        }
    
    }
    
    #包括
    #包括
    #包括
    int_tmain(int argc,TCHAR*argv[])
    {
    STARTUPINFO si;
    处理信息;
    零内存(&si,sizeof(si));
    si.cb=sizeof(si);
    零内存(&pi,sizeof(pi));
    如果(argc!=2)
    {
    printf(“用法:%s[cmdline]\n”,argv[0]);
    返回0;
    }
    //启动子进程。
    如果(!CreateProcess(NULL,//没有模块名称(使用命令行)
    argv[1],//命令行
    NULL,//进程句柄不可继承
    NULL,//线程句柄不可继承
    FALSE,//将句柄继承设置为FALSE
    0,//没有创建标志
    NULL,//使用父级的环境块
    NULL,//使用父级的起始目录
    &si,//指向STARTUPINFO结构的指针
    &pi)//指向进程信息结构的指针
    ) 
    {
    printf(“CreateProcess失败(%d)。\n”,GetLastError());
    返回0;
    }
    }
    
    请显示复制此文件所需的最低代码。还包括Firebird嵌入式版本和您正在使用的Jaybird版本。在没有看到任何代码的情况下,我想您应该优雅地关闭应用程序,而不是只调用exit()。我无法发布源代码,因为它不属于我,但我将尝试提供一些sinippets。我还将提供有关firebird的更多信息。调用
    Platform.exit()
    可能会终止应用程序和-iirc-child应用程序。这可能意味着Firebird embedded不会干净地关闭,也可能意味着使用
    ProcessBuilder
    启动的进程也会被终止。请显示重现此过程所需的最少代码。还包括Firebird嵌入式版本和您正在使用的Jaybird版本。在没有看到任何代码的情况下,我想您应该优雅地关闭应用程序,而不是只调用exit()。我无法发布源代码,因为它不属于我,但我将尝试提供一些sinippets。我还将提供有关firebird的更多信息。调用
    Platform.exit()
    可能会终止应用程序和-iirc-child应用程序。这可能意味着Firebird embedded不会干净地关闭,也可能意味着使用
    ProcessBuilder
    启动的进程也会被终止。