Vaadin 25 and @StyleSheet

Loading lumo.css with @StyleSheet or any direct url does not work out of the box for me.

I have a j2ee application, where the main war (ptsmc) has two distinct paths:

  • /ptsmc/app - All vaadin stuff. Requires login
  • /ptsmc/ - public stuff

In web.xml, “/ptsmc/app” is routed to VaadinServlet

Part of the problem might be that I pack vaadin into a separate jar, ptsmc-widgetset, so that it can be shared with several other entrypoints that we have. This is deployed to ear/lib

In this setup, what is the right url, if any, to load lumo.css?

  • @StyleSheet(Lumo.STYLESHEET) → lumo/lumo.css → /ptsmc/lumo/lumo.css → Doesn’t work
  • /ptsmc/app/lumo/lumo.css → Doesn’t work
  • /ptsmc/app/VAADIN/lumo/lumo.css → Doesn’t work

I flagged this in during the beta program as well, but I never heard anything back.

I’ve worked around this by creating a simple servlet on “lumo” (ie “/ptsmc/lumo” ) that does:

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String pathInfo = request.getPathInfo();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        try(var inputStream = classLoader.getResourceAsStream("META-INF/resources/lumo/" + pathInfo)) {
            if(pathInfo.endsWith(".css")) {
                response.setContentType("text/css");
            }
            inputStream.transferTo(response.getOutputStream());
        }
        catch(Exception e) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

    }

What do you mean by

Did you explicitly define the VaadinServlet configuration in the web.xml and set /ptsmc/app as the servlet mapping?

If so, did you try with the context:// pseudo protocol?

@StyleSheet("context://lumo/lumo.css")

Yes, except the “ptsmc” bit, since that comes from the context root of the war.

	<servlet>
		<servlet-name>web</servlet-name>
		<servlet-class>com.vaadin.flow.server.VaadinServlet</servlet-class>

		<init-param>
			<param-name>pnpm.enable</param-name>
			<param-value>true</param-value>
		</init-param>

		<load-on-startup>1</load-on-startup>

	</servlet>

    <servlet-mapping>
        <servlet-name>web</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

No, will try that now. I did vaguely remember seeing something about this, but had forgotten where.

Doesn’t look like “context://” does anything magical. It still triggers a regular request from the client, which fails. What is it supposed to do?

This looks strange. The CSS should be served directly from the container, since the resource is in META-INF/resources in the lumo JAR file.
Unless there’s something else (e.g. another filter or servlet) that intercepts the request and prevents the container from resolving the resource.
Or maybe some servlet container configuration.

What servlet container are you using?

The request I would expect to work is: http://localhost:8080/ptsmc/app/lumo/lumo.css
“ptsmc” is the context root
“app/*” is what the Vaadin servlet is bound to

I see I was a bit unclear when I said I get 404.
I do get 404, but I also get a response: “Request was not handled by any registered handler.”

Maybe Vaadin is accessing stuff with the wrong classloader?
If it is using the classloader of VaadinServlet, it will probably not see it.

The structure of the application is:
ptsmc.ear :

  • lib\vaadin-xxx.jar
  • lib\ptsmc-core.jar
  • ptsmc-web.war
  • ptsmc-xxx.war

In this case it is “ptsmc-web” I’m accessing, but I have several entrypoints, so I’ve put most shared things in ear\lib, including vaadin.

ptsmc-web.war should be able to access everything in itself and everything in lib.
The things in lib can only see themselves, if they use the this.getClassLoader

My workaround servlet, mentioned earlier, does: Thread.currentThread().getContextClassLoader()
and then I’m able to access everything in ptsmc-web + lib

Wildfly 38

As said, the Lumo stylesheet is supposed to be served by the servlet container. VaadinServlet does not have any special handling for it.

You mentioned ear packaging; I wonder if the container is handling META-INF/resources assets from libs in ear

You are right. If I put vaadin-lumo-theme.jar directly into ptsmc-web:WEB-INF\lib, then I’m able to access it with /ptsmc/lumo/lumo.css

In theory this should’ve worked the same with vaadin-lumo-theme.jar in ear\lib, but obviously not.
Everything in ear\lib is available on the classpath, but it seems META-INF/resources is not automatically exposed.

I’ve done some more digging, and according to the replies I got on a Wildfly mailing list, this is just the way things are.

Looks like my servlet workaround is the way to go