Java 在删除jar文件时优雅地关闭jvm
Java 在删除jar文件时优雅地关闭jvm,java,jvm,Java,Jvm,System.getProperty(“java.class.path”)返回java进程使用的jar文件列表。我有一个服务器进程,当这些jar文件被删除时,它需要优雅地关闭。服务器有一个看门狗线程,如果任何jar文件被删除,它可以关闭进程 我的问题是如何查找是否删除了任何jar(删除/更改了权限) 查找是否删除了任何jar的一种方法是定期检查File.exists是否为每个jar文件返回true或not jvm是否支持在每次不手动检查文件状态的情况下获取此信息?检测所有jar文件是否完整的最佳
System.getProperty(“java.class.path”)
返回java进程使用的jar文件列表。我有一个服务器进程,当这些jar文件被删除时,它需要优雅地关闭。服务器有一个看门狗线程,如果任何jar文件被删除,它可以关闭进程
我的问题是如何查找是否删除了任何jar(删除/更改了权限)
查找是否删除了任何jar的一种方法是定期检查File.exists是否为每个jar文件返回true或not
jvm是否支持在每次不手动检查文件状态的情况下获取此信息?检测所有jar文件是否完整的最佳方法是什么
谢谢。虚拟机中没有专门监视类路径上的jar的功能,没有;您必须通过从j.c.p属性收集jar文件并使用来监视这些文件,从而自己对其进行编程。下面是一个示例代码,它实现了@rzwitserloop指出的功能。示例代码基于上提供的示例。在监视多个文件夹和引发多个事件的情况下,需要进行性能测试
public class CPChangeListeningJava{
public static void main( String[] args ){
/* Store the classpath to check against during an event. */
String cp = System.getProperty( "java.class.path" );
/* For every unique directory in the classpath, create a WatchService. (Only one case shown here.) */
try{
WatchService watcher = FileSystems.getDefault().newWatchService();
String dirStr = "C:\\SKN\\Workspaces\\General\\ctools\\target"; //One of the paths in the classpath
Path dir = Paths.get( dirStr );
try{
WatchKey key = dir.register( watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY );
while( true ){
try{
key = watcher.take();
}
catch( InterruptedException x ){
return;
}
for( WatchEvent<?> event : key.pollEvents() ){
WatchEvent.Kind<?> kind = event.kind();
if( kind == OVERFLOW ){
continue;
}
// The filename is the context of the event.
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path filename = ev.context();
/* If the file is present in the classpath, process it. */
String fullFilePath = dirStr + "\\" + filename; //You may want to check based on Path instances
if( cp.contains( fullFilePath ) ) System.out.println( filename + ": " + ev.kind() );
}
/* Reset the key to receive further watch events. */
boolean valid = key.reset();
if( !valid ) break;
}
}
catch( IOException x ){
System.err.println( x );
}
}
catch( IOException e ){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
公共类cpchangelistingjava{
公共静态void main(字符串[]args){
/*存储事件期间要检查的类路径*/
字符串cp=System.getProperty(“java.class.path”);
/*对于类路径中的每个唯一目录,创建一个WatchService(此处仅显示一个案例)*/
试一试{
WatchService watcher=FileSystems.getDefault().newWatchService();
String dirStr=“C:\\SKN\\workspace\\General\\ctools\\target”;//类路径中的一个路径
Path dir=Path.get(dirStr);
试一试{
WatchKey key=dir.register(观察者、条目创建、条目删除、条目修改);
while(true){
试一试{
key=watcher.take();
}
捕捉(中断异常x){
返回;
}
for(WatchEvent事件:key.pollEvents()){
WatchEvent.Kind-Kind=event.Kind();
如果(种类==溢出){
继续;
}
//文件名是事件的上下文。
WatchEvent ev=(WatchEvent)事件;
路径文件名=ev.context();
/*如果文件存在于类路径中,则处理它*/
String fullFilePath=dirStr+“\\”+filename;//您可能需要基于路径实例进行检查
if(cp.contains(fullFilePath))System.out.println(filename+”:“+ev.kind());
}
/*重置按键以接收更多的监视事件*/
布尔有效值=key.reset();
如果(!有效)中断;
}
}
捕获(IOX异常){
系统错误println(x);
}
}
捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
这可能是一个开始:您正在描述两个步骤–1。请注意,一个文件已被移动,2。停止JVM。步骤1可以在Java应用程序中运行,也可以在外部运行(各种脚本选择)。步骤2也可以从Java应用程序或外部触发(通过向正在运行的JVM发送信号)。对步骤1感兴趣的只是您提到的@kaanIf您不想使用WatchService,轮询每个文件的存在没有什么错,除非您需要立即收到文件删除的通知。请注意,删除类路径中的.jar文件是不正常的。在Windows中甚至不可能实现。我知道用于锁定此类文件的Java进程;我不确定它是否仍然存在。在我的系统上,当在类路径中使用jar文件的JVM进程正在运行时,我不能删除jar文件……如果你想跟上未来(已经存在),你必须知道还有一个模块路径可能包含jar文件。删除包含关机所需代码(尚未加载)的jar文件可能会阻止正常关机。但您可以在类路径中获取jar的目录部分,并为每个jar创建WatcherService
s。然后,在事件上,您可以检查文件名(事件发生的位置)是否为类路径条目。