Skip to content

Commit 8b8853f

Browse files
fix: ensure route annotation is on component class (#22878) (#22883)
Throws an exception at startup if a Route annotation is put on a class that does not extend Component. Fixes #22877 Co-authored-by: Marco Collovati <marco@vaadin.com>
1 parent d71f22b commit 8b8853f

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractRouteRegistryInitializer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,14 @@ protected Set<Class<? extends Component>> validateRouteClasses(
8181
* @return true if applicable class
8282
*/
8383
private boolean isApplicableClass(Class<?> clazz) {
84-
return clazz.isAnnotationPresent(Route.class)
85-
&& Component.class.isAssignableFrom(clazz)
84+
boolean hasRouteAnnotation = clazz.isAnnotationPresent(Route.class);
85+
if (hasRouteAnnotation && !Component.class.isAssignableFrom(clazz)) {
86+
throw new InvalidRouteConfigurationException(String.format(
87+
"'%s' declares '@%s' but does not extend '%s'.",
88+
clazz.getCanonicalName(), Route.class.getSimpleName(),
89+
Component.class.getCanonicalName()));
90+
}
91+
return hasRouteAnnotation
8692
&& clazz.getAnnotation(Route.class).registerAtStartup();
8793
}
8894

flow-server/src/test/java/com/vaadin/flow/server/startup/AbstractRouteRegistryInitializerTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,29 @@ public static class AliasesWithSamePath extends Component {
117117

118118
}
119119

120+
@Route("foo")
121+
public static class NonComponent {
122+
123+
}
124+
120125
@Test(expected = InvalidRouteLayoutConfigurationException.class)
121126
public void routeAndParentLayout_notRouterLayout_throws() {
122127
initializer.validateRouteClasses(context,
123128
Stream.of(RouteAndParentLayout.class));
124129
}
125130

131+
@Test
132+
public void validateRouteClasses_annotationOnNonComponentClass_throws() {
133+
InvalidRouteConfigurationException exception = Assert.assertThrows(
134+
InvalidRouteConfigurationException.class,
135+
() -> initializer.validateRouteClasses(context,
136+
Stream.of(NonComponent.class)));
137+
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
138+
Route.class));
139+
Assert.assertTrue(exception.getMessage()
140+
.contains("not extend '" + Component.class.getCanonicalName()));
141+
}
142+
126143
@Test
127144
public void validateRouteClasses_samePathForRouteAndAlias_throws() {
128145
InvalidRouteConfigurationException exception = Assert.assertThrows(

flow-tests/test-embedding/embedding-test-assets/src/main/java/com/vaadin/flow/webcomponent/ClientSelectExporter.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@
1919
import com.vaadin.flow.component.WebComponentExporter;
2020
import com.vaadin.flow.component.page.AppShellConfigurator;
2121
import com.vaadin.flow.component.webcomponent.WebComponent;
22-
import com.vaadin.flow.router.Route;
2322
import com.vaadin.flow.server.PWA;
2423

2524
@PWA(name = "Client select exporter", shortName = "Client select")
26-
@Route
2725
public class ClientSelectExporter
2826
extends WebComponentExporter<ClientSelectComponent>
2927
implements AppShellConfigurator {

0 commit comments

Comments
 (0)