To reproduce the problem 1. go to https://vaadin.com/start 2. click "download" to get the Spring Boot starter 3. unzip and run mvn 4. When app has started, open http://localhost:8080 to verify that the main view with a button is shown 5. While the app is running, do mv target/classes/com/packagename/myapp/MainView.class . ; sleep 2 ; mv MainView.class target/classes/com/packagename/myapp/MainView.class 6. Refresh the browser and you will see

Could not navigate to ''
Reason: Couldn't find route for ''

instead of the expected view

Note that sleep 2 is dependent on how fast your machine is. On my recent Macbook Pro, 2 is a suitable time to sleep.

If the delay is too short, then devtools will wait for both the removal of the old class and addition of the new class before restarting and the view will be available. If the delay is too long, then devtools will first restart once after the removal and then notice the new class later and restart again. Thus the view will also be available in the end although missing on one reload in between.

When the time is just right, devtools will fail to notice that the class has been added and will just restart the application without the class

Adjusting

spring.devtools.restart.poll-interval

and

spring.devtools.restart.quiet-period

to some degree helps this but is no generic solution as working and broken values are dependent on the speed and load of the development machine.

Now this is not just academic but at least IntelliJ IDEA apparently works like this: first the class is removed and then a new one is created.

Comment From: pleku

This can be also reproduced with getting a project from start.spring.io (instead of steps 1 & 2) using https://start.spring.io/#!platformVersion=2.2.2.RELEASE&dependencies=vaadin,devtools

Comment From: mbhave

I was able to reproduce this with a sleep of 2 and 3 on my machine. It seems like a bug to me. Flagging for team attention to see how the rest of the team think we can fix it.

Comment From: philwebb

Digging into this today and the problem is with the way FileSystemWatcher builds its initial set of snapshot folders. I think the following happens:

  • The initial set of snapshot folders are created
  • The delete occurs and the file watcher notices it
  • The application restarts but the class is missing so it fails
  • After the restart failure the FileSystemWatcher builds the snapshots again
  • In the meantime, the file has been restored.

This means that the application is in a failed state and needs a restart, but the file watcher doesn't trigger one because it thinks that the MainClass has always been there.

Comment From: philwebb

I think I have a fix for this, but it's a bit risky for 2.2.x. I'm going to move this one to 2.4.x.