use of java.nio.file.Watchable in project ci.common by OpenLiberty.
the class DevUtil method watchFiles.
/**
* Watch files for changes.
*
* @param outputDirectory
* @param testOutputDirectory
* @param executor
* @param compileArtifactPaths Compile classpath elements, or null if this
* DevUtil instance has useBuildRecompile=true
* @param testArtifactPaths Test classpath elements, or null if this
* DevUtil instance has useBuildRecompile=true
* @param serverXmlFile Can be null when using the server.xml from the
* configDirectory, which has a default value.
* @param bootstrapPropertiesFile
* @param jvmOptionsFile
* @throws Exception
*/
public void watchFiles(File outputDirectory, File testOutputDirectory, final ThreadPoolExecutor executor, File serverXmlFile, File bootstrapPropertiesFile, File jvmOptionsFile) throws Exception {
this.outputDirectory = outputDirectory;
this.testOutputDirectory = testOutputDirectory;
this.serverXmlFile = serverXmlFile;
this.bootstrapPropertiesFile = bootstrapPropertiesFile;
this.jvmOptionsFile = jvmOptionsFile;
this.dockerfileUsed = null;
this.initialCompile = true;
this.disableDependencyCompile = false;
this.omitWatchingFiles = new ArrayList<File>();
try {
if (isLooseApplication()) {
this.looseAppFile = getLooseApplicationFile();
debug("Loose application configuration file set to: " + looseAppFile);
}
watcher = FileSystems.getDefault().newWatchService();
serverXmlFileParent = null;
if (serverXmlFile != null && serverXmlFile.exists()) {
serverXmlFileParent = serverXmlFile.getParentFile();
}
bootstrapPropertiesFileParent = null;
if (bootstrapPropertiesFile != null && bootstrapPropertiesFile.exists()) {
bootstrapPropertiesFileParent = bootstrapPropertiesFile.getParentFile();
}
jvmOptionsFileParent = null;
if (jvmOptionsFile != null && jvmOptionsFile.exists()) {
jvmOptionsFileParent = jvmOptionsFile.getParentFile();
}
Path srcPath = this.sourceDirectory.getCanonicalFile().toPath();
Path testSrcPath = this.testSourceDirectory.getCanonicalFile().toPath();
Path configPath = this.configDirectory.getCanonicalFile().toPath();
Path srcOutputPath = this.outputDirectory.getCanonicalFile().toPath();
boolean sourceDirRegistered = false;
boolean testSourceDirRegistered = false;
boolean configDirRegistered = false;
boolean serverXmlFileRegistered = false;
boolean bootstrapPropertiesFileRegistered = false;
boolean jvmOptionsFileRegistered = false;
boolean sourceOutputDirRegistered = false;
// register parent poms
if (!parentBuildFiles.isEmpty()) {
for (String key : parentBuildFiles.keySet()) {
File parentBuildFile = new File(key);
if (parentBuildFile.exists()) {
registerSingleFile(parentBuildFile, executor);
}
}
}
// check for upstream projects
if (isMultiModuleProject()) {
for (ProjectModule p : upstreamProjects) {
updateArtifactPaths(p, false, generateFeatures, executor);
if (shouldIncludeSources(p.getPackagingType())) {
// watch src/main/java dir
if (p.getSourceDirectory().exists()) {
omitWatchingFiles.addAll(getOmitFilesList(looseAppFile, p.getSourceDirectory().getCanonicalPath()));
registerAll(p.getSourceDirectory().getCanonicalFile().toPath(), executor);
p.sourceDirRegistered = true;
}
// register source classes directory for feature generation
if (p.getOutputDirectory().exists()) {
registerAll(p.getOutputDirectory().getCanonicalFile().toPath(), executor);
p.sourceOutputDirRegistered = true;
}
}
// watch src/test/java dir
if (p.getTestSourceDirectory().exists()) {
registerAll(p.getTestSourceDirectory().getCanonicalFile().toPath(), executor);
p.testSourceDirRegistered = true;
}
// watch resource directories
HashMap<File, Boolean> upstreamResourceMap = new HashMap<File, Boolean>();
for (File upstreamResourceDir : p.getResourceDirs()) {
upstreamResourceMap.put(upstreamResourceDir, false);
if (upstreamResourceDir.exists()) {
registerAll(upstreamResourceDir.getCanonicalFile().toPath(), executor);
upstreamResourceMap.put(upstreamResourceDir, true);
}
}
p.setResourceMap(upstreamResourceMap);
// watch pom.xml
if (p.getBuildFile().exists()) {
registerSingleFile(p.getBuildFile(), executor);
}
}
}
if (shouldIncludeSources(packagingType)) {
if (this.sourceDirectory.exists()) {
omitWatchingFiles.addAll(getOmitFilesList(looseAppFile, this.sourceDirectory.getCanonicalPath()));
registerAll(srcPath, executor);
sourceDirRegistered = true;
}
// register source classes directory for feature generation
if (this.outputDirectory.exists()) {
registerAll(srcOutputPath, executor);
sourceOutputDirRegistered = true;
}
}
if (this.testSourceDirectory.exists()) {
registerAll(testSrcPath, executor);
testSourceDirRegistered = true;
}
if (this.configDirectory.exists()) {
registerAll(configPath, executor);
configDirRegistered = true;
}
if (serverXmlFile != null && serverXmlFile.exists() && serverXmlFileParent.exists()) {
Path serverXmlFilePath = serverXmlFileParent.getCanonicalFile().toPath();
registerAll(serverXmlFilePath, executor);
serverXmlFileRegistered = true;
}
if (bootstrapPropertiesFile != null && bootstrapPropertiesFile.exists() && bootstrapPropertiesFileParent.exists()) {
Path bootstrapPropertiesFilePath = bootstrapPropertiesFileParent.getCanonicalFile().toPath();
registerAll(bootstrapPropertiesFilePath, executor);
bootstrapPropertiesFileRegistered = true;
}
if (jvmOptionsFile != null && jvmOptionsFile.exists() && jvmOptionsFileParent.exists()) {
Path jvmOptionsFilePath = jvmOptionsFileParent.getCanonicalFile().toPath();
registerAll(jvmOptionsFilePath, executor);
jvmOptionsFileRegistered = true;
}
if (container) {
dockerfileUsed = getDockerfile();
registerSingleFile(dockerfileUsed, executor);
}
HashMap<File, Boolean> resourceMap = new HashMap<File, Boolean>();
for (File resourceDir : resourceDirs) {
resourceMap.put(resourceDir, false);
if (resourceDir.exists()) {
registerAll(resourceDir.getCanonicalFile().toPath(), executor);
resourceMap.put(resourceDir, true);
}
}
HashMap<Path, Boolean> webResourceMap = new HashMap<Path, Boolean>();
for (Path webResourceDir : webResourceDirs) {
webResourceMap.put(webResourceDir, false);
if (Files.exists(webResourceDir)) {
registerAll(webResourceDir, executor);
webResourceMap.put(webResourceDir, true);
}
}
registerSingleFile(buildFile, executor);
if (propertyFilesMap != null) {
for (File f : propertyFilesMap.keySet()) {
registerSingleFile(f, executor);
}
}
initWatchLoop();
while (true) {
// Check the server and stop dev mode by throwing an exception if the server stopped.
checkStopDevMode(true);
if (container) {
synchronized (dockerfileDirectoriesToWatch) {
if (!dockerfileDirectoriesToWatch.isEmpty()) {
for (Path path : dockerfileDirectoriesToWatch) {
File f = path.toFile();
if (f.isDirectory()) {
debug("Registering path from dockerfileDirectoriesToWatch: " + path);
registerAll(path, executor, true);
} else {
debug("Registering file path from dockerfileDirectoriesToWatch: " + path);
registerSingleFile(f, executor, true);
}
dockerfileDirectoriesTracked.add(path);
}
dockerfileDirectoriesToWatch.clear();
}
}
}
if (isMultiModuleProject()) {
// process java compilation for upstream projects
boolean change = processUpstreamJavaCompilation(upstreamProjects, executor);
// process java compilation for main project
processJavaCompilation(outputDirectory, testOutputDirectory, executor, compileArtifactPaths, testArtifactPaths, applicationId, change);
} else {
// process java compilation for main project
processJavaCompilation(outputDirectory, testOutputDirectory, executor, compileArtifactPaths, testArtifactPaths, null, false);
}
// when change in class files are detected scan for Liberty features.
if (generateFeatures && !javaSourceClasses.isEmpty()) {
debug("Detected a change in the following classes: " + javaSourceClasses);
if (!gradle && !foundInitialClasses) {
// For Maven, skip the first call of generate features from the initial Java compilation that happens after dev mode startup
// because features were already generated during the actual dev mode startup steps.
debug("Skipping generate features from first call after dev mode startup");
foundInitialClasses = true;
javaSourceClasses.clear();
} else if (!classesFailingToCompile()) {
// do not run generate features if there are classes failing to compile
incrementGenerateFeatures();
File generatedFeaturesFile = new File(configDirectory, BinaryScannerUtil.GENERATED_FEATURES_FILE_PATH);
if (!generatedFeaturesFile.exists()) {
// run tests if generated-features.xml does not exist as there are no new features to install
if (isMultiModuleProject()) {
runTestThread(false, executor, -1, false, getAllBuildFiles());
} else {
runTestThread(false, executor, -1, false, false, buildFile);
}
}
}
}
if (shouldIncludeSources(packagingType)) {
// check if javaSourceDirectory has been added
if (!sourceDirRegistered && this.sourceDirectory.exists() && this.sourceDirectory.listFiles().length > 0) {
compile(this.sourceDirectory);
registerAll(srcPath, executor);
debug("Registering Java source directory: " + this.sourceDirectory);
// run tests after waiting for app update since app changed
int numApplicationUpdatedMessages = countApplicationUpdatedMessages();
runTestThread(true, executor, numApplicationUpdatedMessages, false, buildFile);
sourceDirRegistered = true;
} else if (sourceDirRegistered && !this.sourceDirectory.exists()) {
cleanTargetDir(outputDirectory);
sourceDirRegistered = false;
}
// check if javaSourceOutputDirectory has been added
if (!sourceOutputDirRegistered && this.outputDirectory.exists() && this.outputDirectory.list().length > 0) {
registerAll(this.outputDirectory.getCanonicalFile().toPath(), executor);
debug("Registering Java source output directory: " + this.outputDirectory);
sourceOutputDirRegistered = true;
}
}
// check if testSourceDirectory has been added
if (!testSourceDirRegistered && this.testSourceDirectory.exists() && this.testSourceDirectory.listFiles().length > 0) {
compile(this.testSourceDirectory);
registerAll(testSrcPath, executor);
debug("Registering Java test directory: " + this.testSourceDirectory);
runTestThread(false, executor, -1, false, buildFile);
testSourceDirRegistered = true;
} else if (testSourceDirRegistered && !this.testSourceDirectory.exists()) {
cleanTargetDir(testOutputDirectory);
testSourceDirRegistered = false;
}
// check if configDirectory has been added
if (!configDirRegistered && this.configDirectory.exists()) {
configDirRegistered = true;
if (serverXmlFile != null && !serverXmlFile.exists()) {
registerAll(configPath, executor);
debug("Registering configuration directory: " + this.configDirectory);
} else {
warn("The server configuration directory " + configDirectory + " has been added. Restart dev mode for it to take effect.");
}
}
// check if serverXmlFile has been added
if (!serverXmlFileRegistered && serverXmlFile != null && serverXmlFile.exists()) {
serverXmlFileRegistered = true;
debug("Server configuration file has been added: " + serverXmlFile);
warn("The server configuration file " + serverXmlFile + " has been added. Restart dev mode for it to take effect.");
}
if (!bootstrapPropertiesFileRegistered && bootstrapPropertiesFile != null && bootstrapPropertiesFile.exists()) {
bootstrapPropertiesFileRegistered = true;
debug("Bootstrap properties file has been added: " + bootstrapPropertiesFile);
warn("The bootstrap properties file " + bootstrapPropertiesFile + " has been added. Restart dev mode for it to take effect.");
}
if (!jvmOptionsFileRegistered && jvmOptionsFile != null && jvmOptionsFile.exists()) {
jvmOptionsFileRegistered = true;
debug("JVM Options file has been added: " + jvmOptionsFile);
warn("The JVM Options file " + jvmOptionsFile + " has been added. Restart dev mode for it to take effect.");
}
// check if resourceDirectory has been added
for (File resourceDir : resourceDirs) {
if (!resourceMap.get(resourceDir) && resourceDir.exists()) {
resourceDirectoryCreated();
registerAll(resourceDir.getCanonicalFile().toPath(), executor);
resourceMap.put(resourceDir, true);
} else if (resourceMap.get(resourceDir) && !resourceDir.exists()) {
// deleted resource directory
warn("The resource directory " + resourceDir + " was deleted. Restart dev mode for it to take effect.");
resourceMap.put(resourceDir, false);
}
}
// Check if webResourceDirectory has been added or deleted
for (Path webResourceDir : webResourceDirs) {
if (!webResourceMap.get(webResourceDir) && Files.exists(webResourceDir)) {
updateLooseApp();
registerAll(webResourceDir, executor);
webResourceMap.put(webResourceDir, true);
runTestThread(false, executor, -1, false, false);
} else if (webResourceMap.get(webResourceDir) && !Files.exists(webResourceDir)) {
// deleted webResource directory
updateLooseApp();
warn("The webResource directory " + webResourceDir + " was deleted. Restart liberty:dev mode for it to take effect.");
webResourceMap.put(webResourceDir, false);
runTestThread(false, executor, -1, false, false);
}
}
if (isMultiModuleProject()) {
for (ProjectModule p : upstreamProjects) {
// check if resource directory of an upstream project has been added/deleted
for (File resourceDir : p.getResourceDirs()) {
if (!p.getResourceMap().get(resourceDir) && resourceDir.exists()) {
registerAll(resourceDir.getCanonicalFile().toPath(), executor);
p.getResourceMap().put(resourceDir, true);
} else if (p.getResourceMap().get(resourceDir) && !resourceDir.exists()) {
// deleted resource directory
warn("The resource directory " + resourceDir + " was deleted. Restart dev mode for it to take effect.");
p.getResourceMap().put(resourceDir, false);
}
}
// https://github.com/OpenLiberty/ci.maven/issues/1202
if (shouldIncludeSources(p.getPackagingType())) {
if (!p.sourceDirRegistered && p.getSourceDirectory().exists() && p.getSourceDirectory().listFiles().length > 0) {
p.sourceDirRegistered = true;
warn("The source directory " + p.getSourceDirectory() + " was added. This may result in compilation errors between dependent modules. Restart dev mode for it to take effect.");
} else if (p.sourceDirRegistered && !p.getSourceDirectory().exists()) {
p.sourceDirRegistered = false;
warn("The source directory " + p.getSourceDirectory() + " was deleted. This may result in compilation errors between dependent modules. Restart dev mode for it to take effect.");
}
// TODO register adding a new output directory once adding a src/main/java dir
// to an upstream project is supported
}
// check if test directory of an upstream project has been added/deleted
if (!p.testSourceDirRegistered && p.getTestSourceDirectory().exists() && p.getTestSourceDirectory().listFiles().length > 0) {
compile(p.getTestSourceDirectory(), p);
registerAll(p.getTestSourceDirectory().getCanonicalFile().toPath(), executor);
p.testSourceDirRegistered = true;
debug("Registering Java test directory: " + p.getTestSourceDirectory());
// compile all tests in downstream modules
for (File dependentBuildFile : p.getDependentModules()) {
ProjectModule depModule = getProjectModule(dependentBuildFile);
if (depModule != null) {
compile(depModule.getTestSourceDirectory(), depModule);
} else {
// main module
compile(this.testSourceDirectory);
}
}
runTestThread(false, executor, -1, false, getAllBuildFiles(p));
} else if (p.testSourceDirRegistered && !p.getTestSourceDirectory().exists()) {
cleanTargetDir(p.getTestOutputDirectory());
p.testSourceDirRegistered = false;
}
}
}
if (trackingMode == FileTrackMode.FILE_WATCHER || trackingMode == FileTrackMode.NOT_SET) {
try {
final WatchKey wk = watcher.poll(100, TimeUnit.MILLISECONDS);
final Watchable watchable = wk.watchable();
final Path directory = (Path) watchable;
List<WatchEvent<?>> events = wk.pollEvents();
for (WatchEvent<?> event : events) {
if (trackingMode == FileTrackMode.NOT_SET) {
trackingMode = FileTrackMode.FILE_WATCHER;
disablePolling();
}
final Path changed = (Path) event.context();
debug("Processing events for watched directory: " + directory);
File fileChanged = new File(directory.toString(), changed.toString());
if (ignoreFileOrDir(fileChanged)) {
// skip this file or directory, and continue to the next file or directory
continue;
}
debug("Changed: " + changed + "; " + event.kind());
ChangeType changeType = null;
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
changeType = ChangeType.CREATE;
} else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
changeType = ChangeType.MODIFY;
} else if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
changeType = ChangeType.DELETE;
}
processFileChanges(executor, fileChanged, outputDirectory, false, changeType);
}
// reset the key
boolean valid = wk.reset();
if (!valid) {
debug("WatchService key has been unregistered for " + directory);
}
} catch (InterruptedException | NullPointerException e) {
// do nothing let loop continue
}
}
if (trackingMode == FileTrackMode.POLLING || trackingMode == FileTrackMode.NOT_SET) {
synchronized (newFileObservers) {
consolidateFileObservers();
}
// iterate through file observers
for (FileAlterationObserver observer : fileObservers) {
if (!cancelledFileObservers.contains(observer)) {
observer.checkAndNotify();
}
}
synchronized (cancelledFileObservers) {
removeCancelledFileObservers();
}
Thread.sleep(pollingInterval);
}
}
} finally {
if (watcher != null) {
try {
watcher.close();
} catch (IOException e) {
error("An error occurred attempting to close the file watcher. " + e.getMessage(), e);
}
}
}
}
use of java.nio.file.Watchable in project phoebus by ControlSystemStudio.
the class DirectoryMonitor method run.
/**
* 'thread' runnable, exits when 'thread' set to <code>null</code>
*/
private void run() {
while (thread != null) {
try {
final WatchKey key = watcher.poll(1, TimeUnit.SECONDS);
if (key != null) {
final Watchable watchable = key.watchable();
if (watchable instanceof Path)
for (WatchEvent<?> event : key.pollEvents()) handle((Path) watchable, event);
key.reset();
}
} catch (ClosedWatchServiceException ex) {
// Ignore, exiting
} catch (Exception ex) {
logger.log(Level.WARNING, "DirectoryMonitor error", ex);
}
}
}
use of java.nio.file.Watchable in project concourse by cinchapi.
the class FileOps method awaitChangeInterruptibly.
/**
* Cause the current thread to block while waiting for a change to
* {@code file}.
* <p>
* Because of limitations of most underlying file systems, this method can
* only guarantee changes that occur at least 1 second after this method is
* invoked. For changes that occur less than 1 second of method invocation,
* the method will return immediately; however, there is a chance that such
* a return is indicative of a false positive case where the file changed
* before this method was invoked, but within the same second of the
* invocation.
* </p>
* <p>
* If protection against that kind of false positive is important, the
* caller should check the contents of the underlying file is this method
* returns immediately.
* </p>
*
* @param file the path to a regular file
*/
public static void awaitChangeInterruptibly(String file) throws InterruptedException {
if (!IS_WATCH_SERVICE_SETUP) {
try {
// Add a PollingWatchService to use as a backup in case the
// default watch service is causing issues (i.e. on Linux the
// max number of inotify watches may be reached, in which case
// we can use the backup as a fail safe.)
PollingWatchService pollingWatchService = new PollingWatchService(Runtime.getRuntime().availableProcessors(), 1000, TimeUnit.MILLISECONDS);
pollingWatchService.start();
FILE_CHANGE_WATCHERS.add(pollingWatchService);
FILE_CHANGE_WATCHERS.add(FileSystems.getDefault().newWatchService());
} catch (Exception e) {
// NOTE: Cannot re-throw the exception because it will prevent
// the class from being loaded...
e.printStackTrace();
}
FILE_CHANGE_WATCHERS.forEach((watcher) -> {
setupWatchService(watcher);
});
IS_WATCH_SERVICE_SETUP = true;
}
long methodStartTime = System.currentTimeMillis();
methodStartTime = TimeUnit.SECONDS.convert(methodStartTime, TimeUnit.MILLISECONDS);
Path path = Paths.get(expandPath(file));
Preconditions.checkArgument(java.nio.file.Files.isRegularFile(path));
String mutex = path.toString().intern();
synchronized (mutex) {
Watchable parent = path.getParent().toAbsolutePath();
if (!REGISTERED_WATCHER_PATHS.contains(parent)) {
for (int i = 0; i < FILE_CHANGE_WATCHERS.size(); ++i) {
WatchService watcher = FILE_CHANGE_WATCHERS.get(i);
try {
if (watcher instanceof PollingWatchService) {
((PollingWatchService) watcher).register((Path) parent, WATCH_EVENT_KINDS, WATCH_EVENT_MODIFIERS);
} else {
parent.register(watcher, WATCH_EVENT_KINDS, WATCH_EVENT_MODIFIERS);
}
break;
} catch (IOException e) {
// accept it.
if (i < FILE_CHANGE_WATCHERS.size()) {
continue;
} else {
throw CheckedExceptions.throwAsRuntimeException(e);
}
}
}
REGISTERED_WATCHER_PATHS.add(parent);
}
try {
long modified = java.nio.file.Files.getLastModifiedTime(path).toMillis();
modified = TimeUnit.SECONDS.convert(modified, TimeUnit.MILLISECONDS);
if (modified >= methodStartTime) {
// invocation
return;
} else {
mutex.wait();
}
} catch (IOException e) {
throw CheckedExceptions.throwAsRuntimeException(e);
}
}
}
use of java.nio.file.Watchable in project jimfs by google.
the class AbstractWatchServiceTest method testRegister.
@Test
public void testRegister() throws IOException {
Watchable watchable = new StubWatchable();
AbstractWatchService.Key key = watcher.register(watchable, ImmutableSet.of(ENTRY_CREATE));
assertThat(key.isValid()).isTrue();
assertThat(key.pollEvents()).isEmpty();
assertThat(key.subscribesTo(ENTRY_CREATE)).isTrue();
assertThat(key.subscribesTo(ENTRY_DELETE)).isFalse();
assertThat(key.watchable()).isEqualTo(watchable);
assertThat(key.state()).isEqualTo(READY);
}
use of java.nio.file.Watchable in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.
the class DiskManager method setupWatchService.
private void setupWatchService() throws IOException {
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
try {
edgeConnectorForKVSConfigurationList.forEach(configuration -> {
System.out.println("Start watching!");
Path path = configuration.getVideoRecordFolderPath();
try {
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
log.info(String.format("Start watch service for video record path: %s", path.getFileName()));
} catch (IOException e) {
log.error(String.format("Start watch service for video record path: %s failed!", path.toString()));
throw new EdgeConnectorForKVSException(e);
}
});
while (true) {
final WatchKey watchKey = watchService.take();
final Watchable watchable = watchKey.watchable();
if (watchable instanceof Path) {
final Path directoryPath = (Path) watchable;
for (WatchEvent<?> event : watchKey.pollEvents()) {
this.callback.handleWatchEvent(directoryPath, event, diskManagerUtil);
}
}
if (!watchKey.reset()) {
log.warn("Disk Management run into issue. Restarting the process...");
setupDiskManagerThread();
break;
}
}
} catch (InterruptedException e) {
log.error("Disk Management process interrupted! ");
Thread.currentThread().interrupt();
}
}
}
Aggregations