Skip to content

Resource handling is inconsistent across different embedded containers #8299

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

Closed
wilkinsona opened this issue Feb 15, 2017 · 10 comments
Closed
Assignees
Labels
type: bug A general bug
Milestone

Comments

@wilkinsona
Copy link
Member

The behaviour of embedded Tomcat, Jetty, and Undertow is inconsistent when the containers themselves are dealing with static resources, i.e. when Spring MVC's resource handling isn't involved. For example, support for loading resources from META-INF/resources of nested jars works with Tomcat but doesn't work with Undertow. Furthermore, I believe it only works with Tomcat when Jasper's on the classpath.

@wilkinsona wilkinsona self-assigned this Feb 15, 2017
@wilkinsona
Copy link
Member Author

Expectations

Fat war

For war files, we're interested in resources in these three locations:

app.war
├── META-INF
│   └── resources
│       └── meta-inf-resource.txt
├── WEB-INF
│   └── lib
│       └── resources.jar
│           └── META-INF
│               └── resources
│                   └── nested-meta-inf-resource.txt
└── resource.txt

Accessing resources via HTTP and via the servlet context (SC) should have the following results:

Path Method Result
/nested-meta-inf-resources.txt HTTP 200
/nested-meta-inf-resources.txt SC URL
/meta-inf-resources.txt HTTP 404
/meta-inf-resources.txt SC Null
/resource.txt HTTP 200
/resource.txt SC URL

Fat jar

For jar files, we're interested in resources in these locations:

app.jar
├── BOOT-INF
│   └── lib
│       └── resources.jar
│           └── META-INF
│               └── resources
│                   └── nested-meta-inf-resource.txt
├── META-INF
│   └── resources
│       └── meta-inf-resource.txt
└── resource.txt

Accessing resources via HTTP and via the servlet context should have the following results:

Path Method Result
/nested-meta-inf-resources.txt HTTP 200
/nested-meta-inf-resources.txt SC URL
/meta-inf-resources.txt HTTP 404
/meta-inf-resources.txt SC Null
/resource.txt HTTP 404
/resource.txt SC 404

Actual behaviour

Fat war

Path Method Jetty Tomcat Undertow
/nested-meta-inf-resources.txt HTTP ❌/✅ (1)
/nested-meta-inf-resources.txt SC ❌/✅ (1)
/meta-inf-resources.txt HTTP
/meta-inf-resources.txt SC
/resource.txt HTTP
/resource.txt SC

(1) - Tomcat only works when Jasper in on the classpath

Fat jar

Path Method Jetty Tomcat Undertow
/nested-meta-inf-resources.txt HTTP ❌/✅ (1)
/nested-meta-inf-resources.txt SC ❌/✅ (1)
/meta-inf-resources.txt HTTP
/meta-inf-resources.txt SC
/resource.txt HTTP
/resource.txt SC

(1) - Tomcat only works when Jasper in on the classpath

@wilkinsona wilkinsona added this to the 1.4.5 milestone Feb 17, 2017
@wilkinsona
Copy link
Member Author

wilkinsona commented Feb 18, 2017

We should consider configuring the containers such that they can serve resources from BOOT-INF/classes/META-INF/resources. This would allow a jar-packaged project to place static resources in src/main/resources/META-INF/resources rather than having to move them out into a separate project that's depended upon (see #8324). A war file doesn't have this problem as war projects can place resources directly in src/main/webapp from where they'll end up in the root of the war.

wilkinsona added a commit to wilkinsona/spring-boot that referenced this issue Mar 9, 2017
The changes made for spring-projectsgh-8299 attempted to make static resource
handling consistent across Jetty, Tomcat, and Undertow. They did so
for application's launched using JarLauncher or WarLauncher but did
not consider application's launched in an IDE or using spring-boot:run
in Maven or bootRun in Gradle.

Running in an IDE or via Maven or Gradle introduces two new
resource locations:

 - Jars on the classpath with file protocol URLs (they are always
   jar protocol URLs when using either launcher)
 - Directories on the classpath from a project that is depended upon
   and contains resources in META-INF/resources

This commit updates the factories for all three containers to handle
these new resources locations. The integration tests have also been
updated.
wilkinsona added a commit that referenced this issue Mar 9, 2017
The changes made for gh-8299 attempted to make static resource
handling consistent across Jetty, Tomcat, and Undertow. They did so
for application's launched using JarLauncher or WarLauncher but did
not consider application's launched in an IDE or using spring-boot:run
in Maven or bootRun in Gradle.

Running in an IDE or via Maven or Gradle introduces two new
resource locations:

 - Jars on the classpath with file protocol URLs (they are always
   jar protocol URLs when using either launcher)
 - Directories on the classpath from a project that is depended upon
   and contains resources in META-INF/resources

This commit updates the factories for all three containers to handle
these new resources locations. The integration tests have also been
updated.
@bjorntj
Copy link

bjorntj commented Mar 28, 2017

Just wondering, where should I put static resources when using embedded Undertow? I have created a jar file that contains these resources and this is working fine when unsing tomcat or jetty, but undertow does not find the resources.
Or is a fix for this issue imminent?

@wilkinsona
Copy link
Member Author

As long as you're using the latest version of 1.4.x and 1.5.x, it should work the same way in all three embedded containers. If you've found a situation where that's not the case, please open a new issue with a small sample that reproduces the problem.

@bjorntj
Copy link

bjorntj commented Mar 28, 2017

I am using 1.5.2 and tomcat and jetty is working fine, but not undertow. All I do to switch, is change this dependency: compile("org.springframework.boot:spring-boot-starter-jetty") to either starter.tomcat or starter.undertow..
I am also using JSF, not sure if that makes a difference...

@bjorntj
Copy link

bjorntj commented Mar 28, 2017

Seems like this is related to JSF, more specific Primefaces and their themes.
Under /META-INF/resources/ there is another directory called resources and beneath this, there is a directory called theme-name, and beneath this again is the folders needed for this theme (css, images, etc).
The error I get when running under Undertow, is:
JSF1064: Unable to find or serve resource, css/layout.css, from library, theme-name

Does this help or do you still need me to open a new issue with a sample case?

@wilkinsona
Copy link
Member Author

If you'd like us to investigate, we'll need a new issue with a sample case please.

@pleku

This comment has been minimized.

@wilkinsona

This comment has been minimized.

@pleku
Copy link

pleku commented Dec 3, 2018

Will do, sorry and thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants