I’m getting intermittent failures of my application to start in my IDE, and when it fails I see this in the log. I don’t understand how it can complain about the same class having conflicting routes.
Caused by: com.vaadin.flow.server.AmbiguousRouteConfigurationException: Navigation targets must have unique routes, found navigation targets ‘com.celerasystems.mc.storefront.views.SearchCustomComponentsView’ and ‘com.celerasystems.mc.storefront.views.SearchCustomComponentsView’ with the same route.
The only thing possibly unusual about this class is that it inherits from a superclass that also contains a @Route annotation.
@Route("searchCustomComponents")
@PreserveOnRefresh
public class SearchCustomComponentsView extends ItemSearchView
The superclass looks like this
@Route("/itemSearch")
@RouteAlias("/startSearch")
@PreserveOnRefresh
public class ItemSearchView extends VerticalLayout implements BeforeEnterObserver, AfterNavigationObserver
I haven’t quite been able to figure out the pattern to identify what causes a successful startup versus a failure. It behaves in a way consistent with some sort of internal race condition. Any ideas as to what is going on? Is this inheritance situation problematic?
Maybe answering my own question by diving into the stack trace.
The internal Vaadin class RouteConfiguration has a method setAnnotatedRoute().
This method in turn calls Class.getAnnotationsByType(RouteAlias.class).
If the class we are scanning inherits from a parent class that has RouteAlias annotations, then this method call is going to return them for the subclass too. Perhaps this should be changed to call getDeclaredAnnotationsByType() instead?
I still can’t explain why the problem seems intermittent…
It is definitely a problem caused by inheritance and the RouteAlias annotation. If I remove the RouteAlias from the parent, the application starts up just fine.
I don’t think it is clear that there is one correct way of treating RouteAlias inheritance. I can think of valid use cases for both processing them and for ignoring them. Perhaps an attribute can be added to the Route annotation to tell how inherited aliases should be handled?
In the meantime, there are 2 workarounds:
Add a RouteAlias annotation to the subclass, even if it doesn’t need one
Add the alias programmatically using RouteConfiguration
Could you please also clarify this
" 1. Add a RouteAlias annotation to the subclass, even if it doesn’t need one", how does this help you? This makes your child view class available with the alias, but still leaves your parent view class with only one path from route annotation.
I put a RouteAlias (with different route values) on both the superclass and the subclass. The annotation on the subclass seems to hide the annotation on the parent from the RouteConfiguration.