Java没有';t在应用程序关闭时释放所有资源
我有两个javafx应用程序,一个是应用程序和更新程序。 应用程序使用Firebird数据库存储一些脆弱的用户数据。数据库以嵌入式模式运行(我认为这是相关的),所以这意味着同一时间只能有一个到数据库的连接(数据库创建一个锁文件)。 更新程序更新应用程序 整个架构如下所示:Java没有';t在应用程序关闭时释放所有资源,java,windows,javafx,firebird,firebird-embedded,Java,Windows,Javafx,Firebird,Firebird Embedded,我有两个javafx应用程序,一个是应用程序和更新程序。 应用程序使用Firebird数据库存储一些脆弱的用户数据。数据库以嵌入式模式运行(我认为这是相关的),所以这意味着同一时间只能有一个到数据库的连接(数据库创建一个锁文件)。 更新程序更新应用程序 整个架构如下所示: 用户运行App->App正在检查是否需要更新,如果需要,则启动更新程序(使用java ProcessBuilder)并关闭自身(Platform.exit()) 更新程序检查应用程序是否已正确终止 更新程序运行命令“App--
- 当我启动应用程序并按[X]关闭它时,所有 “C:\ProgramData\firebird”中的锁定文件将被删除,但当应用程序 启动更新程序并关闭自身,然后锁定文件保持不变。我认为这就是为什么Hibernate不能开始事务
- 更新程序的进程不是应用程序的子进程(我使用进程监视器对此进行了检查)
- 当我直接启动Updater时,它就像一个符咒一样工作-所以问题只有在应用程序启动Updater时才会出现。
- 将数据库切换到其他任何位置-必须嵌入firebird
- 将导出函数移到更新程序
经过长时间的战斗,我终于找到了解决办法。当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
启动的进程也会被终止。