Spring-boot: Configure embedded containers to load static resources from fat jar's BOOT-INF/classes/META-INF/resources

Created on 17 Feb 2017  路  7Comments  路  Source: spring-projects/spring-boot

Might be related to: #7595 (or at least to a comment in this issue)

Starting with 1.4.3, our JSF application isn't processing JSF pages anymore.

  • The application still starts and seems to work, but when we call a JSF page, it returns an error:
    /index.xhtml Not Found in ExternalContext as a Resource
  • After reading #7595, i switched back to 1.5.1, but used the spring-boot-maven-plugin from version 1.4.2. Now the application starts with version 1.5.1 but JSF is still working.

I've appended a small example application. After started, call http://localhost:8085/index.xhtml.

  • If Spring Boot <=1.4.2 is used, the page shows something like "--|test value|--".
  • If Spring Boot >= 1.4.3 is used, an error page is displayed
  • If Spring Boot >= 1.4.3 with spring-boot-maven-plugin:1.4.2 is used, no error occurs and the expected "--|test value|--" is shown

BugTest.zip

BTW: If you start the application in Eclipse with the Spring Plugin, the result depends on your eclipse environment (for some developers it works, for some not - guess it depends, which loader is used by eclipse),

declined enhancement

Most helpful comment

The change that has stopped this from working is intentional as it aligns Spring Boot more closely with the Servlet spec.

The spec states that resources in META-INF/resources should be loaded from jars packaged in WEB-INF/lib but should not be loaded from META-INF/resources within the main archive. In 1.4.2 and earlier (and only with Tomcat (see #8299)) we loaded resources from META-INF/resources within the main archive (actually from BOOT-INF/classes/META-INF/resources). In 1.4.3 and later we now only load resources from META-INF/resources of a jar packaged in BOOT-INF/lib.

The one significant difference between a jar and a war file is that a war project can use src/main/webapp to package resources in the root of the archive from where they will be accessible. This isn't an option with a jar. We can consider officially supporting BOOT-INF/classes/META-INF/resources as an extension to what the Servlet spec suggests, but I'm yet to convince myself that it's a good idea.

In the meantime, you have two options here:

  • Package your application as a war file and use src/main/webapp/ for your resources rather than src/main/resources/META-INF/resources/. You can still launch it using java -jar.
  • Continue packaging your application as a jar file, but move your resources into a separate module and make your app depend on the module such that its jar is packaged in BOOT-INF/lib

I'm going to close this in favour of #8299 which will make resource handling consistent across all three containers. We'll consider supporting BOOT-INF/classes/META-INF/resources as part of that.

All 7 comments

The change that has stopped this from working is intentional as it aligns Spring Boot more closely with the Servlet spec.

The spec states that resources in META-INF/resources should be loaded from jars packaged in WEB-INF/lib but should not be loaded from META-INF/resources within the main archive. In 1.4.2 and earlier (and only with Tomcat (see #8299)) we loaded resources from META-INF/resources within the main archive (actually from BOOT-INF/classes/META-INF/resources). In 1.4.3 and later we now only load resources from META-INF/resources of a jar packaged in BOOT-INF/lib.

The one significant difference between a jar and a war file is that a war project can use src/main/webapp to package resources in the root of the archive from where they will be accessible. This isn't an option with a jar. We can consider officially supporting BOOT-INF/classes/META-INF/resources as an extension to what the Servlet spec suggests, but I'm yet to convince myself that it's a good idea.

In the meantime, you have two options here:

  • Package your application as a war file and use src/main/webapp/ for your resources rather than src/main/resources/META-INF/resources/. You can still launch it using java -jar.
  • Continue packaging your application as a jar file, but move your resources into a separate module and make your app depend on the module such that its jar is packaged in BOOT-INF/lib

I'm going to close this in favour of #8299 which will make resource handling consistent across all three containers. We'll consider supporting BOOT-INF/classes/META-INF/resources as part of that.

On second thoughts, this would be better handled as a separate issue rather than rolling it into #8299

This is also the case for JSP pages. My Kerberos bases SSO solution stops working, when the Spring Boot Maven Plugin is later than 1.4.2.RELEASE

@GyllingSW JSPs are only supported when you package your application as a war file

@wilkinsona - I know JSP has limitations, but non the less it works with the maven plugin <= the 1.4.2.RELEASE version.
I use the approach shown here:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp

@GyllingSW That sample is fine. It is building a war file. If you're doing that then there's no problem

I'm going to close this. There's been relatively little demand for it yet implementing it would add complexity to achieve something that can already been done using one of the two options that I described in my comment above.

Was this page helpful?
0 / 5 - 0 ratings