我正在使用java.nio.file.WatchService监视Spring启动应用程序中的一个目录。我一直收到以下异常,它似乎没有检测到被监视文件夹中的任何文件更改:
java.nio.file.ClosedWatchServiceException: null
at sun.nio.fs.AbstractWatchService.checkOpen(AbstractWatchService.java:80)
at sun.nio.fs.AbstractWatchService.take(AbstractWatchService.java:117)
at com.company.MyFilesMonitor.monitorMappingFiles(MyMappingFilesMonitor.java:27)
at com.company.MyFilesMonitor$$FastClassBySpringCGLIB$$3d959079.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
下面是创建bean的代码:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.*;
import java.util.Objects;
@Configuration
public class MyFilesMonitorConfiguration {
@Value("${company.integration.converter.mapper-files:mappers}")
private String mapperFilesLocation;
@Bean
public WatchService mappingFilesWatch() throws IOException, URISyntaxException {
URL url = Objects.requireNonNull(ClassUtils.getDefaultClassLoader()).getResource(mapperFilesLocation);
try(WatchService watchService = FileSystems.getDefault().newWatchService()) {
Path path = Paths.get(url.toURI());
if (!Files.isDirectory(path)) {
// ToDo: i18n
throw new RuntimeException("Invalid mapping files path" + path);
}
path.register(
watchService,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_CREATE
);
return watchService;
}
}
}
这是使用watchServicebean的类:
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.nio.file.*;
@Service
public class MyMappingFilesMonitor {
private final WatchService watchService;
private static final Logger LOGGER = LoggerFactory.getLogger(MyMappingFilesMonitor.class);
@Autowired
public MyMappingFilesMonitor(WatchService watchService) {
this.watchService = watchService;
}
@Async
@Scheduled(fixedDelay = 1000)
public void monitorMappingFiles() {
final WatchKey key;
try {
key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
final WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
@SuppressWarnings("unchecked")
final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) event;
final Path filename = watchEventPath.context();
System.out.println("******** kind: " + kind + " -> " + filename);
key.reset();
}
} catch (InterruptedException e) {
return;
}
}
}
我不知道我在这里错过了什么。我在这里和那里查看了不同的示例代码,我没有做任何不同的事情,但我仍然一直得到这个异常。任何帮助或建议都将不胜感激。
您正在使用try-with-resources来创建新的监视服务,因此在方法mappingFilesWatch()
返回它时它总是关闭的:
try(WatchService watchService = FileSystems.getDefault().newWatchService()) {
...
return watchService; // THIS IS AUTO-CLOSED
}
您只需要删除try块。