Open Artur- opened 1 month ago
To make it more interesting, if the modified resource is directly in src/main/resources
then there is no logging about the watcher not being valid, it is not removed, modifying from inside IntelliJ triggers reload events - it all works fine
try to add following line to hotswap-agent.properties in your application resources/
LOGGER.org.hotswap.agent.watch=trace
you should see sequence of WATCH EVENTS generated by Idea deployment and compare it to touch
command, pby there is a problem in event handler (Watcher) in HA.
Inside IntelliJ it is the above mentioned rows
HOTSWAP AGENT: 11:25:14.802 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watcher on /.../target/classes/vaadin-i18n not valid, removing path=
HOTSWAP AGENT: 11:25:14.947 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_MODIFY' on '/.../target/classes/vaadin-i18n' --> vaadin-i18n
and outside (touch
) it is only
HOTSWAP AGENT: 12:23:03.040 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_MODIFY' on '/.../target/classes/vaadin-i18n/translations.properties' --> translations.properties
I think IntelliJ does something like
rm target/classes/vaadin-i18n/translations.properties && rmdir target/classes/vaadin-i18n && mkdir target/classes/vaadin-i18n && cp translations.properties target/classes/vaadin-i18n/translations.properties
when updating the files, which causes similar logs as with IntelliJ
Is the "Hotswap Watcher" thread still running after it stops responding?
The watcher thread keeps running and only the listener for the vaadin-i18n/translations.properties
stops working. Doing touch target/classes/foo/bar.properties
still triggers an event.
Also, if you do the command slowly, step by step, the output is quite different:
rm target/classes/vaadin-i18n/translations.properties
HOTSWAP AGENT: 14:30:43.072 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_DELETE' on '/.../target/classes/vaadin-i18n/translations.properties' --> translations.properties
rmdir target/classes/vaadin-i18n
HOTSWAP AGENT: 14:31:15.271 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watcher on /.../target/classes/vaadin-i18n not valid, removing path=
HOTSWAP AGENT: 14:31:15.524 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_DELETE' on '/.../target/classes/vaadin-i18n' --> vaadin-i18n
mkdir target/classes/vaadin-i18n
HOTSWAP AGENT: 14:32:04.229 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_CREATE' on '/.../target/classes/vaadin-i18n' --> vaadin-i18n
HOTSWAP AGENT: 14:32:04.230 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Registering directory /.../target/classes/vaadin-i18n
cp translations.properties target/classes/vaadin-i18n/translations.properties
HOTSWAP AGENT: 14:32:52.979 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_CREATE' on '/.../target/classes/vaadin-i18n/translations.properties' --> translations.properties
What OS are you using?
macOS 15.0 aka sequoia
There is WatcherNIO2Test in HA core, I've tried to simulate your problem, and don't see some events on Linux, too.
@Test
public void recreateDirFile() throws IOException {
final ResultHolder resultHolder = new ResultHolder();
Path testDir = temp.resolve("testdir");
Files.createDirectories(testDir);
File testFile = new File(testDir.toFile(), "testfile.txt");
testFile.createNewFile();
watcher.addEventListener(null, temp.toUri(), new WatchEventListener() {
@Override
public void onEvent(WatchFileEvent event) {
System.out.println(event.toString());
// assertEquals("New file event type", FileEvent.CREATE, event.getEventType());
// assertTrue("File name", event.getURI().toString().endsWith("testfile.txt"));
resultHolder.result = true;
}
});
//assertTrue("Event listener called", waitForResult(resultHolder));
Files.walk(testDir)
.sorted(Comparator.reverseOrder())
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
e.printStackTrace();
}
});
Files.deleteIfExists(testDir);
Files.createDirectories(testDir);
testFile = new File(testDir.toFile(), "testfile.txt");
testFile.createNewFile();
assertTrue("Event listener called", waitForResult(resultHolder));
}
Problem is in WatcherNIO2.registerAll
, it is called too late, after directory+files are recreated. I've tried to "touch" existing files inside preVisitDirectory
and it generates modify event, but additional touch could have side effects. So only solution I see is to make "fake" create events and feed dispatcher.add(ev, child);
with them.
There is a fix for it in the master + junit test. Could you check it please?
Based on a quick test, it works perfectly. The output is
HOTSWAP AGENT: 19:38:28.283 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_MODIFY' on '/.../target/classes/vaadin-i18n/translations.properties' --> translations.properties
and nothing else
Added LOG for fake events, you should see ENTRY_CREATE event
Otherwise, this change breaks the Spring plugin tests, the other plugins remain unaffected.
Tests are fixed now.
There may be a similar problem on Windows, as it uses a different implementation of Watcher. Have you had the opportunity to test your issue on Windows?
I tried in a virtual machine with Windows 11 and don't see the original issue with HA 2.0.1. It logs
HOTSWAP AGENT: 10:25:05.686 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_DELETE' on '...\target\classes\i18n\translations.properties' --> i18n\translations.properties
HOTSWAP AGENT: 10:25:05.719 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on '...\target\classes\i18n' --> i18n
HOTSWAP AGENT: 10:25:05.720 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_DELETE' on '...\target\classes\i18n' --> i18n
HOTSWAP AGENT: 10:25:05.748 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_CREATE' on '...\target\classes\i18n' --> i18n
HOTSWAP AGENT: 10:25:05.748 INFO (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Registering directory ...\target\classes\i18n
HOTSWAP AGENT: 10:25:05.748 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Path ...\target\classes\i18n watched via ...\target\classes
HOTSWAP AGENT: 10:25:05.749 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_CREATE' on '...\target\classes\i18n\translations.properties' --> i18n\translations.properties
HOTSWAP AGENT: 10:25:05.750 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on '...\target\classes\i18n\translations.properties' --> i18n\translations.properties
HOTSWAP AGENT: 10:25:05.751 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on '...\target\classes\i18n\translations.properties' --> i18n\translations.properties
HOTSWAP AGENT: 10:25:05.766 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on '...\target\classes\i18n' --> i18n
and the watcher keeps working
Now when testing some more on Mac, there are still some issues. Either I am testing it wrong or something is still bugging.
With the latest master
, when changing vaadin-i18n/translations.properties
in IntelliJ, I see
HOTSWAP AGENT: 11:03:21.338 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watcher on /.../target/classes/vaadin-i18n not valid, removing path=
HOTSWAP AGENT: 11:03:21.547 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_MODIFY' on '/.../target/classes/vaadin-i18n' --> vaadin-i18n
and then on subsequent changes only
HOTSWAP AGENT: 11:03:21.547 DEBUG (org.hotswap.agent.watch.nio.WatcherNIO2) - Watch event 'ENTRY_MODIFY' on '/.../target/classes/vaadin-i18n' --> vaadin-i18n
there are no modify events for the file itself and manually doing touch target/classes/vaadin-i18n/translations.properties
does nog log anything from org.hotswap.agent.watch
I don't get it. Now it works like yesterday again... I wonder if there is a timing issue still somewhere
Could you make simple example for testing?
If I have a resource, say
src/main/resources/vaadin-i18n/translations.properties
containingfoo=bar
, then when running with HotswapAgent and doingtriggers hotswap events for file reload, triggers the Vaadin plugin etc. Just like expected.
However, if you in IntelliJ open the file, change it to
foo=baz
and pressBuild -> Recompile 'translations.properties'
then the following is loggedand there is no hotswap event received.
After that, no hotswap events are sent any more when updating from outside IntelliJ either, i.e. HotswapAgent no longer reacts to
in any way