我有一个Vaadin Web应用程序,即部署OK。 但是当我使用
添加FolderWatcher服务作为监听器时@WebListener
应用程序无法部署,但如果我禁用应用程序部署的注释@WebListener
,它将启动该线程。
文件夹观察者类
public class FolderWatchService {
private final WatchService watcher;
private final Map<WatchKey, Path> keys;
private static final Logger LOGGER = Logger.getLogger( FolderWatchService.class.getName() );
/**
* Creates a WatchService and registers the given directory
*/
public FolderWatchService(Path dir) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey, Path>();
walkAndRegisterDirectories(dir);
}
/**
* Register the given directory with the WatchService; This function will be called by FileVisitor
*/
private void registerDirectory(Path dir) throws IOException
{
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
}
/**
* Register the given directory, and all its sub-directories, with the WatchService.
*/
private void walkAndRegisterDirectories(final Path start) throws IOException {
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
registerDirectory(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
* Process all events for keys queued to the watcher
*/
public void processEvents() {
for (;;) {
// wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
Path dir = keys.get(key);
if (dir == null) {
LOGGER.log( Level.FINE, "WatchKey not recognized!!", "" );
System.err.println("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event : key.pollEvents()) {
@SuppressWarnings("rawtypes")
WatchEvent.Kind kind = event.kind();
// Context for directory entry event is the file name of entry
@SuppressWarnings("unchecked")
Path name = ((WatchEvent<Path>)event).context();
Path child = dir.resolve(name);
String fileContent;
// if directory is created, and watching recursively, then register it and its sub-directories
if (kind == ENTRY_CREATE) {
System.out.println("File created");
LOGGER.log( Level.FINER, "New File created", "" );
readFile(child.toString());
}
}
// reset key and remove from set if directory no longer accessible
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
break;
}
}
}
}
private static void readFile(String pathname){
try {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");
try {
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + lineSeparator);
}
String fileContent = fileContents.toString();
System.out.println("File name: "+FilenameUtils.getBaseName(pathname));
LOGGER.log( Level.FINER, "File name: "+FilenameUtils.getBaseName(pathname), "" );
String title = "File Title: "+fileContent.substring(0, 64).trim().lastIndexOf(System.getProperty("line.separator"))+"...";
} finally {
scanner.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ContextLister类
@WebListener
public class ContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("#### Folder watcher service destroyed");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("#### Folder watcher service initialized");
Path dir = Paths.get(PropertiesCache.getInstance().getProperty("file_input_location"));
try {
new FolderWatchService(dir).processEvents();
System.out.println("#### Folder watcher service started");
} catch (IOException e) {
System.out.println("#### Folder watcher Problem");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
编辑:添加了日志打印的内容
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.AprLifecycleListener
lifecycleEvent
INFO: Loaded APR based Apache Tomcat Native library 1.2.12 using APR version
1.5.2.
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.AprLifecycleListener
lifecycleEvent
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters
[false], random [true].
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.AprLifecycleListener
lifecycleEvent
INFO: APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.AprLifecycleListener
initializeSSL
INFO: OpenSSL successfully initialized (OpenSSL 1.0.2k 26 Jan 2017)
Jun 26, 2017 10:56:31 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Jun 26, 2017 10:56:31 PM org.apache.tomcat.util.net.NioSelectorPool
getSharedSelector
INFO: Using a shared selector for servlet write/read
Jun 26, 2017 10:56:31 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-nio-8009"]
Jun 26, 2017 10:56:31 PM org.apache.tomcat.util.net.NioSelectorPool
getSharedSelector
INFO: Using a shared selector for servlet write/read
Jun 26, 2017 10:56:31 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1392 ms
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.StandardService
startInternal
INFO: Starting service Catalina
Jun 26, 2017 10:56:31 PM org.apache.catalina.core.StandardEngine
startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.5.12
Jun 26, 2017 10:56:32 PM org.apache.catalina.util.SessionIdGeneratorBase
createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using
[SHA1PRNG] took [126] milliseconds.
Jun 26, 2017 10:56:40 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable
debug logging for this logger for a complete list of JARs that were scanned
but no TLDs were found in them. Skipping unneeded JARs during scanning can
improve startup time and JSP compilation time.
#### Folder watcher service initialized
这里的最后一行是来自ContextLister的println和应用程序
我在这里做错了什么?
答案 0 :(得分:0)
监听器实现似乎在new FolderWatchService(dir).processEvents();
阻塞。您应该在另一个线程中运行事件处理(即使用ExecutorService提交processEvents
作业,并可能在contextDestroyed
中取消/关闭