Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tomcat: fix auto-configuration of VaadinServlet #30

Open
mvysny opened this issue Sep 6, 2024 · 3 comments
Open

Tomcat: fix auto-configuration of VaadinServlet #30

mvysny opened this issue Sep 6, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@mvysny
Copy link
Owner

mvysny commented Sep 6, 2024

Vaadin's ServletDeployer is apparently not being called, and therefore the default VaadinServlet isn't being configured automatically if the app doesn't provide one.

The problem apparently is that Tomcat doesn't perform a full classpath scanning. Vaadin-Boot forces Tomcat to perform classpath scanning, but only in project jar file, see TomcatWebServer.enableClasspathScanning().

Perhaps setting metadata-complete to false can persuade Tomcat to perform full classpath scanning: https://stackoverflow.com/questions/9820379/what-to-do-with-annotations-after-setting-metadata-complete-true-which-resolv

However, that's definitely not easy: it can't be programmatically configured for Tomcat Embedded: https://stackoverflow.com/questions/15988578/specify-a-custom-web-xml-to-an-embedded-tomcat

Oddly enough Vaadin Lookup is initialized correctly, but that's because LookupServletContainerInitializer is ServletContainerInitializer mentioned in META-INF/services, which causes Tomcat to load it.

We could use the same technique to load and run ServletDeployer, something like:

public class VaadinInitializer implements ServletContainerInitializer {
    @NotNull
    private final ServletDeployer servletDeployer = new ServletDeployer();
    @NotNull
    private final JSR356WebsocketInitializer jsr356WebsocketInitializer = new JSR356WebsocketInitializer();
    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        servletDeployer.contextInitialized(new ServletContextEvent(ctx));
        jsr356WebsocketInitializer.contextInitialized(new ServletContextEvent(ctx));
    }
}

but that's tricky: ServletDeployer fails if Lookup wasn't initialized, and therefore this would depend on the ordering of ServletContainerInitializers, which is fragile.

@mvysny mvysny self-assigned this Sep 6, 2024
@mvysny mvysny added the enhancement New feature or request label Sep 6, 2024
@mvysny
Copy link
Owner Author

mvysny commented Sep 6, 2024

If anyone has any clue how to enable classpath scanning for Embedded Tomcat, please let me know.

@mvysny mvysny added the help wanted Extra attention is needed label Sep 6, 2024
@mvysny
Copy link
Owner Author

mvysny commented Sep 6, 2024

((StandardContext) ctx).setDefaultWebXml(TomcatWebServer.class.getClassLoader().getResource("boot/web.xml").toExternalForm()); does nothing - the file is ignored and not loaded.

@mvysny
Copy link
Owner Author

mvysny commented Sep 6, 2024

server.getHost().setAutoDeploy(true); does nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant