RouteConfiguration and @Route

Hi. I have created two simple views:

// MainView have many components
@Route("main")
public class MainView extends VerticalLayout {}

// MainView2 have only one component, for example only Button
@Route("main2")
public class MainView2 extends VerticalLayout {}

And activate it by RouteConfiguration:

public class VaadinServletExtended extends VaadinServlet {

    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();
        RouteConfiguration configuration = RouteConfiguration.forApplicationScope();
        configuration.setRoute("main", MainView.class);
        configuration.setRoute("main2", MainView2.class);
    }
	...
}

Steps 1:

  • comment @Route(“main”), uncomment @Route(“main2”)
  • Maven clean, package
    Result: only Button and VerticalLayout components on “main” page are shown, i think because they only had been used in Main2 and attached on Maven ‘package’ stage for whole project.

Step2:

  • uncomment @Route(“main”), comment @Route(“main2”)
  • Maven clean, package
    Result: all necessary components used in MainView class are shown in ‘main’ page, and all necessary components are shown in MainView2 class.

Note: the project is with Production mode activated.

Question: Am i MUST annotate all View classes with @Route annotations if i want to use RouteConfiguration for manual routes manage?

Hmm. If i use Production mode and mvn package then i cannot use extended VaadinServlet.class. I have an error 500 on output.

Regarding your original question:
depending on version which you use there is only one or two different strategies to find frontend dependencies in your project.
In older versions byte code scanning strategy is used only. It finds “endpoints”. In this case the endpoints are routes (the classes annotated with @Route). Dynamic routes are not considered as endpoints.

So if component can’t be reached out from the endpoint then it won’t be scanned and its frontend deps won’t be added to the bundle.

In the newer versions there are two strategies:

  • In dev mode full classpath scanning strategy is used. It will find anything in your classpath.
  • In production mode byte code scanner is still used. But in the latest versions (may be pre-release) there is a fallback which will be used in case the component has not been analyzed by bytecode scanner and again: everything will work out of the box.

There should be a plugin config option which allows you to use full classpath scanner even in production mode.

Denis Anisimov:

Thanks, Denis.
Today i was able to start project in development mode. I want to exclude AnnotationConfiguration from Jetty embedded context handler, because it takes a lot of seconds every time i restart project while developing. Using RouteConfiguration on app start is much more preferable for us.

I added file ‘src\main\resources\META-INF\services\javax.servlet.ServletContainerInitializer’ with one line:
com.vaadin.flow.server.startup.DevModeInitializer
But it didn’t start. I completely confused.

DevModeInitializer is already added as a service in flow-server module.
So if it’s not executed out of the box then adding it one more time in your app doesn’t help.

You are using some custom Jetty startup.
I’m not familiar with custom Jetty configurations and with your config specifically.
So it’s about making this configuration properly so that DevModeInitializer is invoked somewehow at a proper time. If it’s not possible to invoke it as ServletContainerInitializer then you may workaround it somehow to invoke it manually (but I don’t know how).

I think you should read Jetty documentation and find a way to run ServletContainerInitializer with a custom config.

Hmm. About ‘custom Jetty startup’. I trying to get to work simple test app, and there is simply clear project.
I add some mods to the Martin’s demo project: [https://github.com/mvysny/vaadin14-embedded-jetty]
(https://github.com/mvysny/vaadin14-embedded-jetty).
There is an archived project attached. In ManualJetty.java i comment/uncomment line with new AnnotationConfiguration(), and get the problem. URL for test: http://localhost:8080/main
17944383.zip (105 KB)

Denis Anisimov:
If it’s not possible to invoke it as ServletContainerInitializer
I think you should read Jetty documentation and find a way to run ServletContainerInitializer with a custom config.

I went to Google for how to invoke as ServletContainerInitializer…

Unfortunately I’m not familiar with this project.
I would recommend ask Martin directly or create a ticket in this project.

https://github.com/vaadin/skeleton-starter-flow project which uses Jetty via Servlet 3.0 spec works so there are definitely some configuration issues.

Denis Anisimov:
Unfortunately I’m not familiar with this project.
I would recommend ask Martin directly or create a ticket in this project.

https://github.com/vaadin/skeleton-starter-flow project which uses Jetty via Servlet 3.0 spec works so there are definitely some configuration issues.

It uses jetty in unclear Maven-plugin form. I will search simpler way…

Currently it is necessary to scan all classes in classpath to detect ServletContainerInitializer classes. And my attempts to exclude Jetty’s AnnotationConfiguration will not give any performance improvements on app restart in IDE.
Am i thinking right?

I’m not familiar with Jetty API and AnnotationConfiguration , sorry.
ServletContainerInitializer classes are defined as services. There is no need to find them.
But to be able to make ServletContainerInitializer instances work the whole classpath should be scanned apparently.

Denis Anisimov:
I’m not familiar with Jetty API and AnnotationConfiguration , sorry.
ServletContainerInitializer classes are defined as services. There is no need to find them.
But to be able to make ServletContainerInitializer instances work the whole classpath should be scanned apparently.

Thanks, Denis. It is became much cleaner.