Wildfly 38 - Access META-INF\resources from jars in ear\lib from browser?

27 views
Skip to first unread message

Guttorm Vik

unread,
Feb 12, 2026, 8:30:44 AMFeb 12
to WildFly
I have an ear with skinnywars, where all shared jars are in ear\lib
Some of these jars have resources in META-INF\resources.
I had expected the content of ear\lib\*.jar\META-INF\resources to be exposed to the browser, via whatever war I'm running, but they are not.

If I move the jar from ear\lib to someWar\WEB-INF\lib *then* it is available.

What am I missing?

luca stancapiano

unread,
Feb 13, 2026, 11:29:31 AMFeb 13
to Guttorm Vik, WildFly

Hi Guttorm,

in WildFly only JARs on the web app classpath (for example under someWar/WEB-INF/lib) are automatically scanned as web fragments and have their META-INF/resources exposed as static resources.
JARs placed in ear/lib are visible for classes, but they are not treated as web fragments of a particular WAR, so their META-INF/resources are not mapped to any servlet context and therefore are not directly available from the browser.

That is why it starts working when you move the JAR from ear/lib into someWar/WEB-INF/lib: at that point it becomes part of that WAR’s web module and its META-INF/resources are served by that WAR.
If you need those resources shared, the usual approaches are to put the JAR in each WAR that should expose them, or split them into a dedicated web module (for example a separate WAR) that serves the shared static content.

Best regards,

Luca Stancapiano


--
You received this message because you are subscribed to the Google Groups "WildFly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wildfly+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/wildfly/54b37b4a-e8dc-4e44-8ca4-db384309539fn%40googlegroups.com.

Guttorm Vik

unread,
Feb 13, 2026, 4:43:50 PMFeb 13
to WildFly
Hi Luca, thanks for the reply.

I find this limitation a bit frustrating and baffling, but at least I can stop banging my head against the wall trying to make this work.
It seems I have to stick with my plan B, which is to have a servlet in the war that looks up and forwards to resources from META-INF\resources

luca stancapiano

unread,
Feb 14, 2026, 4:48:04 AMFeb 14
to Guttorm Vik, WildFly

Hi Guttorm,

I completely understand the frustration – it feels counter‑intuitive when the structure looks right but the container still does not expose the resources the way you expect. Unfortunately, the EAR‑level classloader separation in WildFly means there is no clean switch you can flip to make ear/lib JARs behave like web fragments of the WAR.

Given that, your plan B with a servlet that looks up and forwards META-INF/resources is a perfectly reasonable and pragmatic solution, especially if you want to keep the JARs truly shared at the EAR level. The only thing I would watch out for is caching and URL design, so that browsers and reverse proxies can cache those resources effectively and you do not end up with odd paths that are hard to maintain.

If at some point you decide to revisit this, the only container‑native alternatives are still the ones I mentioned: either duplicating the JAR in the WARs that need to expose the resources, or introducing a dedicated WAR whose sole purpose is to serve the shared static content. Neither is as elegant as EAR‑level sharing, but they do align with how WildFly’s web resource mapping works today.

Best regards,
Luca


Guttorm Vik

unread,
Feb 14, 2026, 6:18:26 AMFeb 14
to luca stancapiano, WildFly
Thanks again Luca,

You have explained the issue perfectly, but I thought I should give some more details for future visitors:

Our application is an ear with multiple war entry points. We have this mostly so that they can have separate security contexts, but it also helps with organization.
These wars share a lot of code, including the 3rd party server-side rendering framework; Vaadin.
To save space, all the shared stuff has been placed in ear/lib.

The client-side of Vaadin consists of a huge js blob. That is served by the main Vaadin servlet itself, so that causes no issues.
Recently they have separated out their base styling into a separate jar; vaadin-lumo-theme.jar, and that is where my problem started.

In the lumo jar we have META-INF/resources /lumo/lumo.css, so the expected path is <war context root>/lumo/lumo.css
This works fine when the jar is in the war's WEB-INF/lib, but not when moved to ear/lib.

As you have explained Luca, Wildfly doesn't support this, so I have to do something else.

I *could* duplicate just the vaadin-lumo-theme.jar into every war that needs it, but it has dependencies, so by default it drags several other Vaadin libraries with it.
Maybe I could fight that, but I'd rather not.

Since it is 3rd party library, I really don't want to mess with the structure.

Everything in ear\lib is available on the classpath, so my initial hack, while looking for the "right" solution, was to add a LumoServlet listening on "lumo" to my war:

    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)) {
            inputStream.transferTo(response.getOutputStream());
        }
        catch(Exception e) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }

    }

Now that this is to be the solution instead of a hack, I'll have to do some cleanup, like ensuring the path doesn't contain any "..".

One extra wrinkle; We've just turned on "X-Content-Type-Options: nosniff", so out of the box the browser rejects the /lumo/lumo.css file when returned by the above servlet.
Until now I've just done: response.setContentType("text/css"), but now I'll replace it with something like URLConnection.guessContentTypeFromName.

Guttorm

Jose Socola

unread,
Feb 14, 2026, 8:52:57 AMFeb 14
to Guttorm Vik, luca stancapiano, WildFly
Hi,

deployment-overlay it's maybe applied in this case?


Regards,
JS

luca stancapiano

unread,
Feb 16, 2026, 2:33:46 AM (13 days ago) Feb 16
to Jose Socola, Guttorm Vik, WildFly

Hi Guttorm,

thanks a lot for the detailed follow‑up, it’s very clear and I’m sure it will be useful for others hitting the same limitation.

Your current solution with a dedicated servlet that loads the resources from the classpath is a reasonable approach given that WildFly does not expose META-INF/resources from jars in ear/lib. Just make sure, as you already mentioned, to sanitize the path (avoid .., absolute paths, etc.) and to set the correct Content-Type to keep X-Content-Type-Options: nosniff happy.

Regarding alternatives, the main ones remain:

  • Keep the Vaadin theme jar in each WAR’s WEB-INF/lib when you need the automatic META-INF/resources mapping.

  • Or, keep your servlet approach but maybe wrap it with a small helper to centralize path sanitization and content‑type detection (e.g. using URLConnection.guessContentTypeFromName or a small custom map for common types).

Unfortunately there is currently no WildFly configuration switch that would make META-INF/resources from ear/lib directly available like in WEB-INF/lib, so your workaround is aligned with what the server supports.

Best regards,
Luca

Reply all
Reply to author
Forward
0 new messages